Skip to content

Commit 3432def

Browse files
MrSidimsbader
authored andcommitted
Fix IntelFPGA memory attrs on struct that has c'tor
Strip all bitcast and addrspace casts from the pointer argument: llvm annotation intrinsic only takes i8*, so the original pointer probably had to loose its addrspace and its original type. Signed-off-by: Dmitry Sidorov <[email protected]>
1 parent 09fa8a7 commit 3432def

File tree

2 files changed

+88
-8
lines changed

2 files changed

+88
-8
lines changed

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,12 @@ void addIntelFPGADecorationsForStructMember(
12361236
SPIRVEntry *E, SPIRVWord MemberNumber,
12371237
std::vector<std::pair<Decoration, std::string>> &Decorations) {
12381238
for (const auto &I : Decorations) {
1239+
// Such decoration already exists on a type, skip it
1240+
if (E->hasMemberDecorate(I.first, /*Index=*/0, MemberNumber,
1241+
/*Result=*/nullptr)) {
1242+
continue;
1243+
}
1244+
12391245
switch (I.first) {
12401246
case DecorationMemoryINTEL:
12411247
E->addMemberDecorate(
@@ -1410,20 +1416,21 @@ SPIRVValue *LLVMToSPIRV::transIntrinsicInst(IntrinsicInst *II,
14101416
return SV;
14111417
}
14121418
case Intrinsic::ptr_annotation: {
1413-
GetElementPtrInst *GI;
1414-
if (auto *BI = dyn_cast<BitCastInst>(II->getArgOperand(0))) {
1415-
GI = dyn_cast<GetElementPtrInst>(BI->getOperand(0));
1416-
} else {
1417-
GI = dyn_cast<GetElementPtrInst>(II->getOperand(0));
1418-
}
1419-
14201419
GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(II->getArgOperand(1));
14211420
Constant *C = dyn_cast<Constant>(GEP->getOperand(0));
14221421
// TODO: Refactor to use getConstantStringInfo()
14231422
StringRef AnnotationString =
14241423
dyn_cast<ConstantDataArray>(C->getOperand(0))->getAsCString();
14251424

1426-
if (GI) {
1425+
// Strip all bitcast and addrspace casts from the pointer argument:
1426+
// llvm annotation intrinsic only takes i8*, so the original pointer
1427+
// probably had to loose its addrspace and its original type.
1428+
Value *AnnotSubj = II->getArgOperand(0);
1429+
while (isa<BitCastInst>(AnnotSubj) || isa<AddrSpaceCastInst>(AnnotSubj)) {
1430+
AnnotSubj = cast<CastInst>(AnnotSubj)->getOperand(0);
1431+
}
1432+
// If the pointer is a GEP, then we have to emit a member decoration
1433+
if (auto *GI = dyn_cast<GetElementPtrInst>(AnnotSubj)) {
14271434
auto *Ty = transType(GI->getSourceElementType());
14281435
SPIRVWord MemberNumber =
14291436
dyn_cast<ConstantInt>(GI->getOperand(2))->getZExtValue();

llvm-spirv/test/IntelFPGAMemoryAttributesForStruct.ll

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
; CHECK-SPIRV: MemberDecorate {{[0-9]+}} 0 MemoryINTEL "DEFAULT"
1212
; CHECK-SPIRV: MemberDecorate {{[0-9]+}} 3 MemoryINTEL "DEFAULT"
1313
; CHECK-SPIRV: MemberDecorate {{[0-9]+}} 2 MemoryINTEL "MLAB"
14+
; CHECK-SPIRV: MemberDecorate {{[0-9]+}} 0 NumbanksINTEL 2
1415
; CHECK-SPIRV: MemberDecorate {{[0-9]+}} 0 NumbanksINTEL 4
1516
; CHECK-SPIRV: MemberDecorate {{[0-9]+}} 3 BankwidthINTEL 8
1617
; CHECK-SPIRV: MemberDecorate {{[0-9]+}} 4 MaxPrivateCopiesINTEL 4
@@ -26,6 +27,8 @@ target triple = "spir64-unknown-linux"
2627
%class.anon = type { i8 }
2728
%struct.foo = type { i32, i32, i32, i32, i8, i32, i32, i32, i32, i32 }
2829

30+
%struct._ZTSZ20field_addrspace_castvE5state.state = type { [8 x i32] }
31+
2932
; CHECK-LLVM: [[STR1:@[0-9_.]+]] = {{.*}}{memory:DEFAULT}{numbanks:4}
3033
; CHECK-LLVM: [[STR2:@[0-9_.]+]] = {{.*}}{register:1}
3134
; CHECK-LLVM: [[STR3:@[0-9_.]+]] = {{.*}}{memory:MLAB}
@@ -36,6 +39,7 @@ target triple = "spir64-unknown-linux"
3639
; CHECK-LLVM: [[STR8:@[0-9_.]+]] = {{.*}}{memory:DEFAULT}{merge:foobar:width}
3740
; CHECK-LLVM: [[STR9:@[0-9_.]+]] = {{.*}}{max_replicates:4}
3841
; CHECK-LLVM: [[STR10:@[0-9_.]+]] = {{.*}}{memory:DEFAULT}{simple_dual_port:1}
42+
; CHECK-LLVM: [[STR11:@[0-9_.]+]] = {{.*}}{memory:DEFAULT}{numbanks:2}
3943
@.str = private unnamed_addr constant [29 x i8] c"{memory:DEFAULT}{numbanks:4}\00", section "llvm.metadata"
4044
@.str.1 = private unnamed_addr constant [16 x i8] c"test_struct.cpp\00", section "llvm.metadata"
4145
@.str.2 = private unnamed_addr constant [13 x i8] c"{register:1}\00", section "llvm.metadata"
@@ -47,6 +51,7 @@ target triple = "spir64-unknown-linux"
4751
@.str.8 = private unnamed_addr constant [37 x i8] c"{memory:DEFAULT}{merge:foobar:width}\00", section "llvm.metadata"
4852
@.str.9 = private unnamed_addr constant [19 x i8] c"{max_replicates:4}\00", section "llvm.metadata"
4953
@.str.10 = private unnamed_addr constant [37 x i8] c"{memory:DEFAULT}{simple_dual_port:1}\00", section "llvm.metadata"
54+
@.str.11 = private unnamed_addr constant [29 x i8] c"{memory:DEFAULT}{numbanks:2}\00", section "llvm.metadata"
5055

5156
; Function Attrs: nounwind
5257
define spir_kernel void @_ZTSZ4mainE15kernel_function() #0 !kernel_arg_addr_space !4 !kernel_arg_access_qual !4 !kernel_arg_type !4 !kernel_arg_base_type !4 !kernel_arg_type_qual !4 {
@@ -164,9 +169,77 @@ entry:
164169
ret void
165170
}
166171

172+
define spir_func void @_Z20field_addrspace_castv() #3 {
173+
entry:
174+
%state_var = alloca %struct._ZTSZ20field_addrspace_castvE5state.state, align 4
175+
%0 = bitcast %struct._ZTSZ20field_addrspace_castvE5state.state* %state_var to i8*
176+
call void @llvm.lifetime.start.p0i8(i64 32, i8* %0) #4
177+
%1 = addrspacecast %struct._ZTSZ20field_addrspace_castvE5state.state* %state_var to %struct._ZTSZ20field_addrspace_castvE5state.state addrspace(4)*
178+
call spir_func void @_ZZ20field_addrspace_castvEN5stateC2Ev(%struct._ZTSZ20field_addrspace_castvE5state.state addrspace(4)* %1)
179+
%mem = getelementptr inbounds %struct._ZTSZ20field_addrspace_castvE5state.state, %struct._ZTSZ20field_addrspace_castvE5state.state* %state_var, i32 0, i32 0
180+
; CHECK-LLVM: %[[GEP:.*]] = getelementptr inbounds %struct._ZTSZ20field_addrspace_castvE5state.state, %struct._ZTSZ20field_addrspace_castvE5state.state* %state_var, i32 0, i32 0
181+
; CHECK-LLVM: %[[CAST11:.*]] = bitcast [8 x i32]* %[[GEP:.*]] to i8*
182+
; CHECK-LLVM: %{{[0-9]+}} = call i8* @llvm.ptr.annotation.p0i8(i8* %[[CAST11]]{{.*}}[[STR11]]
183+
%2 = bitcast [8 x i32]* %mem to i8*
184+
%3 = call i8* @llvm.ptr.annotation.p0i8(i8* %2, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.11, i32 0, i32 0), i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.1, i32 0, i32 0), i32 24)
185+
%4 = bitcast i8* %3 to [8 x i32]*
186+
%arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* %4, i64 0, i64 0
187+
store i32 42, i32* %arrayidx, align 4, !tbaa !9
188+
%5 = bitcast %struct._ZTSZ20field_addrspace_castvE5state.state* %state_var to i8*
189+
call void @llvm.lifetime.end.p0i8(i64 32, i8* %5) #4
190+
ret void
191+
}
192+
193+
define internal spir_func void @_ZZ20field_addrspace_castvEN5stateC2Ev(%struct._ZTSZ20field_addrspace_castvE5state.state addrspace(4)* %this) unnamed_addr #3 align 2 {
194+
entry:
195+
%this.addr = alloca %struct._ZTSZ20field_addrspace_castvE5state.state addrspace(4)*, align 8
196+
%i = alloca i32, align 4
197+
store %struct._ZTSZ20field_addrspace_castvE5state.state addrspace(4)* %this, %struct._ZTSZ20field_addrspace_castvE5state.state addrspace(4)** %this.addr, align 8, !tbaa !5
198+
%this1 = load %struct._ZTSZ20field_addrspace_castvE5state.state addrspace(4)*, %struct._ZTSZ20field_addrspace_castvE5state.state addrspace(4)** %this.addr, align 8
199+
%0 = bitcast i32* %i to i8*
200+
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #4
201+
store i32 0, i32* %i, align 4, !tbaa !9
202+
br label %for.cond
203+
204+
for.cond: ; preds = %for.inc, %entry
205+
%1 = load i32, i32* %i, align 4, !tbaa !9
206+
%cmp = icmp slt i32 %1, 8
207+
br i1 %cmp, label %for.body, label %for.cond.cleanup
208+
209+
for.cond.cleanup: ; preds = %for.cond
210+
%2 = bitcast i32* %i to i8*
211+
call void @llvm.lifetime.end.p0i8(i64 4, i8* %2) #4
212+
br label %for.end
213+
214+
for.body: ; preds = %for.cond
215+
%3 = load i32, i32* %i, align 4, !tbaa !9
216+
%mem = getelementptr inbounds %struct._ZTSZ20field_addrspace_castvE5state.state, %struct._ZTSZ20field_addrspace_castvE5state.state addrspace(4)* %this1, i32 0, i32 0
217+
; FIXME: currently llvm.ptr.annotation is not emitted for c'tors, need to fix it and add a check here
218+
%4 = bitcast [8 x i32] addrspace(4)* %mem to i8 addrspace(4)*
219+
%5 = call i8 addrspace(4)* @llvm.ptr.annotation.p4i8(i8 addrspace(4)* %4, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.11, i32 0, i32 0), i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.1, i32 0, i32 0), i32 24)
220+
%6 = bitcast i8 addrspace(4)* %5 to [8 x i32] addrspace(4)*
221+
%7 = load i32, i32* %i, align 4, !tbaa !9
222+
%idxprom = sext i32 %7 to i64
223+
%arrayidx = getelementptr inbounds [8 x i32], [8 x i32] addrspace(4)* %6, i64 0, i64 %idxprom
224+
store i32 %3, i32 addrspace(4)* %arrayidx, align 4, !tbaa !9
225+
br label %for.inc
226+
227+
for.inc: ; preds = %for.body
228+
%8 = load i32, i32* %i, align 4, !tbaa !9
229+
%inc = add nsw i32 %8, 1
230+
store i32 %inc, i32* %i, align 4, !tbaa !9
231+
br label %for.cond
232+
233+
for.end: ; preds = %for.cond.cleanup
234+
ret void
235+
}
236+
167237
; Function Attrs: nounwind
168238
declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32) #4
169239

240+
; Function Attrs: nounwind
241+
declare i8 addrspace(4)* @llvm.ptr.annotation.p4i8(i8 addrspace(4)*, i8*, i8*, i32) #4
242+
170243
attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" }
171244
attributes #1 = { argmemonly nounwind }
172245
attributes #2 = { inlinehint nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }

0 commit comments

Comments
 (0)