1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes='function(scalarizer)' %s | FileCheck %s
5 declare <2 x float> @llvm.sqrt.v2f32(<2 x float>)
8 declare <2 x float> @llvm.minnum.v2f32(<2 x float>, <2 x float>)
9 declare <2 x float> @llvm.minimum.v2f32(<2 x float>, <2 x float>)
10 declare <2 x float> @llvm.maximum.v2f32(<2 x float>, <2 x float>)
13 declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>)
16 declare <2 x i32> @llvm.bswap.v2i32(<2 x i32>)
18 ; Unary int plus constant scalar operand
19 declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1)
21 ; Unary fp plus any scalar operand
22 declare <2 x float> @llvm.powi.v2f32.i32(<2 x float>, i32)
24 ; Binary int plus constant scalar operand
25 declare <2 x i32> @llvm.smul.fix.sat.v2i32(<2 x i32>, <2 x i32>, i32)
26 declare <2 x i32> @llvm.umul.fix.sat.v2i32(<2 x i32>, <2 x i32>, i32)
28 ; Unary fp operand, int return type
29 declare <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float>)
30 declare <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float>)
32 ; Unary fp operand, int return type
33 declare <2 x i32> @llvm.lrint.v2i32.v2f32(<2 x float>)
34 declare <2 x i32> @llvm.llrint.v2i32.v2f32(<2 x float>)
36 ; Bool return type, overloaded on fp operand type
37 declare <2 x i1> @llvm.is.fpclass(<2 x float>, i32)
40 define <2 x float> @scalarize_sqrt_v2f32(<2 x float> %x) #0 {
41 ; CHECK-LABEL: @scalarize_sqrt_v2f32(
42 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
43 ; CHECK-NEXT: [[SQRT_I0:%.*]] = call float @llvm.sqrt.f32(float [[X_I0]])
44 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
45 ; CHECK-NEXT: [[SQRT_I1:%.*]] = call float @llvm.sqrt.f32(float [[X_I1]])
46 ; CHECK-NEXT: [[SQRT_UPTO0:%.*]] = insertelement <2 x float> poison, float [[SQRT_I0]], i64 0
47 ; CHECK-NEXT: [[SQRT:%.*]] = insertelement <2 x float> [[SQRT_UPTO0]], float [[SQRT_I1]], i64 1
48 ; CHECK-NEXT: ret <2 x float> [[SQRT]]
50 %sqrt = call <2 x float> @llvm.sqrt.v2f32(<2 x float> %x)
54 define <2 x float> @scalarize_minnum_v2f32(<2 x float> %x, <2 x float> %y) #0 {
55 ; CHECK-LABEL: @scalarize_minnum_v2f32(
56 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
57 ; CHECK-NEXT: [[Y_I0:%.*]] = extractelement <2 x float> [[Y:%.*]], i64 0
58 ; CHECK-NEXT: [[MINNUM_I0:%.*]] = call float @llvm.minnum.f32(float [[X_I0]], float [[Y_I0]])
59 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
60 ; CHECK-NEXT: [[Y_I1:%.*]] = extractelement <2 x float> [[Y]], i64 1
61 ; CHECK-NEXT: [[MINNUM_I1:%.*]] = call float @llvm.minnum.f32(float [[X_I1]], float [[Y_I1]])
62 ; CHECK-NEXT: [[MINNUM_UPTO0:%.*]] = insertelement <2 x float> poison, float [[MINNUM_I0]], i64 0
63 ; CHECK-NEXT: [[MINNUM:%.*]] = insertelement <2 x float> [[MINNUM_UPTO0]], float [[MINNUM_I1]], i64 1
64 ; CHECK-NEXT: ret <2 x float> [[MINNUM]]
66 %minnum = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> %y)
67 ret <2 x float> %minnum
70 define <2 x float> @scalarize_minimum_v2f32(<2 x float> %x, <2 x float> %y) #0 {
71 ; CHECK-LABEL: @scalarize_minimum_v2f32(
72 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
73 ; CHECK-NEXT: [[Y_I0:%.*]] = extractelement <2 x float> [[Y:%.*]], i64 0
74 ; CHECK-NEXT: [[MINIMUM_I0:%.*]] = call float @llvm.minimum.f32(float [[X_I0]], float [[Y_I0]])
75 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
76 ; CHECK-NEXT: [[Y_I1:%.*]] = extractelement <2 x float> [[Y]], i64 1
77 ; CHECK-NEXT: [[MINIMUM_I1:%.*]] = call float @llvm.minimum.f32(float [[X_I1]], float [[Y_I1]])
78 ; CHECK-NEXT: [[MINIMUM_UPTO0:%.*]] = insertelement <2 x float> poison, float [[MINIMUM_I0]], i64 0
79 ; CHECK-NEXT: [[MINIMUM:%.*]] = insertelement <2 x float> [[MINIMUM_UPTO0]], float [[MINIMUM_I1]], i64 1
80 ; CHECK-NEXT: ret <2 x float> [[MINIMUM]]
82 %minimum = call <2 x float> @llvm.minimum.v2f32(<2 x float> %x, <2 x float> %y)
83 ret <2 x float> %minimum
86 define <2 x float> @scalarize_maximum_v2f32(<2 x float> %x, <2 x float> %y) #0 {
87 ; CHECK-LABEL: @scalarize_maximum_v2f32(
88 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
89 ; CHECK-NEXT: [[Y_I0:%.*]] = extractelement <2 x float> [[Y:%.*]], i64 0
90 ; CHECK-NEXT: [[MAXIMUM_I0:%.*]] = call float @llvm.maximum.f32(float [[X_I0]], float [[Y_I0]])
91 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
92 ; CHECK-NEXT: [[Y_I1:%.*]] = extractelement <2 x float> [[Y]], i64 1
93 ; CHECK-NEXT: [[MAXIMUM_I1:%.*]] = call float @llvm.maximum.f32(float [[X_I1]], float [[Y_I1]])
94 ; CHECK-NEXT: [[MAXIMUM_UPTO0:%.*]] = insertelement <2 x float> poison, float [[MAXIMUM_I0]], i64 0
95 ; CHECK-NEXT: [[MAXIMUM:%.*]] = insertelement <2 x float> [[MAXIMUM_UPTO0]], float [[MAXIMUM_I1]], i64 1
96 ; CHECK-NEXT: ret <2 x float> [[MAXIMUM]]
98 %maximum = call <2 x float> @llvm.maximum.v2f32(<2 x float> %x, <2 x float> %y)
99 ret <2 x float> %maximum
102 define <2 x float> @scalarize_fma_v2f32(<2 x float> %x, <2 x float> %y, <2 x float> %z) #0 {
103 ; CHECK-LABEL: @scalarize_fma_v2f32(
104 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
105 ; CHECK-NEXT: [[Y_I0:%.*]] = extractelement <2 x float> [[Y:%.*]], i64 0
106 ; CHECK-NEXT: [[Z_I0:%.*]] = extractelement <2 x float> [[Z:%.*]], i64 0
107 ; CHECK-NEXT: [[FMA_I0:%.*]] = call float @llvm.fma.f32(float [[X_I0]], float [[Y_I0]], float [[Z_I0]])
108 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
109 ; CHECK-NEXT: [[Y_I1:%.*]] = extractelement <2 x float> [[Y]], i64 1
110 ; CHECK-NEXT: [[Z_I1:%.*]] = extractelement <2 x float> [[Z]], i64 1
111 ; CHECK-NEXT: [[FMA_I1:%.*]] = call float @llvm.fma.f32(float [[X_I1]], float [[Y_I1]], float [[Z_I1]])
112 ; CHECK-NEXT: [[FMA_UPTO0:%.*]] = insertelement <2 x float> poison, float [[FMA_I0]], i64 0
113 ; CHECK-NEXT: [[FMA:%.*]] = insertelement <2 x float> [[FMA_UPTO0]], float [[FMA_I1]], i64 1
114 ; CHECK-NEXT: ret <2 x float> [[FMA]]
116 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %x, <2 x float> %y, <2 x float> %z)
120 define <2 x i32> @scalarize_bswap_v2i32(<2 x i32> %x) #0 {
121 ; CHECK-LABEL: @scalarize_bswap_v2i32(
122 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
123 ; CHECK-NEXT: [[BSWAP_I0:%.*]] = call i32 @llvm.bswap.i32(i32 [[X_I0]])
124 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x i32> [[X]], i64 1
125 ; CHECK-NEXT: [[BSWAP_I1:%.*]] = call i32 @llvm.bswap.i32(i32 [[X_I1]])
126 ; CHECK-NEXT: [[BSWAP_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[BSWAP_I0]], i64 0
127 ; CHECK-NEXT: [[BSWAP:%.*]] = insertelement <2 x i32> [[BSWAP_UPTO0]], i32 [[BSWAP_I1]], i64 1
128 ; CHECK-NEXT: ret <2 x i32> [[BSWAP]]
130 %bswap = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> %x)
134 define <2 x i32> @scalarize_ctlz_v2i32(<2 x i32> %x) #0 {
135 ; CHECK-LABEL: @scalarize_ctlz_v2i32(
136 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
137 ; CHECK-NEXT: [[CTLZ_I0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_I0]], i1 true)
138 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x i32> [[X]], i64 1
139 ; CHECK-NEXT: [[CTLZ_I1:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_I1]], i1 true)
140 ; CHECK-NEXT: [[CTLZ_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[CTLZ_I0]], i64 0
141 ; CHECK-NEXT: [[CTLZ:%.*]] = insertelement <2 x i32> [[CTLZ_UPTO0]], i32 [[CTLZ_I1]], i64 1
142 ; CHECK-NEXT: ret <2 x i32> [[CTLZ]]
144 %ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %x, i1 true)
148 define <2 x float> @scalarize_powi_v2f32(<2 x float> %x, i32 %y) #0 {
149 ; CHECK-LABEL: @scalarize_powi_v2f32(
150 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
151 ; CHECK-NEXT: [[POWI_I0:%.*]] = call float @llvm.powi.f32.i32(float [[X_I0]], i32 [[Y:%.*]])
152 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
153 ; CHECK-NEXT: [[POWI_I1:%.*]] = call float @llvm.powi.f32.i32(float [[X_I1]], i32 [[Y]])
154 ; CHECK-NEXT: [[POWI_UPTO0:%.*]] = insertelement <2 x float> poison, float [[POWI_I0]], i64 0
155 ; CHECK-NEXT: [[POWI:%.*]] = insertelement <2 x float> [[POWI_UPTO0]], float [[POWI_I1]], i64 1
156 ; CHECK-NEXT: ret <2 x float> [[POWI]]
158 %powi = call <2 x float> @llvm.powi.v2f32.i32(<2 x float> %x, i32 %y)
159 ret <2 x float> %powi
162 define <2 x i32> @scalarize_smul_fix_sat_v2i32(<2 x i32> %x) #0 {
163 ; CHECK-LABEL: @scalarize_smul_fix_sat_v2i32(
164 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
165 ; CHECK-NEXT: [[SMULFIXSAT_I0:%.*]] = call i32 @llvm.smul.fix.sat.i32(i32 [[X_I0]], i32 5, i32 31)
166 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x i32> [[X]], i64 1
167 ; CHECK-NEXT: [[SMULFIXSAT_I1:%.*]] = call i32 @llvm.smul.fix.sat.i32(i32 [[X_I1]], i32 19, i32 31)
168 ; CHECK-NEXT: [[SMULFIXSAT_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[SMULFIXSAT_I0]], i64 0
169 ; CHECK-NEXT: [[SMULFIXSAT:%.*]] = insertelement <2 x i32> [[SMULFIXSAT_UPTO0]], i32 [[SMULFIXSAT_I1]], i64 1
170 ; CHECK-NEXT: ret <2 x i32> [[SMULFIXSAT]]
172 %smulfixsat = call <2 x i32> @llvm.smul.fix.sat.v2i32(<2 x i32> %x, <2 x i32> <i32 5, i32 19>, i32 31)
173 ret <2 x i32> %smulfixsat
176 define <2 x i32> @scalarize_umul_fix_sat_v2i32(<2 x i32> %x) #0 {
177 ; CHECK-LABEL: @scalarize_umul_fix_sat_v2i32(
178 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
179 ; CHECK-NEXT: [[UMULFIXSAT_I0:%.*]] = call i32 @llvm.umul.fix.sat.i32(i32 [[X_I0]], i32 5, i32 31)
180 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x i32> [[X]], i64 1
181 ; CHECK-NEXT: [[UMULFIXSAT_I1:%.*]] = call i32 @llvm.umul.fix.sat.i32(i32 [[X_I1]], i32 19, i32 31)
182 ; CHECK-NEXT: [[UMULFIXSAT_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[UMULFIXSAT_I0]], i64 0
183 ; CHECK-NEXT: [[UMULFIXSAT:%.*]] = insertelement <2 x i32> [[UMULFIXSAT_UPTO0]], i32 [[UMULFIXSAT_I1]], i64 1
184 ; CHECK-NEXT: ret <2 x i32> [[UMULFIXSAT]]
186 %umulfixsat = call <2 x i32> @llvm.umul.fix.sat.v2i32(<2 x i32> %x, <2 x i32> <i32 5, i32 19>, i32 31)
187 ret <2 x i32> %umulfixsat
190 define <2 x i32> @scalarize_fptosi_sat(<2 x float> %x) #0 {
191 ; CHECK-LABEL: @scalarize_fptosi_sat(
192 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
193 ; CHECK-NEXT: [[SAT_I0:%.*]] = call i32 @llvm.fptosi.sat.i32.f32(float [[X_I0]])
194 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
195 ; CHECK-NEXT: [[SAT_I1:%.*]] = call i32 @llvm.fptosi.sat.i32.f32(float [[X_I1]])
196 ; CHECK-NEXT: [[SAT_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[SAT_I0]], i64 0
197 ; CHECK-NEXT: [[SAT:%.*]] = insertelement <2 x i32> [[SAT_UPTO0]], i32 [[SAT_I1]], i64 1
198 ; CHECK-NEXT: ret <2 x i32> [[SAT]]
200 %sat = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> %x)
204 define <2 x i32> @scalarize_fptoui_sat(<2 x float> %x) #0 {
205 ; CHECK-LABEL: @scalarize_fptoui_sat(
206 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
207 ; CHECK-NEXT: [[SAT_I0:%.*]] = call i32 @llvm.fptoui.sat.i32.f32(float [[X_I0]])
208 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
209 ; CHECK-NEXT: [[SAT_I1:%.*]] = call i32 @llvm.fptoui.sat.i32.f32(float [[X_I1]])
210 ; CHECK-NEXT: [[SAT_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[SAT_I0]], i64 0
211 ; CHECK-NEXT: [[SAT:%.*]] = insertelement <2 x i32> [[SAT_UPTO0]], i32 [[SAT_I1]], i64 1
212 ; CHECK-NEXT: ret <2 x i32> [[SAT]]
214 %sat = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> %x)
218 define <2 x i32> @scalarize_lrint(<2 x float> %x) #0 {
219 ; CHECK-LABEL: @scalarize_lrint(
220 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
221 ; CHECK-NEXT: [[RND_I0:%.*]] = call i32 @llvm.lrint.i32.f32(float [[X_I0]])
222 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
223 ; CHECK-NEXT: [[RND_I1:%.*]] = call i32 @llvm.lrint.i32.f32(float [[X_I1]])
224 ; CHECK-NEXT: [[RND_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[RND_I0]], i64 0
225 ; CHECK-NEXT: [[RND:%.*]] = insertelement <2 x i32> [[RND_UPTO0]], i32 [[RND_I1]], i64 1
226 ; CHECK-NEXT: ret <2 x i32> [[RND]]
228 %rnd = call <2 x i32> @llvm.lrint.v2i32.v2f32(<2 x float> %x)
232 define <2 x i32> @scalarize_llrint(<2 x float> %x) #0 {
233 ; CHECK-LABEL: @scalarize_llrint(
234 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
235 ; CHECK-NEXT: [[RND_I0:%.*]] = call i32 @llvm.llrint.i32.f32(float [[X_I0]])
236 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
237 ; CHECK-NEXT: [[RND_I1:%.*]] = call i32 @llvm.llrint.i32.f32(float [[X_I1]])
238 ; CHECK-NEXT: [[RND_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[RND_I0]], i64 0
239 ; CHECK-NEXT: [[RND:%.*]] = insertelement <2 x i32> [[RND_UPTO0]], i32 [[RND_I1]], i64 1
240 ; CHECK-NEXT: ret <2 x i32> [[RND]]
242 %rnd = call <2 x i32> @llvm.llrint.v2i32.v2f32(<2 x float> %x)
246 define <2 x i1> @scalarize_is_fpclass(<2 x float> %x) #0 {
247 ; CHECK-LABEL: @scalarize_is_fpclass(
248 ; CHECK-NEXT: [[X_I0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
249 ; CHECK-NEXT: [[ISFPCLASS_I0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X_I0]], i32 123)
250 ; CHECK-NEXT: [[X_I1:%.*]] = extractelement <2 x float> [[X]], i64 1
251 ; CHECK-NEXT: [[ISFPCLASS_I1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X_I1]], i32 123)
252 ; CHECK-NEXT: [[ISFPCLASS_UPTO0:%.*]] = insertelement <2 x i1> poison, i1 [[ISFPCLASS_I0]], i64 0
253 ; CHECK-NEXT: [[ISFPCLASS:%.*]] = insertelement <2 x i1> [[ISFPCLASS_UPTO0]], i1 [[ISFPCLASS_I1]], i64 1
254 ; CHECK-NEXT: ret <2 x i1> [[ISFPCLASS]]
256 %isfpclass = call <2 x i1> @llvm.is.fpclass(<2 x float> %x, i32 123)
257 ret <2 x i1> %isfpclass