Skip to content

Commit 0948d83

Browse files
artemradsys-ce-bb
authored andcommitted
Fixing Intrinsic::ptr_annotation (#2235)
There is a fundamental misalignment between when translating llvm.ptr.annotation to SPIRV's OpMemberDecorate. llvm.ptr.annotation is applied onto a pointer. OpMemberDecorate is applied on a type, which means that all variables of this type will have this Decoration. This change fixes this misalignment by translating llvm.ptr.annotation to SPIRV's OpDecorate instead, which instead places the decoration onto the pointer. Original commit: KhronosGroup/SPIRV-LLVM-Translator@3770469
1 parent d791581 commit 0948d83

File tree

9 files changed

+185
-287
lines changed

9 files changed

+185
-287
lines changed

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 24 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3217,6 +3217,8 @@ AnnotationDecorations tryParseAnnotationString(SPIRVModule *BM,
32173217

32183218
std::pair<StringRef, StringRef> Split = AnnotatedDecoration.split(':');
32193219
StringRef Name = Split.first, ValueStr = Split.second;
3220+
SPIRVDBG(spvdbgs() << "[tryParseAnnotationString]: AnnotationString: "
3221+
<< Name.str() << "\n");
32203222

32213223
unsigned DecorationKind = 0;
32223224
if (!Name.getAsInteger(10, DecorationKind)) {
@@ -4367,19 +4369,17 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
43674369
// i8* <ptr> is a pointer on a GV, which can carry optinal variadic
43684370
// clang::annotation attribute expression arguments.
43694371
case Intrinsic::ptr_annotation: {
4370-
// Strip all bitcast and addrspace casts from the pointer argument:
4371-
// llvm annotation intrinsic only takes i8*, so the original pointer
4372-
// probably had to loose its addrspace and its original type.
4373-
Value *AnnotSubj = II->getArgOperand(0);
4374-
while (isa<BitCastInst>(AnnotSubj) || isa<AddrSpaceCastInst>(AnnotSubj)) {
4375-
AnnotSubj = cast<CastInst>(AnnotSubj)->getOperand(0);
4372+
Value *AnnotSubj = nullptr;
4373+
if (auto *BI = dyn_cast<BitCastInst>(II->getArgOperand(0))) {
4374+
AnnotSubj = BI->getOperand(0);
4375+
} else {
4376+
AnnotSubj = II->getOperand(0);
43764377
}
43774378

43784379
std::string AnnotationString;
43794380
processAnnotationString(II, AnnotationString);
43804381
AnnotationDecorations Decorations =
43814382
tryParseAnnotationString(BM, AnnotationString);
4382-
43834383
// Translate FPGARegIntel annotations to OpFPGARegINTEL.
43844384
if (AnnotationString == kOCLBuiltinName::FPGARegIntel) {
43854385
auto *Ty = transScavengedType(II);
@@ -4389,76 +4389,26 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
43894389
return transValue(BI, BB);
43904390
}
43914391

4392-
// If the pointer is a GEP on a struct, then we have to emit a member
4393-
// decoration for the GEP-accessed struct, or a memory access decoration
4394-
// for the GEP itself. There may not be a GEP in this case if the access is
4395-
// to the first member of the struct; if so, attempt to get a struct type
4396-
// from an alloca instead.
4397-
SPIRVType *StructTy = nullptr;
4398-
[[maybe_unused]] SPIRVValue *ResPtr = nullptr;
4399-
[[maybe_unused]] SPIRVWord MemberNumber = 0;
4400-
if (auto *const GI = dyn_cast<GetElementPtrInst>(AnnotSubj)) {
4401-
if (auto *const STy = dyn_cast<StructType>(GI->getSourceElementType())) {
4402-
StructTy = transType(STy);
4403-
ResPtr = transValue(GI, BB);
4404-
MemberNumber = dyn_cast<ConstantInt>(GI->getOperand(2))->getZExtValue();
4405-
}
4406-
} else if (auto *const AI = dyn_cast<AllocaInst>(AnnotSubj)) {
4407-
if (auto *const STy = dyn_cast<StructType>(AI->getAllocatedType())) {
4408-
StructTy = transType(STy);
4409-
ResPtr = transValue(AI, BB);
4410-
MemberNumber = 0;
4411-
}
4412-
}
4413-
if (StructTy) {
4414-
4415-
// If we didn't find any IntelFPGA-specific decorations, let's add the
4416-
// whole annotation string as UserSemantic Decoration
4417-
if (Decorations.empty()) {
4418-
// TODO: Is there a way to detect that the annotation belongs solely
4419-
// to struct member memory atributes or struct member memory access
4420-
// controls? This would allow emitting just the necessary decoration.
4421-
StructTy->addMemberDecorate(new SPIRVMemberDecorateUserSemanticAttr(
4422-
StructTy, MemberNumber, AnnotationString.c_str()));
4423-
ResPtr->addDecorate(new SPIRVDecorateUserSemanticAttr(
4424-
ResPtr, AnnotationString.c_str()));
4425-
} else {
4426-
addAnnotationDecorationsForStructMember(
4427-
StructTy, MemberNumber, Decorations.MemoryAttributesVec);
4428-
// Apply the LSU parameter decoration to the pointer result of a GEP
4429-
// to the given struct member (InBoundsPtrAccessChain in SPIR-V).
4430-
// Decorating the member itself with a MemberDecoration is not feasible,
4431-
// because multiple accesses to the struct-held memory can require
4432-
// different LSU parameters.
4433-
addAnnotationDecorations(ResPtr, Decorations.MemoryAccessesVec);
4434-
if (allowDecorateWithBufferLocationOrLatencyControlINTEL(II)) {
4435-
addAnnotationDecorations(ResPtr, Decorations.BufferLocationVec);
4436-
addAnnotationDecorations(ResPtr, Decorations.LatencyControlVec);
4437-
}
4438-
}
4439-
II->replaceAllUsesWith(II->getOperand(0));
4392+
SPIRVValue *DecSubj = transValue(AnnotSubj, BB);
4393+
if (Decorations.empty()) {
4394+
DecSubj->addDecorate(
4395+
new SPIRVDecorateUserSemanticAttr(DecSubj, AnnotationString.c_str()));
44404396
} else {
4441-
// Memory accesses to a standalone pointer variable
4442-
auto *DecSubj = transValue(II->getArgOperand(0), BB);
4443-
if (Decorations.empty())
4444-
DecSubj->addDecorate(new SPIRVDecorateUserSemanticAttr(
4445-
DecSubj, AnnotationString.c_str()));
4446-
else {
4447-
// Apply the LSU parameter decoration to the pointer result of an
4448-
// instruction. Note it's the address to the accessed memory that's
4449-
// loaded from the original pointer variable, and not the value
4450-
// accessed by the latter.
4451-
addAnnotationDecorations(DecSubj, Decorations.MemoryAccessesVec);
4452-
if (allowDecorateWithBufferLocationOrLatencyControlINTEL(II)) {
4453-
addAnnotationDecorations(DecSubj, Decorations.BufferLocationVec);
4454-
addAnnotationDecorations(DecSubj, Decorations.LatencyControlVec);
4455-
}
4456-
4457-
addAnnotationDecorations(DecSubj, Decorations.CacheControlVec);
4397+
addAnnotationDecorations(DecSubj, Decorations.MemoryAttributesVec);
4398+
// Apply the LSU parameter decoration to the pointer result of a GEP
4399+
// to the given struct member (InBoundsPtrAccessChain in SPIR-V).
4400+
// Decorating the member itself with a MemberDecoration is not feasible,
4401+
// because multiple accesses to the struct-held memory can require
4402+
// different LSU parameters.
4403+
addAnnotationDecorations(DecSubj, Decorations.MemoryAccessesVec);
4404+
addAnnotationDecorations(DecSubj, Decorations.CacheControlVec);
4405+
if (allowDecorateWithBufferLocationOrLatencyControlINTEL(II)) {
4406+
addAnnotationDecorations(DecSubj, Decorations.BufferLocationVec);
4407+
addAnnotationDecorations(DecSubj, Decorations.LatencyControlVec);
44584408
}
4459-
II->replaceAllUsesWith(II->getOperand(0));
44604409
}
4461-
return nullptr;
4410+
II->replaceAllUsesWith(II->getOperand(0));
4411+
return DecSubj;
44624412
}
44634413
case Intrinsic::stacksave: {
44644414
if (BM->isAllowedToUseExtension(

llvm-spirv/test/extensions/INTEL/SPV_INTEL_fpga_memory_accesses/IntelFPGAMemoryAccesses.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ entry:
204204
%15 = bitcast double addrspace(4)** %t to i8*
205205
call void @llvm.lifetime.start.p0i8(i64 8, i8* %15) #5
206206
; CHECK-LLVM: %[[FLOAT_FUNC_PARAM_LOAD:[[:alnum:].]+]] = load ptr addrspace(4), ptr %[[FLOAT_FUNC_PARAM]]
207-
; CHECK-LLVM: %[[BITCAST_FLOAT_TO_DOUBLE:[[:alnum:].]+]] = bitcast ptr addrspace(4) %[[FLOAT_FUNC_PARAM_LOAD]] to ptr addrspace(4)
208-
; CHECK-LLVM: %[[INTRINSIC_CALL:[[:alnum:].]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) %[[BITCAST_FLOAT_TO_DOUBLE]], ptr [[PARAM_3_CACHE_0]]
209-
; CHECK-LLVM: store ptr addrspace(4) %[[INTRINSIC_CALL]], ptr %[[DOUBLE_VAR]]
207+
; CHECK-LLVM: %[[INTRINSIC_CALL:[[:alnum:].]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) %[[FLOAT_FUNC_PARAM_LOAD]], ptr [[PARAM_3_CACHE_0]]
208+
; CHECK-LLVM: %[[BITCAST_FLOAT_TO_DOUBLE:[[:alnum:].]+]] = bitcast ptr addrspace(4) %[[INTRINSIC_CALL]] to ptr addrspace(4)
209+
; CHECK-LLVM: store ptr addrspace(4) %[[BITCAST_FLOAT_TO_DOUBLE]], ptr %[[DOUBLE_VAR]]
210210
%16 = load float addrspace(4)*, float addrspace(4)** %A.addr, align 8, !tbaa !5
211211
%17 = bitcast float addrspace(4)* %16 to double addrspace(4)*
212212
%18 = call double addrspace(4)* @llvm.ptr.annotation.p4f64(double addrspace(4)* %17, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i32 0, i32 0), i32 0, i8* null) #6

llvm-spirv/test/extensions/INTEL/SPV_INTEL_fpga_memory_accesses/intel_fpga_lsu_optimized.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,38 +90,38 @@ entry:
9090
; CHECK-LLVM: [[PTR_i27:[%0-9a-z.]+]] = getelementptr inbounds i32, ptr addrspace(1) {{[%0-9a-z._]+}}, i64 {{[%0-9a-z.]+}}
9191
; CHECK-LLVM: [[PTR_i:[%0-9a-z.]+]] = getelementptr inbounds i32, ptr addrspace(1) {{[%0-9a-z._]+}}, i64 {{[%0-9a-z.]+}}
9292
; CHECK-LLVM: [[PTR_i27_AS_CAST:[%0-9a-z.]+]] = addrspacecast ptr addrspace(1) [[PTR_i27]] to ptr addrspace(4)
93-
; CHECK-LLVM: [[PTR_i27_BIT_CAST:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_i27_AS_CAST]] to ptr addrspace(4)
94-
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) [[PTR_i27_BIT_CAST]], ptr [[PTR_i27_ANNOT_STR]]
93+
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) [[PTR_i27_AS_CAST]], ptr [[PTR_i27_ANNOT_STR]]
9594
; CHECK-LLVM: [[PTR_ANNOT_CALL_BC:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_ANNOT_CALL]] to ptr addrspace(4)
96-
; CHECK-LLVM: [[PTR_RESULT_LOAD:[%0-9a-z.]+]] = load i32, ptr addrspace(4) [[PTR_ANNOT_CALL_BC]]
95+
; CHECK-LLVM: [[PTR_ANNOT_CALL_BC2:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_ANNOT_CALL_BC]] to ptr addrspace(4)
96+
; CHECK-LLVM: [[PTR_RESULT_LOAD:[%0-9a-z.]+]] = load i32, ptr addrspace(4) [[PTR_ANNOT_CALL_BC2]]
9797
%add.ptr.i15.i = getelementptr inbounds i32, i32 addrspace(1)* %add.ptr.i27, i64 1
9898
%7 = addrspacecast i32 addrspace(1)* %add.ptr.i15.i to i32 addrspace(4)*
9999
%8 = tail call dereferenceable(4) i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* %7, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i64 0, i64 0), i32 0, i8* null) #2
100100
%9 = load i32, i32 addrspace(4)* %8, align 4, !tbaa !9
101101
; CHECK-LLVM: [[PTR_i15_i:[%0-9a-z.]+]] = getelementptr inbounds i32, ptr addrspace(1) {{[%0-9a-z._]+}}, i64 {{[%0-9a-z.]+}}
102102
; CHECK-LLVM: [[PTR_i15_i_AS_CAST:[%0-9a-z.]+]] = addrspacecast ptr addrspace(1) [[PTR_i15_i]] to ptr addrspace(4)
103-
; CHECK-LLVM: [[PTR_i15_i_BIT_CAST:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_i15_i_AS_CAST]] to ptr addrspace(4)
104-
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) [[PTR_i15_i_BIT_CAST]], ptr [[PTR_i15_i_ANNOT_STR]]
103+
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) [[PTR_i15_i_AS_CAST]], ptr [[PTR_i15_i_ANNOT_STR]]
105104
; CHECK-LLVM: [[PTR_ANNOT_CALL_BC:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_ANNOT_CALL]] to ptr addrspace(4)
106-
; CHECK-LLVM: [[PTR_RESULT_LOAD_1:[%0-9a-z.]+]] = load i32, ptr addrspace(4) [[PTR_ANNOT_CALL_BC]]
105+
; CHECK-LLVM: [[PTR_ANNOT_CALL_BC2:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_ANNOT_CALL_BC]] to ptr addrspace(4)
106+
; CHECK-LLVM: [[PTR_RESULT_LOAD_1:[%0-9a-z.]+]] = load i32, ptr addrspace(4) [[PTR_ANNOT_CALL_BC2]]
107107
%10 = addrspacecast i32 addrspace(1)* %add.ptr.i to i32 addrspace(4)*
108108
%11 = tail call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* %10, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i64 0, i64 0), i32 0, i8* null) #2
109109
store i32 %6, i32 addrspace(4)* %11, align 4, !tbaa !9
110110
; CHECK-LLVM: [[PTR_i_AS_CAST:[%0-9a-z.]+]] = addrspacecast ptr addrspace(1) [[PTR_i]] to ptr addrspace(4)
111-
; CHECK-LLVM: [[PTR_i_BIT_CAST:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_i_AS_CAST]] to ptr addrspace(4)
112-
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) [[PTR_i_BIT_CAST]], ptr [[PTR_i_ANNOT_STR]]
111+
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) [[PTR_i_AS_CAST]], ptr [[PTR_i_ANNOT_STR]]
113112
; CHECK-LLVM: [[PTR_ANNOT_CALL_BC:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_ANNOT_CALL]] to ptr addrspace(4)
114-
; CHECK-LLVM: store i32 [[PTR_RESULT_LOAD]], ptr addrspace(4) [[PTR_ANNOT_CALL_BC]]
113+
; CHECK-LLVM: [[PTR_ANNOT_CALL_BC2:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_ANNOT_CALL_BC]] to ptr addrspace(4)
114+
; CHECK-LLVM: store i32 [[PTR_RESULT_LOAD]], ptr addrspace(4) [[PTR_ANNOT_CALL_BC2]]
115115
%add.ptr.i.i = getelementptr inbounds i32, i32 addrspace(1)* %add.ptr.i, i64 1
116116
%12 = addrspacecast i32 addrspace(1)* %add.ptr.i.i to i32 addrspace(4)*
117117
%13 = tail call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* %12, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.4, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i64 0, i64 0), i32 0, i8* null) #2
118118
store i32 %9, i32 addrspace(4)* %13, align 4, !tbaa !9
119119
; CHECK-LLVM: [[PTR_i_i:[%0-9a-z.]+]] = getelementptr inbounds i32, ptr addrspace(1) {{[%0-9a-z._]+}}, i64 {{[%0-9a-z.]+}}
120120
; CHECK-LLVM: [[PTR_i_i_AS_CAST:[%0-9a-z.]+]] = addrspacecast ptr addrspace(1) [[PTR_i_i]] to ptr addrspace(4)
121-
; CHECK-LLVM: [[PTR_i_i_BIT_CAST:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_i_i_AS_CAST]] to ptr addrspace(4)
122-
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) [[PTR_i_i_BIT_CAST]], ptr [[PTR_i_i_ANNOT_STR]]
121+
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) [[PTR_i_i_AS_CAST]], ptr [[PTR_i_i_ANNOT_STR]]
123122
; CHECK-LLVM: [[PTR_ANNOT_CALL_BC:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_ANNOT_CALL]] to ptr addrspace(4)
124-
; CHECK-LLVM: store i32 [[PTR_RESULT_LOAD_1]], ptr addrspace(4) [[PTR_ANNOT_CALL_BC]]
123+
; CHECK-LLVM: [[PTR_ANNOT_CALL_BC2:[%0-9a-z.]+]] = bitcast ptr addrspace(4) [[PTR_ANNOT_CALL_BC]] to ptr addrspace(4)
124+
; CHECK-LLVM: store i32 [[PTR_RESULT_LOAD_1]], ptr addrspace(4) [[PTR_ANNOT_CALL_BC2]]
125125
ret void
126126
}
127127

0 commit comments

Comments
 (0)