Skip to content

Commit e17a42e

Browse files
committed
Add missing test. Rewrite extract generated extract instruction to spv intrinsic.
1 parent 92c6074 commit e17a42e

File tree

2 files changed

+150
-1
lines changed

2 files changed

+150
-1
lines changed

llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
178178
.alwaysLegal();
179179

180180
getActionDefinitionsBuilder(G_EXTRACT_VECTOR_ELT)
181-
.legalIf(vectorElementCountIsLessThanOrEqualTo(1, MaxVectorSize))
182181
.moreElementsToNextPow2(1)
183182
.fewerElementsIf(vectorElementCountIsGreaterThan(1, MaxVectorSize),
184183
LegalizeMutations::changeElementCountTo(
@@ -426,6 +425,21 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
426425
verify(*ST.getInstrInfo());
427426
}
428427

428+
static bool legalizeExtractVectorElt(LegalizerHelper &Helper, MachineInstr &MI,
429+
SPIRVGlobalRegistry *GR) {
430+
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
431+
Register DstReg = MI.getOperand(0).getReg();
432+
Register SrcReg = MI.getOperand(1).getReg();
433+
Register IdxReg = MI.getOperand(2).getReg();
434+
435+
MIRBuilder
436+
.buildIntrinsic(Intrinsic::spv_extractelt, ArrayRef<Register>{DstReg})
437+
.addUse(SrcReg)
438+
.addUse(IdxReg);
439+
MI.eraseFromParent();
440+
return true;
441+
}
442+
429443
static Register convertPtrToInt(Register Reg, LLT ConvTy, SPIRVType *SpvType,
430444
LegalizerHelper &Helper,
431445
MachineRegisterInfo &MRI,
@@ -449,6 +463,8 @@ bool SPIRVLegalizerInfo::legalizeCustom(
449463
return true;
450464
case TargetOpcode::G_BITCAST:
451465
return legalizeBitcast(Helper, MI);
466+
case TargetOpcode::G_EXTRACT_VECTOR_ELT:
467+
return legalizeExtractVectorElt(Helper, MI, GR);
452468
case TargetOpcode::G_INTRINSIC:
453469
case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
454470
return legalizeIntrinsic(Helper, MI);
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-vulkan %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan %s -o - -filetype=obj | spirv-val --target-env vulkan1.3 %}
3+
4+
; CHECK-DAG: %[[#int:]] = OpTypeInt 32 0
5+
; CHECK-DAG: %[[#double:]] = OpTypeFloat 64
6+
; CHECK-DAG: %[[#v4int:]] = OpTypeVector %[[#int]] 4
7+
; CHECK-DAG: %[[#v4double:]] = OpTypeVector %[[#double]] 4
8+
; CHECK-DAG: %[[#v2int:]] = OpTypeVector %[[#int]] 2
9+
; CHECK-DAG: %[[#v2double:]] = OpTypeVector %[[#double]] 2
10+
; CHECK-DAG: %[[#v3int:]] = OpTypeVector %[[#int]] 3
11+
; CHECK-DAG: %[[#v3double:]] = OpTypeVector %[[#double]] 3
12+
; CHECK-DAG: %[[#ptr_v4double:]] = OpTypePointer Private %[[#v4double]]
13+
; CHECK-DAG: %[[#ptr_v4int:]] = OpTypePointer Private %[[#v4int]]
14+
; CHECK-DAG: %[[#ptr_v3double:]] = OpTypePointer Private %[[#v3double]]
15+
; CHECK-DAG: %[[#ptr_v3int:]] = OpTypePointer Private %[[#v3int]]
16+
; CHECK-DAG: %[[#GVec4:]] = OpVariable %[[#ptr_v4double]] Private
17+
; CHECK-DAG: %[[#Lows:]] = OpVariable %[[#ptr_v4int]] Private
18+
; CHECK-DAG: %[[#Highs:]] = OpVariable %[[#ptr_v4int]] Private
19+
; CHECK-DAG: %[[#GVec3:]] = OpVariable %[[#ptr_v3double]] Private
20+
; CHECK-DAG: %[[#Lows3:]] = OpVariable %[[#ptr_v3int]] Private
21+
; CHECK-DAG: %[[#Highs3:]] = OpVariable %[[#ptr_v3int]] Private
22+
23+
@GVec4 = internal addrspace(10) global <4 x double> zeroinitializer
24+
@Lows = internal addrspace(10) global <4 x i32> zeroinitializer
25+
@Highs = internal addrspace(10) global <4 x i32> zeroinitializer
26+
@GVec3 = internal addrspace(10) global <3 x double> zeroinitializer
27+
@Lows3 = internal addrspace(10) global <3 x i32> zeroinitializer
28+
@Highs3 = internal addrspace(10) global <3 x i32> zeroinitializer
29+
30+
; Test splitting a vector of size 8.
31+
define internal void @test_split() {
32+
entry:
33+
; CHECK: %[[#load_v4double:]] = OpLoad %[[#v4double]] %[[#GVec4]]
34+
; CHECK: %[[#v2double_01:]] = OpVectorShuffle %[[#v2double]] %[[#load_v4double]] %{{[a-zA-Z0-9_]+}} 0 1
35+
; CHECK: %[[#v2double_23:]] = OpVectorShuffle %[[#v2double]] %[[#load_v4double]] %{{[a-zA-Z0-9_]+}} 2 3
36+
; CHECK: %[[#v4int_01:]] = OpBitcast %[[#v4int]] %[[#v2double_01]]
37+
; CHECK: %[[#v4int_23:]] = OpBitcast %[[#v4int]] %[[#v2double_23]]
38+
%0 = load <8 x i32>, ptr addrspace(10) @GVec4, align 32
39+
40+
; CHECK: %[[#l0:]] = OpCompositeExtract %[[#int]] %[[#v4int_01]] 0
41+
; CHECK: %[[#l1:]] = OpCompositeExtract %[[#int]] %[[#v4int_01]] 2
42+
; CHECK: %[[#l2:]] = OpCompositeExtract %[[#int]] %[[#v4int_23]] 0
43+
; CHECK: %[[#l3:]] = OpCompositeExtract %[[#int]] %[[#v4int_23]] 2
44+
; CHECK: %[[#res_low:]] = OpCompositeConstruct %[[#v4int]] %[[#l0]] %[[#l1]] %[[#l2]] %[[#l3]]
45+
%1 = shufflevector <8 x i32> %0, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
46+
47+
; CHECK: %[[#h0:]] = OpCompositeExtract %[[#int]] %[[#v4int_01]] 1
48+
; CHECK: %[[#h1:]] = OpCompositeExtract %[[#int]] %[[#v4int_01]] 3
49+
; CHECK: %[[#h2:]] = OpCompositeExtract %[[#int]] %[[#v4int_23]] 1
50+
; CHECK: %[[#h3:]] = OpCompositeExtract %[[#int]] %[[#v4int_23]] 3
51+
; CHECK: %[[#res_high:]] = OpCompositeConstruct %[[#v4int]] %[[#h0]] %[[#h1]] %[[#h2]] %[[#h3]]
52+
%2 = shufflevector <8 x i32> %0, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
53+
54+
store <4 x i32> %1, ptr addrspace(10) @Lows, align 16
55+
store <4 x i32> %2, ptr addrspace(10) @Highs, align 16
56+
ret void
57+
}
58+
59+
define internal void @test_recombine() {
60+
entry:
61+
; CHECK: %[[#l:]] = OpLoad %[[#v4int]] %[[#Lows]]
62+
%0 = load <4 x i32>, ptr addrspace(10) @Lows, align 16
63+
; CHECK: %[[#h:]] = OpLoad %[[#v4int]] %[[#Highs]]
64+
%1 = load <4 x i32>, ptr addrspace(10) @Highs, align 16
65+
66+
; CHECK-DAG: %[[#l0:]] = OpCompositeExtract %[[#int]] %[[#l]] 0
67+
; CHECK-DAG: %[[#l1:]] = OpCompositeExtract %[[#int]] %[[#l]] 1
68+
; CHECK-DAG: %[[#l2:]] = OpCompositeExtract %[[#int]] %[[#l]] 2
69+
; CHECK-DAG: %[[#l3:]] = OpCompositeExtract %[[#int]] %[[#l]] 3
70+
; CHECK-DAG: %[[#h0:]] = OpCompositeExtract %[[#int]] %[[#h]] 0
71+
; CHECK-DAG: %[[#h1:]] = OpCompositeExtract %[[#int]] %[[#h]] 1
72+
; CHECK-DAG: %[[#h2:]] = OpCompositeExtract %[[#int]] %[[#h]] 2
73+
; CHECK-DAG: %[[#h3:]] = OpCompositeExtract %[[#int]] %[[#h]] 3
74+
; CHECK-DAG: %[[#v2i0:]] = OpCompositeConstruct %[[#v2int]] %[[#l0]] %[[#h0]]
75+
; CHECK-DAG: %[[#d0:]] = OpBitcast %[[#double]] %[[#v2i0]]
76+
; CHECK-DAG: %[[#v2i1:]] = OpCompositeConstruct %[[#v2int]] %[[#l1]] %[[#h1]]
77+
; CHECK-DAG: %[[#d1:]] = OpBitcast %[[#double]] %[[#v2i1]]
78+
; CHECK-DAG: %[[#v2i2:]] = OpCompositeConstruct %[[#v2int]] %[[#l2]] %[[#h2]]
79+
; CHECK-DAG: %[[#d2:]] = OpBitcast %[[#double]] %[[#v2i2]]
80+
; CHECK-DAG: %[[#v2i3:]] = OpCompositeConstruct %[[#v2int]] %[[#l3]] %[[#h3]]
81+
; CHECK-DAG: %[[#d3:]] = OpBitcast %[[#double]] %[[#v2i3]]
82+
; CHECK-DAG: %[[#res:]] = OpCompositeConstruct %[[#v4double]] %[[#d0]] %[[#d1]] %[[#d2]] %[[#d3]]
83+
%2 = shufflevector <4 x i32> %0, <4 x i32> %1, <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7>
84+
85+
; CHECK: OpStore %[[#GVec4]] %[[#res]]
86+
store <8 x i32> %2, ptr addrspace(10) @GVec4, align 32
87+
ret void
88+
}
89+
90+
; Test splitting a vector of size 6. It must be expanded to 8, and then split.
91+
define internal void @test_bitcast_expand() {
92+
entry:
93+
; CHECK: %[[#load:]] = OpLoad %[[#v3double]] %[[#GVec3]]
94+
%0 = load <3 x double>, ptr addrspace(10) @GVec3, align 32
95+
96+
; CHECK: %[[#d0:]] = OpCompositeExtract %[[#double]] %[[#load]] 0
97+
; CHECK: %[[#d1:]] = OpCompositeExtract %[[#double]] %[[#load]] 1
98+
; CHECK: %[[#d2:]] = OpCompositeExtract %[[#double]] %[[#load]] 2
99+
; CHECK: %[[#v2d0:]] = OpCompositeConstruct %[[#v2double]] %[[#d0]] %[[#d1]]
100+
; CHECK: %[[#v2d1:]] = OpCompositeConstruct %[[#v2double]] %[[#d2]] %[[#]]
101+
; CHECK: %[[#v4i0:]] = OpBitcast %[[#v4int]] %[[#v2d0]]
102+
; CHECK: %[[#v4i1:]] = OpBitcast %[[#v4int]] %[[#v2d1]]
103+
%1 = bitcast <3 x double> %0 to <6 x i32>
104+
105+
; CHECK: %[[#l0:]] = OpCompositeExtract %[[#int]] %[[#v4i0]] 0
106+
; CHECK: %[[#l1:]] = OpCompositeExtract %[[#int]] %[[#v4i0]] 2
107+
; CHECK: %[[#l2:]] = OpCompositeExtract %[[#int]] %[[#v4i1]] 0
108+
; CHECK: %[[#res_low:]] = OpCompositeConstruct %[[#v3int]] %[[#l0]] %[[#l1]] %[[#l2]]
109+
%2 = shufflevector <6 x i32> %1, <6 x i32> poison, <3 x i32> <i32 0, i32 2, i32 4>
110+
111+
; CHECK: %[[#h0:]] = OpCompositeExtract %[[#int]] %[[#v4i0]] 1
112+
; CHECK: %[[#h1:]] = OpCompositeExtract %[[#int]] %[[#v4i0]] 3
113+
; CHECK: %[[#h2:]] = OpCompositeExtract %[[#int]] %[[#v4i1]] 1
114+
; CHECK: %[[#res_high:]] = OpCompositeConstruct %[[#v3int]] %[[#h0]] %[[#h1]] %[[#h2]]
115+
%3 = shufflevector <6 x i32> %1, <6 x i32> poison, <3 x i32> <i32 1, i32 3, i32 5>
116+
117+
; CHECK: OpStore %[[#Lows3]] %[[#res_low]]
118+
store <3 x i32> %2, ptr addrspace(10) @Lows3, align 16
119+
120+
; CHECK: OpStore %[[#Highs3]] %[[#res_high]]
121+
store <3 x i32> %3, ptr addrspace(10) @Highs3, align 16
122+
ret void
123+
}
124+
125+
define void @main() local_unnamed_addr #0 {
126+
entry:
127+
call void @test_split()
128+
call void @test_recombine()
129+
call void @test_bitcast_expand()
130+
ret void
131+
}
132+
133+
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }

0 commit comments

Comments
 (0)