xref: /llvm-project/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/firstbitlow.ll (revision 4f48abff0fb90ea0a05470755b799cdb1ff79d89)
1*4f48abffSAshley Coleman; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
2*4f48abffSAshley Coleman; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3*4f48abffSAshley Coleman
4*4f48abffSAshley Coleman; CHECK-DAG: [[glsl_450_ext:%.+]] = OpExtInstImport "GLSL.std.450"
5*4f48abffSAshley Coleman; CHECK-DAG: OpMemoryModel Logical GLSL450
6*4f48abffSAshley Coleman; CHECK-DAG: [[u32_t:%.+]] = OpTypeInt 32 0
7*4f48abffSAshley Coleman; CHECK-DAG: [[u32x2_t:%.+]] = OpTypeVector [[u32_t]] 2
8*4f48abffSAshley Coleman; CHECK-DAG: [[u32x3_t:%.+]] = OpTypeVector [[u32_t]] 3
9*4f48abffSAshley Coleman; CHECK-DAG: [[u32x4_t:%.+]] = OpTypeVector [[u32_t]] 4
10*4f48abffSAshley Coleman; CHECK-DAG: [[const_0:%.*]] = OpConstant [[u32_t]] 0
11*4f48abffSAshley Coleman; CHECK-DAG: [[const_0x2:%.*]] = OpConstantComposite [[u32x2_t]] [[const_0]] [[const_0]]
12*4f48abffSAshley Coleman; CHECK-DAG: [[const_1:%.*]] = OpConstant [[u32_t]] 1
13*4f48abffSAshley Coleman; CHECK-DAG: [[const_2:%.*]] = OpConstant [[u32_t]] 2
14*4f48abffSAshley Coleman; CHECK-DAG: [[const_32:%.*]] = OpConstant [[u32_t]] 32
15*4f48abffSAshley Coleman; CHECK-DAG: [[const_32x2:%.*]] = OpConstantComposite [[u32x2_t]] [[const_32]] [[const_32]]
16*4f48abffSAshley Coleman; CHECK-DAG: [[const_neg1:%.*]] = OpConstant [[u32_t]] 4294967295
17*4f48abffSAshley Coleman; CHECK-DAG: [[const_neg1x2:%.*]] = OpConstantComposite [[u32x2_t]] [[const_neg1]] [[const_neg1]]
18*4f48abffSAshley Coleman; CHECK-DAG: [[u16_t:%.+]] = OpTypeInt 16 0
19*4f48abffSAshley Coleman; CHECK-DAG: [[u16x2_t:%.+]] = OpTypeVector [[u16_t]] 2
20*4f48abffSAshley Coleman; CHECK-DAG: [[u16x3_t:%.+]] = OpTypeVector [[u16_t]] 3
21*4f48abffSAshley Coleman; CHECK-DAG: [[u16x4_t:%.+]] = OpTypeVector [[u16_t]] 4
22*4f48abffSAshley Coleman; CHECK-DAG: [[u64_t:%.+]] = OpTypeInt 64 0
23*4f48abffSAshley Coleman; CHECK-DAG: [[u64x2_t:%.+]] = OpTypeVector [[u64_t]] 2
24*4f48abffSAshley Coleman; CHECK-DAG: [[u64x3_t:%.+]] = OpTypeVector [[u64_t]] 3
25*4f48abffSAshley Coleman; CHECK-DAG: [[u64x4_t:%.+]] = OpTypeVector [[u64_t]] 4
26*4f48abffSAshley Coleman; CHECK-DAG: [[bool_t:%.+]] = OpTypeBool
27*4f48abffSAshley Coleman; CHECK-DAG: [[boolx2_t:%.+]] = OpTypeVector [[bool_t]] 2
28*4f48abffSAshley Coleman
29*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_i32
30*4f48abffSAshley Colemandefine noundef i32 @firstbitlow_i32(i32 noundef %a) {
31*4f48abffSAshley Colemanentry:
32*4f48abffSAshley Coleman; CHECK: [[a:%.+]] = OpFunctionParameter [[u32_t]]
33*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpExtInst [[u32_t]] [[glsl_450_ext]] FindILsb [[a]]
34*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
35*4f48abffSAshley Coleman  %elt.firstbitlow = call i32 @llvm.spv.firstbitlow.i32(i32 %a)
36*4f48abffSAshley Coleman  ret i32 %elt.firstbitlow
37*4f48abffSAshley Coleman}
38*4f48abffSAshley Coleman
39*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_v2xi32
40*4f48abffSAshley Colemandefine noundef <2 x i32> @firstbitlow_v2xi32(<2 x i32> noundef %a) {
41*4f48abffSAshley Colemanentry:
42*4f48abffSAshley Coleman; CHECK: [[a:%.+]] = OpFunctionParameter [[u32x2_t]]
43*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpExtInst [[u32x2_t]] [[glsl_450_ext]] FindILsb [[a]]
44*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
45*4f48abffSAshley Coleman  %elt.firstbitlow = call <2 x i32> @llvm.spv.firstbitlow.v2i32(<2 x i32> %a)
46*4f48abffSAshley Coleman  ret <2 x i32> %elt.firstbitlow
47*4f48abffSAshley Coleman}
48*4f48abffSAshley Coleman
49*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_v3xi32
50*4f48abffSAshley Colemandefine noundef <3 x i32> @firstbitlow_v3xi32(<3 x i32> noundef %a) {
51*4f48abffSAshley Colemanentry:
52*4f48abffSAshley Coleman; CHECK: [[a:%.+]] = OpFunctionParameter [[u32x3_t]]
53*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpExtInst [[u32x3_t]] [[glsl_450_ext]] FindILsb [[a]]
54*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
55*4f48abffSAshley Coleman  %elt.firstbitlow = call <3 x i32> @llvm.spv.firstbitlow.v3i32(<3 x i32> %a)
56*4f48abffSAshley Coleman  ret <3 x i32> %elt.firstbitlow
57*4f48abffSAshley Coleman}
58*4f48abffSAshley Coleman
59*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_v4xi32
60*4f48abffSAshley Colemandefine noundef <4 x i32> @firstbitlow_v4xi32(<4 x i32> noundef %a) {
61*4f48abffSAshley Colemanentry:
62*4f48abffSAshley Coleman; CHECK: [[a:%.+]] = OpFunctionParameter [[u32x4_t]]
63*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpExtInst [[u32x4_t]] [[glsl_450_ext]] FindILsb [[a]]
64*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
65*4f48abffSAshley Coleman  %elt.firstbitlow = call <4 x i32> @llvm.spv.firstbitlow.v4i32(<4 x i32> %a)
66*4f48abffSAshley Coleman  ret <4 x i32> %elt.firstbitlow
67*4f48abffSAshley Coleman}
68*4f48abffSAshley Coleman
69*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_i16
70*4f48abffSAshley Colemandefine noundef i32 @firstbitlow_i16(i16 noundef %a) {
71*4f48abffSAshley Colemanentry:
72*4f48abffSAshley Coleman; CHECK: [[a16:%.+]] = OpFunctionParameter [[u16_t]]
73*4f48abffSAshley Coleman; CHECK: [[a32:%.+]] = OpUConvert [[u32_t]] [[a16]]
74*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpExtInst [[u32_t]] [[glsl_450_ext]] FindILsb [[a32]]
75*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
76*4f48abffSAshley Coleman  %elt.firstbitlow = call i32 @llvm.spv.firstbitlow.i16(i16 %a)
77*4f48abffSAshley Coleman  ret i32 %elt.firstbitlow
78*4f48abffSAshley Coleman}
79*4f48abffSAshley Coleman
80*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_v2xi16
81*4f48abffSAshley Colemandefine noundef <2 x i32> @firstbitlow_v2xi16(<2 x i16> noundef %a) {
82*4f48abffSAshley Colemanentry:
83*4f48abffSAshley Coleman; CHECK: [[a16:%.+]] = OpFunctionParameter [[u16x2_t]]
84*4f48abffSAshley Coleman; CHECK: [[a32:%.+]] = OpUConvert [[u32x2_t]] [[a16]]
85*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpExtInst [[u32x2_t]] [[glsl_450_ext]] FindILsb [[a32]]
86*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
87*4f48abffSAshley Coleman  %elt.firstbitlow = call <2 x i32> @llvm.spv.firstbitlow.v2i16(<2 x i16> %a)
88*4f48abffSAshley Coleman  ret <2 x i32> %elt.firstbitlow
89*4f48abffSAshley Coleman}
90*4f48abffSAshley Coleman
91*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_v3xi16
92*4f48abffSAshley Colemandefine noundef <3 x i32> @firstbitlow_v3xi16(<3 x i16> noundef %a) {
93*4f48abffSAshley Colemanentry:
94*4f48abffSAshley Coleman; CHECK: [[a16:%.+]] = OpFunctionParameter [[u16x3_t]]
95*4f48abffSAshley Coleman; CHECK: [[a32:%.+]] = OpUConvert [[u32x3_t]] [[a16]]
96*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpExtInst [[u32x3_t]] [[glsl_450_ext]] FindILsb [[a32]]
97*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
98*4f48abffSAshley Coleman  %elt.firstbitlow = call <3 x i32> @llvm.spv.firstbitlow.v3i16(<3 x i16> %a)
99*4f48abffSAshley Coleman  ret <3 x i32> %elt.firstbitlow
100*4f48abffSAshley Coleman}
101*4f48abffSAshley Coleman
102*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_v4xi16
103*4f48abffSAshley Colemandefine noundef <4 x i32> @firstbitlow_v4xi16(<4 x i16> noundef %a) {
104*4f48abffSAshley Colemanentry:
105*4f48abffSAshley Coleman; CHECK: [[a16:%.+]] = OpFunctionParameter [[u16x4_t]]
106*4f48abffSAshley Coleman; CHECK: [[a32:%.+]] = OpUConvert [[u32x4_t]] [[a16]]
107*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpExtInst [[u32x4_t]] [[glsl_450_ext]] FindILsb [[a32]]
108*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
109*4f48abffSAshley Coleman  %elt.firstbitlow = call <4 x i32> @llvm.spv.firstbitlow.v4i16(<4 x i16> %a)
110*4f48abffSAshley Coleman  ret <4 x i32> %elt.firstbitlow
111*4f48abffSAshley Coleman}
112*4f48abffSAshley Coleman
113*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_i64
114*4f48abffSAshley Colemandefine noundef i32 @firstbitlow_i64(i64 noundef %a) {
115*4f48abffSAshley Colemanentry:
116*4f48abffSAshley Coleman; CHECK: [[a64:%.+]] = OpFunctionParameter [[u64_t]]
117*4f48abffSAshley Coleman; CHECK: [[a32x2:%.+]] = OpBitcast [[u32x2_t]] [[a64]]
118*4f48abffSAshley Coleman; CHECK: [[lsb_bits:%.+]] = OpExtInst [[u32x2_t]] [[glsl_450_ext]] FindILsb [[a32x2]]
119*4f48abffSAshley Coleman; CHECK: [[high_bits:%.+]] = OpVectorExtractDynamic [[u32_t]] [[lsb_bits]] [[const_0]]
120*4f48abffSAshley Coleman; CHECK: [[low_bits:%.+]] = OpVectorExtractDynamic [[u32_t]] [[lsb_bits]] [[const_1]]
121*4f48abffSAshley Coleman; CHECK: [[should_use_high:%.+]] = OpIEqual [[bool_t]] [[low_bits]] [[const_neg1]]
122*4f48abffSAshley Coleman; CHECK: [[ans_bits:%.+]] = OpSelect [[u32_t]] [[should_use_high]] [[high_bits]] [[low_bits]]
123*4f48abffSAshley Coleman; CHECK: [[ans_offset:%.+]] = OpSelect [[u32_t]] [[should_use_high]] [[const_32]] [[const_0]]
124*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpIAdd [[u32_t]] [[ans_offset]] [[ans_bits]]
125*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
126*4f48abffSAshley Coleman  %elt.firstbitlow = call i32 @llvm.spv.firstbitlow.i64(i64 %a)
127*4f48abffSAshley Coleman  ret i32 %elt.firstbitlow
128*4f48abffSAshley Coleman}
129*4f48abffSAshley Coleman
130*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_v2xi64
131*4f48abffSAshley Colemandefine noundef <2 x i32> @firstbitlow_v2xi64(<2 x i64> noundef %a) {
132*4f48abffSAshley Colemanentry:
133*4f48abffSAshley Coleman; CHECK: [[a64x2:%.+]] = OpFunctionParameter [[u64x2_t]]
134*4f48abffSAshley Coleman; CHECK: [[a32x4:%.+]] = OpBitcast [[u32x4_t]] [[a64x2]]
135*4f48abffSAshley Coleman; CHECK: [[lsb_bits:%.+]] = OpExtInst [[u32x4_t]] [[glsl_450_ext]] FindILsb [[a32x4]]
136*4f48abffSAshley Coleman; CHECK: [[high_bits:%.+]] = OpVectorShuffle [[u32x2_t]] [[lsb_bits]] [[lsb_bits]] 0 2
137*4f48abffSAshley Coleman; CHECK: [[low_bits:%.+]] = OpVectorShuffle [[u32x2_t]] [[lsb_bits]] [[lsb_bits]] 1 3
138*4f48abffSAshley Coleman; CHECK: [[should_use_high:%.+]] = OpIEqual [[boolx2_t]] [[low_bits]] [[const_neg1x2]]
139*4f48abffSAshley Coleman; CHECK: [[ans_bits:%.+]] = OpSelect [[u32x2_t]] [[should_use_high]] [[high_bits]] [[low_bits]]
140*4f48abffSAshley Coleman; CHECK: [[ans_offset:%.+]] = OpSelect [[u32x2_t]] [[should_use_high]] [[const_32x2]] [[const_0x2]]
141*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpIAdd [[u32x2_t]] [[ans_offset]] [[ans_bits]]
142*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
143*4f48abffSAshley Coleman  %elt.firstbitlow = call <2 x i32> @llvm.spv.firstbitlow.v2i64(<2 x i64> %a)
144*4f48abffSAshley Coleman  ret <2 x i32> %elt.firstbitlow
145*4f48abffSAshley Coleman}
146*4f48abffSAshley Coleman
147*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_v3xi64
148*4f48abffSAshley Colemandefine noundef <3 x i32> @firstbitlow_v3xi64(<3 x i64> noundef %a) {
149*4f48abffSAshley Colemanentry:
150*4f48abffSAshley Coleman; Preamble
151*4f48abffSAshley Coleman; CHECK: [[a:%.+]] = OpFunctionParameter [[u64x3_t]]
152*4f48abffSAshley Coleman
153*4f48abffSAshley Coleman; Extract first 2 components from %a
154*4f48abffSAshley Coleman; CHECK: [[pt1:%.+]] = OpVectorShuffle [[u64x2_t]] [[a]] [[a]] 0 1
155*4f48abffSAshley Coleman
156*4f48abffSAshley Coleman; Do firstbitlow on the first 2 components
157*4f48abffSAshley Coleman; CHECK: [[pt1_cast:%.+]] = OpBitcast [[u32x4_t]] [[pt1]]
158*4f48abffSAshley Coleman; CHECK: [[pt1_lsb_bits:%.+]] = OpExtInst [[u32x4_t]] [[glsl_450_ext]] FindILsb [[pt1_cast]]
159*4f48abffSAshley Coleman; CHECK: [[pt1_high_bits:%.+]] = OpVectorShuffle [[u32x2_t]] [[pt1_lsb_bits]] [[pt1_lsb_bits]] 0 2
160*4f48abffSAshley Coleman; CHECK: [[pt1_low_bits:%.+]] = OpVectorShuffle [[u32x2_t]] [[pt1_lsb_bits]] [[pt1_lsb_bits]] 1 3
161*4f48abffSAshley Coleman; CHECK: [[pt1_should_use_high:%.+]] = OpIEqual [[boolx2_t]] [[pt1_low_bits]] [[const_neg1x2]]
162*4f48abffSAshley Coleman; CHECK: [[pt1_ans_bits:%.+]] = OpSelect [[u32x2_t]] [[pt1_should_use_high]] [[pt1_high_bits]] [[pt1_low_bits]]
163*4f48abffSAshley Coleman; CHECK: [[pt1_ans_offset:%.+]] = OpSelect [[u32x2_t]] [[pt1_should_use_high]] [[const_32x2]] [[const_0x2]]
164*4f48abffSAshley Coleman; CHECK: [[pt1_res:%.+]] = OpIAdd [[u32x2_t]] [[pt1_ans_offset]] [[pt1_ans_bits]]
165*4f48abffSAshley Coleman
166*4f48abffSAshley Coleman; Extract the last component from %a
167*4f48abffSAshley Coleman; CHECK: [[pt2:%.+]] = OpVectorExtractDynamic [[u64_t]] [[a]] [[const_2]]
168*4f48abffSAshley Coleman
169*4f48abffSAshley Coleman; Do firstbitlow on the last component
170*4f48abffSAshley Coleman; CHECK: [[pt2_cast:%.+]] = OpBitcast [[u32x2_t]] [[pt2]]
171*4f48abffSAshley Coleman; CHECK: [[pt2_lsb_bits:%.+]] = OpExtInst [[u32x2_t]] [[glsl_450_ext]] FindILsb [[pt2_cast]]
172*4f48abffSAshley Coleman; CHECK: [[pt2_high_bits:%.+]] = OpVectorExtractDynamic [[u32_t]] [[pt2_lsb_bits]] [[const_0]]
173*4f48abffSAshley Coleman; CHECK: [[pt2_low_bits:%.+]] = OpVectorExtractDynamic [[u32_t]] [[pt2_lsb_bits]] [[const_1]]
174*4f48abffSAshley Coleman; CHECK: [[pt2_should_use_high:%.+]] = OpIEqual [[bool_t]] [[pt2_low_bits]] [[const_neg1]]
175*4f48abffSAshley Coleman; CHECK: [[pt2_ans_bits:%.+]] = OpSelect [[u32_t]] [[pt2_should_use_high]] [[pt2_high_bits]] [[pt2_low_bits]]
176*4f48abffSAshley Coleman; CHECK: [[pt2_ans_offset:%.+]] = OpSelect [[u32_t]] [[pt2_should_use_high]] [[const_32]] [[const_0]]
177*4f48abffSAshley Coleman; CHECK: [[pt2_res:%.+]] = OpIAdd [[u32_t]] [[pt2_ans_offset]] [[pt2_ans_bits]]
178*4f48abffSAshley Coleman
179*4f48abffSAshley Coleman; Merge the parts into the final i32x3 and return it
180*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpCompositeConstruct [[u32x3_t]] [[pt1_res]] [[pt2_res]]
181*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
182*4f48abffSAshley Coleman  %elt.firstbitlow = call <3 x i32> @llvm.spv.firstbitlow.v3i64(<3 x i64> %a)
183*4f48abffSAshley Coleman  ret <3 x i32> %elt.firstbitlow
184*4f48abffSAshley Coleman}
185*4f48abffSAshley Coleman
186*4f48abffSAshley Coleman; CHECK-LABEL: Begin function firstbitlow_v4xi64
187*4f48abffSAshley Colemandefine noundef <4 x i32> @firstbitlow_v4xi64(<4 x i64> noundef %a) {
188*4f48abffSAshley Colemanentry:
189*4f48abffSAshley Coleman; Preamble
190*4f48abffSAshley Coleman; CHECK: [[a:%.+]] = OpFunctionParameter [[u64x4_t]]
191*4f48abffSAshley Coleman
192*4f48abffSAshley Coleman; Extract first 2 components from %a
193*4f48abffSAshley Coleman; CHECK: [[pt1:%.+]] = OpVectorShuffle [[u64x2_t]] [[a]] [[a]] 0 1
194*4f48abffSAshley Coleman
195*4f48abffSAshley Coleman; Do firstbitlow on the first 2 components
196*4f48abffSAshley Coleman; CHECK: [[pt1_cast:%.+]] = OpBitcast [[u32x4_t]] [[pt1]]
197*4f48abffSAshley Coleman; CHECK: [[pt1_lsb_bits:%.+]] = OpExtInst [[u32x4_t]] [[glsl_450_ext]] FindILsb [[pt1_cast]]
198*4f48abffSAshley Coleman; CHECK: [[pt1_high_bits:%.+]] = OpVectorShuffle [[u32x2_t]] [[pt1_lsb_bits]] [[pt1_lsb_bits]] 0 2
199*4f48abffSAshley Coleman; CHECK: [[pt1_low_bits:%.+]] = OpVectorShuffle [[u32x2_t]] [[pt1_lsb_bits]] [[pt1_lsb_bits]] 1 3
200*4f48abffSAshley Coleman; CHECK: [[pt1_should_use_high:%.+]] = OpIEqual [[boolx2_t]] [[pt1_low_bits]] [[const_neg1x2]]
201*4f48abffSAshley Coleman; CHECK: [[pt1_ans_bits:%.+]] = OpSelect [[u32x2_t]] [[pt1_should_use_high]] [[pt1_high_bits]] [[pt1_low_bits]]
202*4f48abffSAshley Coleman; CHECK: [[pt1_ans_offset:%.+]] = OpSelect [[u32x2_t]] [[pt1_should_use_high]] [[const_32x2]] [[const_0x2]]
203*4f48abffSAshley Coleman; CHECK: [[pt1_res:%.+]] = OpIAdd [[u32x2_t]] [[pt1_ans_offset]] [[pt1_ans_bits]]
204*4f48abffSAshley Coleman
205*4f48abffSAshley Coleman; Extract last 2 components from %a
206*4f48abffSAshley Coleman; CHECK: [[pt2:%.+]] = OpVectorShuffle [[u64x2_t]] [[a]] [[a]] 2 3
207*4f48abffSAshley Coleman
208*4f48abffSAshley Coleman; Do firstbituhigh on the last 2 components
209*4f48abffSAshley Coleman; CHECK: [[pt2_cast:%.+]] = OpBitcast [[u32x4_t]] [[pt2]]
210*4f48abffSAshley Coleman; CHECK: [[pt2_lsb_bits:%.+]] = OpExtInst [[u32x4_t]] [[glsl_450_ext]] FindILsb [[pt2_cast]]
211*4f48abffSAshley Coleman; CHECK: [[pt2_high_bits:%.+]] = OpVectorShuffle [[u32x2_t]] [[pt2_lsb_bits]] [[pt2_lsb_bits]] 0 2
212*4f48abffSAshley Coleman; CHECK: [[pt2_low_bits:%.+]] = OpVectorShuffle [[u32x2_t]] [[pt2_lsb_bits]] [[pt2_lsb_bits]] 1 3
213*4f48abffSAshley Coleman; CHECK: [[pt2_should_use_high:%.+]] = OpIEqual [[boolx2_t]] [[pt2_low_bits]] [[const_neg1x2]]
214*4f48abffSAshley Coleman; CHECK: [[pt2_ans_bits:%.+]] = OpSelect [[u32x2_t]] [[pt2_should_use_high]] [[pt2_high_bits]] [[pt2_low_bits]]
215*4f48abffSAshley Coleman; CHECK: [[pt2_ans_offset:%.+]] = OpSelect [[u32x2_t]] [[pt2_should_use_high]] [[const_32x2]] [[const_0x2]]
216*4f48abffSAshley Coleman; CHECK: [[pt2_res:%.+]] = OpIAdd [[u32x2_t]] [[pt2_ans_offset]] [[pt2_ans_bits]]
217*4f48abffSAshley Coleman
218*4f48abffSAshley Coleman; Merge the parts into the final i32x4 and return it
219*4f48abffSAshley Coleman; CHECK: [[ret:%.+]] = OpCompositeConstruct [[u32x4_t]] [[pt1_res]] [[pt2_res]]
220*4f48abffSAshley Coleman; CHECK: OpReturnValue [[ret]]
221*4f48abffSAshley Coleman  %elt.firstbitlow = call <4 x i32> @llvm.spv.firstbitlow.v4i64(<4 x i64> %a)
222*4f48abffSAshley Coleman  ret <4 x i32> %elt.firstbitlow
223*4f48abffSAshley Coleman}
224*4f48abffSAshley Coleman
225*4f48abffSAshley Coleman;declare i16 @llvm.spv.firstbitlow.i16(i16)
226*4f48abffSAshley Coleman;declare i32 @llvm.spv.firstbitlow.i32(i32)
227*4f48abffSAshley Coleman;declare i64 @llvm.spv.firstbitlow.i64(i64)
228*4f48abffSAshley Coleman;declare i16 @llvm.spv.firstbitlow.v2i16(<2 x i16>)
229*4f48abffSAshley Coleman;declare i32 @llvm.spv.firstbitlow.v2i32(<2 x i32>)
230*4f48abffSAshley Coleman;declare i64 @llvm.spv.firstbitlow.v2i64(<2 x i64>)
231