Skip to content

Commit 89b319e

Browse files
FznamznonMrSidims
authored andcommitted
Fix SPIRV->LLVM translation of variable lenght arrays
VLAs were translated in section where non-instruction SPIR-V values are translated. Hovewer translation of them produce LLVM IR instructions. This patch moves translation of VLAs to the proper place where other instructions are created, so the placeholder creation logic also works for them. This fixes the case when VLA used in complex control flow graph caused producing of invalid LLVM module during reverse translation.
1 parent 0a1f59c commit 89b319e

File tree

2 files changed

+143
-15
lines changed

2 files changed

+143
-15
lines changed

lib/SPIRV/SPIRVReader.cpp

+17-15
Original file line numberDiff line numberDiff line change
@@ -1515,21 +1515,6 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
15151515
return Res;
15161516
}
15171517

1518-
case OpVariableLengthArrayINTEL: {
1519-
auto *VLA = static_cast<SPIRVVariableLengthArrayINTEL *>(BV);
1520-
llvm::Type *Ty = transType(BV->getType()->getPointerElementType());
1521-
llvm::Value *ArrSize = transValue(VLA->getOperand(0), F, BB, false);
1522-
return mapValue(
1523-
BV, new AllocaInst(Ty, SPIRAS_Private, ArrSize, BV->getName(), BB));
1524-
}
1525-
case OpRestoreMemoryINTEL: {
1526-
auto *Restore = static_cast<SPIRVRestoreMemoryINTEL *>(BV);
1527-
llvm::Value *Ptr = transValue(Restore->getOperand(0), F, BB, false);
1528-
Function *StackRestore =
1529-
Intrinsic::getDeclaration(M, Intrinsic::stackrestore);
1530-
return mapValue(BV, CallInst::Create(StackRestore, {Ptr}, "", BB));
1531-
}
1532-
15331518
case OpFunctionParameter: {
15341519
auto BA = static_cast<SPIRVFunctionParameter *>(BV);
15351520
assert(F && "Invalid function");
@@ -1579,10 +1564,27 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
15791564
// Translation of instructions
15801565
int OpCode = BV->getOpCode();
15811566
switch (OpCode) {
1567+
case OpVariableLengthArrayINTEL: {
1568+
auto *VLA = static_cast<SPIRVVariableLengthArrayINTEL *>(BV);
1569+
llvm::Type *Ty = transType(BV->getType()->getPointerElementType());
1570+
llvm::Value *ArrSize = transValue(VLA->getOperand(0), F, BB);
1571+
return mapValue(
1572+
BV, new AllocaInst(Ty, SPIRAS_Private, ArrSize, BV->getName(), BB));
1573+
}
1574+
1575+
case OpRestoreMemoryINTEL: {
1576+
auto *Restore = static_cast<SPIRVRestoreMemoryINTEL *>(BV);
1577+
llvm::Value *Ptr = transValue(Restore->getOperand(0), F, BB);
1578+
Function *StackRestore =
1579+
Intrinsic::getDeclaration(M, Intrinsic::stackrestore);
1580+
return mapValue(BV, CallInst::Create(StackRestore, {Ptr}, "", BB));
1581+
}
1582+
15821583
case OpSaveMemoryINTEL: {
15831584
Function *StackSave = Intrinsic::getDeclaration(M, Intrinsic::stacksave);
15841585
return mapValue(BV, CallInst::Create(StackSave, "", BB));
15851586
}
1587+
15861588
case OpBranch: {
15871589
auto *BR = static_cast<SPIRVBranch *>(BV);
15881590
auto *BI = BranchInst::Create(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
; RUN: llvm-as < %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_variable_length_array
3+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
4+
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
5+
6+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
7+
target triple = "spir64-unknown-unknown"
8+
9+
; Function Attrs: noinline nounwind optnone uwtable
10+
define weak dso_local spir_kernel void @K(i32 addrspace(1)* %S.ul.GEP.1) local_unnamed_addr #0 {
11+
newFuncRoot:
12+
%.ascast1 = addrspacecast i32 addrspace(1)* %S.ul.GEP.1 to i32 addrspace(4)*
13+
%S.ul.GEP.1.addr = alloca i32 addrspace(4)*, align 8
14+
store i32 addrspace(4)* %.ascast1, i32 addrspace(4)** %S.ul.GEP.1.addr, align 8
15+
%S.ul.GEP.1.value = load i32 addrspace(4)*, i32 addrspace(4)** %S.ul.GEP.1.addr, align 8
16+
%"$loop_ctr46" = alloca i64, align 8
17+
%"$loop_ctr50" = alloca i64, align 8
18+
%"$loop_ctr38" = alloca i64, align 8
19+
%"var$102" = alloca i64, align 8
20+
%"var$103" = alloca i32, align 4
21+
%temp = alloca i32, align 4
22+
br label %fallthru
23+
24+
; CHECK-LABEL: bb269
25+
; CHECK-LLVM: %1 = getelementptr inbounds i32, i32* %"ascastB$val41", i64 %0
26+
bb269: ; preds = %bb269.preheader, %bb269
27+
%"var$102_fetch.202" = load i64, i64* %"var$102", align 1
28+
%0 = sub nsw i64 %"var$102_fetch.202", 1
29+
%1 = getelementptr inbounds i32, i32* %"ascastB$val41", i64 %0
30+
%add.17 = add nsw i64 %"var$102_fetch.202", 1
31+
store i64 %add.17, i64* %"var$102", align 1
32+
%"var$103_fetch.203" = load i32, i32* %"var$103", align 1
33+
%add.18 = add nsw i32 %"var$103_fetch.203", 1
34+
store i32 %add.18, i32* %"var$103", align 1
35+
%"var$103_fetch.204" = load i32, i32* %"var$103", align 1
36+
%"ascastB$val_fetch.205" = load i32, i32* %temp, align 1
37+
%rel.41 = icmp sle i32 %"var$103_fetch.204", %"ascastB$val_fetch.205"
38+
br i1 %rel.41, label %bb269, label %bb270.loopexit
39+
40+
bb270.loopexit: ; preds = %bb269
41+
br label %bb270
42+
43+
bb270: ; preds = %bb270.loopexit, %fallthru
44+
store i64 1, i64* %"$loop_ctr38", align 1
45+
br label %loop_test315
46+
47+
loop_test315: ; preds = ,loop_body316, %bb270
48+
%"$loop_ctr_fetch.208" = load i64, i64* %"$loop_ctr38", align 1
49+
%rel.42 = icmp sle i64 %"$loop_ctr_fetch.208", %int_sext39
50+
br i1 %rel.42, label %loop_body316, label %loop_exit317
51+
52+
; CHECK-LABEL: loop_body316
53+
; CHECK-LLVM: %3 = getelementptr inbounds i32, i32* %"ascastB$val41", i64 %2
54+
loop_body316: ; preds = %loop_test315
55+
%"$loop_ctr_fetch.206" = load i64, i64* %"$loop_ctr38", align 1
56+
%2 = sub nsw i64 %"$loop_ctr_fetch.206", 1
57+
%3 = getelementptr inbounds i32, i32* %"ascastB$val41", i64 %2
58+
%"ascastB$val[]_fetch.207" = load i32, i32* %3, align 1
59+
%"$loop_ctr_fetch.195" = load i64, i64* %"$loop_ctr38", align 1
60+
br label %loop_test315
61+
62+
loop_exit317: ; preds = %loop_body316
63+
call spir_func void @llvm.stackrestore(i8* %"$stacksave37")
64+
%S.ul.GEP.1_fetch.210 = load i32, i32 addrspace(4)* %S.ul.GEP.1.value, align 1
65+
%int_sext47 = sext i32 %S.ul.GEP.1_fetch.210 to i64
66+
store i64 1, i64* %"$loop_ctr46", align 1
67+
br label %loop_test323
68+
69+
loop_test323: ; preds = %loop_body324, %loop_exit317
70+
%"$loop_ctr_fetch.212" = load i64, i64* %"$loop_ctr46", align 1
71+
%rel.45 = icmp sle i64 %"$loop_ctr_fetch.212", %int_sext47
72+
br i1 %rel.45, label %loop_body324, label %loop_exit325
73+
74+
loop_body324: ; preds = %loop_test323
75+
%"$loop_ctr_fetch.211" = load i64, i64* %"$loop_ctr46", align 1
76+
br label %loop_test323
77+
78+
loop_exit325: ; preds = %loop_test323
79+
%S.ul.GEP.1_fetch.214 = load i32, i32 addrspace(4)* %S.ul.GEP.1.value, align 1
80+
%int_sext51 = sext i32 %S.ul.GEP.1_fetch.214 to i64
81+
store i64 1, i64* %"$loop_ctr50", align 1
82+
br label %loop_test327
83+
84+
loop_test327: ; preds = %loop_body328, %loop_exit325
85+
%"$loop_ctr_fetch.216" = load i64, i64* %"$loop_ctr50", align 1
86+
%rel.48 = icmp sle i64 %"$loop_ctr_fetch.216", %int_sext51
87+
br i1 %rel.48, label %loop_body328, label %loop_exit329
88+
89+
loop_body328: ; preds = %loop_test327
90+
%"$loop_ctr_fetch.215" = load i64, i64* %"$loop_ctr50", align 1
91+
br label %loop_test327
92+
93+
loop_exit329: ; preds = %loop_test327
94+
ret void
95+
; CHECK-LABEL: fallthru
96+
; CHECK-LLVM: %"ascastB$val41" = alloca i32, i64 %div.3
97+
fallthru: ; preds = %newFuncRoot
98+
%"$stacksave37" = call spir_func i8* @llvm.stacksave()
99+
%S.ul.GEP.1_fetch.194 = load i32, i32 addrspace(4)* %S.ul.GEP.1.value, align 1
100+
%int_sext39 = sext i32 %S.ul.GEP.1_fetch.194 to i64
101+
%rel.39 = icmp sgt i32 0, %S.ul.GEP.1_fetch.194
102+
%slct.13 = select i1 %rel.39, i32 0, i32 %S.ul.GEP.1_fetch.194
103+
%int_sext40 = sext i32 %slct.13 to i64
104+
%mul.11 = mul nsw i64 %int_sext40, 4
105+
%div.3 = sdiv i64 %mul.11, 4
106+
%"ascastB$val41" = alloca i32, i64 %div.3, align 4
107+
store i64 1, i64* %"var$102", align 1
108+
store i32 %S.ul.GEP.1_fetch.194, i32* %temp, align 1
109+
store i32 1, i32* %"var$103", align 1
110+
%"ascastB$val_fetch.197" = load i32, i32* %temp, align 1
111+
%rel.40 = icmp slt i32 %"ascastB$val_fetch.197", 1
112+
br i1 %rel.40, label %bb270, label %bb269.preheader
113+
114+
bb269.preheader: ; preds = %fallthru
115+
br label %bb269
116+
}
117+
118+
; Function Attrs: nofree nosync nounwind willreturn mustprogress
119+
declare void @llvm.stackrestore(i8*) #1
120+
121+
; Function Attrs: nofree nosync nounwind willreturn mustprogress
122+
declare i8* @llvm.stacksave() #1
123+
124+
attributes #0 = { noinline nounwind optnone uwtable }
125+
attributes #1 = { nofree nosync nounwind willreturn mustprogress }
126+

0 commit comments

Comments
 (0)