Skip to content

Commit 6e97ea4

Browse files
vmaksimosys-ce-bb
authored andcommitted
Fix reverse translation of non-constant values of OpCompositeConstruct pt.2 (#2296)
This patch introduces a way to use runtime values for array and vector types. It continues #2256 Original commit: KhronosGroup/SPIRV-LLVM-Translator@4db768c
1 parent 22a99e0 commit 6e97ea4

File tree

4 files changed

+132
-12
lines changed

4 files changed

+132
-12
lines changed

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,11 +2238,38 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
22382238
}
22392239

22402240
switch (static_cast<size_t>(BV->getType()->getOpCode())) {
2241-
case OpTypeVector:
2242-
return mapValue(BV, ConstantVector::get(CV));
2241+
case OpTypeVector: {
2242+
if (!HasRtValues)
2243+
return mapValue(BV, ConstantVector::get(CV));
2244+
2245+
auto *VT = cast<FixedVectorType>(transType(CC->getType()));
2246+
Value *NewVec = ConstantVector::getSplat(
2247+
VT->getElementCount(), PoisonValue::get(VT->getElementType()));
2248+
2249+
for (size_t I = 0; I < Constituents.size(); I++) {
2250+
NewVec = InsertElementInst::Create(NewVec, Constituents[I],
2251+
getInt32(M, I), "", BB);
2252+
}
2253+
return mapValue(BV, NewVec);
2254+
}
22432255
case OpTypeArray: {
22442256
auto *AT = cast<ArrayType>(transType(CC->getType()));
2245-
return mapValue(BV, ConstantArray::get(AT, CV));
2257+
if (!HasRtValues)
2258+
return mapValue(BV, ConstantArray::get(AT, CV));
2259+
2260+
AllocaInst *Alloca = new AllocaInst(AT, SPIRAS_Private, "", BB);
2261+
2262+
// get pointer to the element of the array
2263+
// store the result of argument
2264+
for (size_t I = 0; I < Constituents.size(); I++) {
2265+
auto *GEP = GetElementPtrInst::Create(
2266+
Constituents[I]->getType(), Alloca, {getInt32(M, I)}, "gep", BB);
2267+
GEP->setIsInBounds(true);
2268+
new StoreInst(Constituents[I], GEP, false, BB);
2269+
}
2270+
2271+
auto *Load = new LoadInst(AT, Alloca, "load", false, BB);
2272+
return mapValue(BV, Load);
22462273
}
22472274
case OpTypeStruct: {
22482275
auto *ST = cast<StructType>(transType(CC->getType()));
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
; REQUIRES: spirv-as
2+
; RUN: spirv-as --target-env spv1.0 -o %t.spv %s
3+
; RUN: spirv-val %t.spv
4+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
5+
; RUN: llvm-dis %t.rev.bc
6+
; RUN: FileCheck < %t.rev.ll %s
7+
8+
; CHECK: define spir_func [4 x i8] @non_constant_array_elements(i8 %[[#ARG0:]], i8 %[[#ARG1:]])
9+
; CHECK: %[[#ArrayPtr:]] = alloca [4 x i8]
10+
; CHECK: %[[GEP:[0-9a-z.]+]] = getelementptr inbounds i8, ptr %[[#ArrayPtr]], i32 0
11+
; CHECK: store i8 %[[#ARG1]], ptr %[[GEP]]
12+
; CHECK: %[[GEP1:[0-9a-z.]+]] = getelementptr inbounds i8, ptr %[[#ArrayPtr]], i32 1
13+
; CHECK: store i8 %[[#ARG0]], ptr %[[GEP1]]
14+
; CHECK: %[[GEP2:[0-9a-z.]+]] = getelementptr inbounds i8, ptr %[[#ArrayPtr]], i32 2
15+
; CHECK: store i8 0, ptr %[[GEP2]]
16+
; CHECK: %[[GEP3:[0-9a-z.]+]] = getelementptr inbounds i8, ptr %[[#ArrayPtr]], i32 3
17+
; CHECK: store i8 10, ptr %[[GEP3]]
18+
19+
; CHECK: %[[LoadArr:[0-9a-z.]+]] = load [4 x i8], ptr %[[#ArrayPtr]]
20+
; CHECK: ret [4 x i8] %[[LoadArr]]
21+
22+
; SPIR-V
23+
; Version: 1.0
24+
; Generator: Khronos LLVM/SPIR-V Translator; 14
25+
; Bound: 23
26+
; Schema: 0
27+
OpCapability Addresses
28+
OpCapability Linkage
29+
OpCapability Kernel
30+
OpCapability Int8
31+
%1 = OpExtInstImport "OpenCL.std"
32+
OpMemoryModel Physical64 OpenCL
33+
OpSource Unknown 0
34+
OpName %_arr_uchar_uint_4 "arrtype"
35+
OpName %non_constant_array_elements "non_constant_array_elements"
36+
OpDecorate %non_constant_array_elements LinkageAttributes "non_constant_array_elements" Export
37+
%uchar = OpTypeInt 8 0
38+
%uint = OpTypeInt 32 0
39+
%uchar_10 = OpConstant %uchar 10
40+
%uchar_0 = OpConstant %uchar 0
41+
%uint_0 = OpConstant %uint 0
42+
%uint_1 = OpConstant %uint 1
43+
%uint_4 = OpConstant %uint 4
44+
%_arr_uchar_uint_4 = OpTypeArray %uchar %uint_4
45+
%5 = OpTypeFunction %_arr_uchar_uint_4 %uchar %uchar
46+
%_ptr_Function_uint = OpTypePointer Function %uint
47+
%non_constant_array_elements = OpFunction %_arr_uchar_uint_4 None %5
48+
%484 = OpFunctionParameter %uchar
49+
%485 = OpFunctionParameter %uchar
50+
%7 = OpLabel
51+
%14 = OpCompositeConstruct %_arr_uchar_uint_4 %485 %484 %uchar_0 %uchar_10
52+
OpReturnValue %14
53+
OpFunctionEnd

llvm-spirv/test/composite_construct_struct_non_constant.spt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
; RUN: spirv-val %t.spv
33
; RUN: llvm-spirv -r %t.spv -o %t.bc
44
; RUN: llvm-dis %t.bc
5-
; RUN: FileCheck < %t.ll %s --check-prefix=CHECK-LLVM
5+
; RUN: FileCheck < %t.ll %s
66

7-
; CHECK-LLVM: %[[StructTy:[0-9a-z.]+]] = type { float, i32 }
8-
; CHECK-LLVM: %[[#StructPtr:]] = alloca %[[StructTy]]
9-
; CHECK-LLVM: %[[GEP:[0-9a-z.]+]] = getelementptr inbounds float, ptr %[[#StructPtr]], i32 0
10-
; CHECK-LLVM: store float %[[#]], ptr %[[GEP]]
11-
; CHECK-LLVM: %[[GEP1:[0-9a-z.]+]] = getelementptr inbounds i32, ptr %[[#StructPtr]], i32 1
12-
; CHECK-LLVM: store i32 %[[#]], ptr %[[GEP1]]
13-
; CHECK-LLVM: %[[LoadStr:[0-9a-z.]+]] = load %[[StructTy]], ptr %[[#StructPtr]]
14-
; CHECK-LLVM: ret %[[StructTy]] %[[LoadStr]]
7+
; CHECK: %[[StructTy:[0-9a-z.]+]] = type { float, i32 }
8+
; CHECK: %[[#StructPtr:]] = alloca %[[StructTy]]
9+
; CHECK: %[[GEP:[0-9a-z.]+]] = getelementptr inbounds float, ptr %[[#StructPtr]], i32 0
10+
; CHECK: store float %[[#]], ptr %[[GEP]]
11+
; CHECK: %[[GEP1:[0-9a-z.]+]] = getelementptr inbounds i32, ptr %[[#StructPtr]], i32 1
12+
; CHECK: store i32 %[[#]], ptr %[[GEP1]]
13+
; CHECK: %[[LoadStr:[0-9a-z.]+]] = load %[[StructTy]], ptr %[[#StructPtr]]
14+
; CHECK: ret %[[StructTy]] %[[LoadStr]]
1515

1616
119734787 65536 393230 23 0
1717
2 Capability Addresses
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
; REQUIRES: spirv-as
2+
; RUN: spirv-as --target-env spv1.0 -o %t.spv %s
3+
; RUN: spirv-val %t.spv
4+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
5+
; RUN: llvm-dis %t.rev.bc
6+
; RUN: FileCheck < %t.rev.ll %s
7+
8+
; CHECK: define spir_func <3 x i32> @non_constant_vector_elements(i32 %[[#ARG0:]], i32 %[[#ARG1:]])
9+
; CHECK: %[[#VEC0:]] = insertelement <3 x i32> poison, i32 %[[#ARG1]], i32 0
10+
; CHECK: %[[#VEC1:]] = insertelement <3 x i32> %[[#VEC0]], i32 %[[#ARG0]], i32 1
11+
; CHECK: %[[#VEC2:]] = insertelement <3 x i32> %[[#VEC1]], i32 1, i32 2
12+
; CHECK: ret <3 x i32> %[[#VEC2]]
13+
14+
; SPIR-V
15+
; Version: 1.0
16+
; Generator: Khronos LLVM/SPIR-V Translator; 14
17+
; Bound: 23
18+
; Schema: 0
19+
OpCapability Addresses
20+
OpCapability Linkage
21+
OpCapability Kernel
22+
%1 = OpExtInstImport "OpenCL.std"
23+
OpMemoryModel Physical64 OpenCL
24+
OpSource Unknown 0
25+
OpName %vectype "vectype"
26+
OpName %non_constant_vector_elements "non_constant_vector_elements"
27+
OpDecorate %non_constant_vector_elements LinkageAttributes "non_constant_vector_elements" Export
28+
%uint = OpTypeInt 32 0
29+
%uint_0 = OpConstant %uint 0
30+
%uint_1 = OpConstant %uint 1
31+
%vectype = OpTypeVector %uint 3
32+
%5 = OpTypeFunction %vectype %uint %uint
33+
%_ptr_Function_uint = OpTypePointer Function %uint
34+
%non_constant_vector_elements = OpFunction %vectype None %5
35+
%484 = OpFunctionParameter %uint
36+
%485 = OpFunctionParameter %uint
37+
%7 = OpLabel
38+
%14 = OpCompositeConstruct %vectype %485 %484 %uint_1
39+
OpReturnValue %14
40+
OpFunctionEnd

0 commit comments

Comments
 (0)