[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / fneg-fabs-as-int.ll
blob8b245bdd792993b1548c8dd0f1d2e752a8af5242
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -S -passes=instcombine %s | FileCheck %s
4 define i32 @fneg_fabs_as_int_f32_noimplicitfloat(float %x) noimplicitfloat {
5 ; CHECK-LABEL: define i32 @fneg_fabs_as_int_f32_noimplicitfloat
6 ; CHECK-SAME: (float [[X:%.*]]) #[[ATTR0:[0-9]+]] {
7 ; CHECK-NEXT:    [[BC:%.*]] = bitcast float [[X]] to i32
8 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BC]], -2147483648
9 ; CHECK-NEXT:    ret i32 [[OR]]
11   %bc = bitcast float %x to i32
12   %or = or i32 %bc, -2147483648
13   ret i32 %or
16 define <2 x i32> @fneg_fabs_as_int_v2f32_noimplicitfloat(<2 x float> %x) noimplicitfloat {
17 ; CHECK-LABEL: define <2 x i32> @fneg_fabs_as_int_v2f32_noimplicitfloat
18 ; CHECK-SAME: (<2 x float> [[X:%.*]]) #[[ATTR0]] {
19 ; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
20 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[BC]], splat (i32 -2147483648)
21 ; CHECK-NEXT:    ret <2 x i32> [[OR]]
23   %bc = bitcast <2 x float> %x to <2 x i32>
24   %or = or <2 x i32> %bc, <i32 -2147483648, i32 -2147483648>
25   ret <2 x i32> %or
28 define float @fneg_fabs_fabs_as_int_f32_and_or(float %val) {
29 ; CHECK-LABEL: define float @fneg_fabs_fabs_as_int_f32_and_or
30 ; CHECK-SAME: (float [[VAL:%.*]]) {
31 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]])
32 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg float [[TMP1]]
33 ; CHECK-NEXT:    ret float [[TMP2]]
35   %bitcast = bitcast float %val to i32
36   %and = and i32 %bitcast, 2147483647
37   %or = or i32 %and, -2147483648
38   %fneg.fabs = bitcast i32 %or to float
39   ret float %fneg.fabs
42 define float @fneg_fabs_as_int_f32_castback(float %val) {
43 ; CHECK-LABEL: define float @fneg_fabs_as_int_f32_castback
44 ; CHECK-SAME: (float [[VAL:%.*]]) {
45 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]])
46 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg float [[TMP1]]
47 ; CHECK-NEXT:    ret float [[TMP2]]
49   %bitcast = bitcast float %val to i32
50   %or = or i32 %bitcast, -2147483648
51   %fneg = bitcast i32 %or to float
52   ret float %fneg
55 define float @not_fneg_fabs_as_int_f32_castback_wrongconst(float %val) {
56 ; CHECK-LABEL: define float @not_fneg_fabs_as_int_f32_castback_wrongconst
57 ; CHECK-SAME: (float [[VAL:%.*]]) {
58 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
59 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BITCAST]], -2147483647
60 ; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[OR]] to float
61 ; CHECK-NEXT:    ret float [[FNEG]]
63   %bitcast = bitcast float %val to i32
64   %or = or i32 %bitcast, -2147483647
65   %fneg = bitcast i32 %or to float
66   ret float %fneg
69 define float @fneg_fabs_as_int_f32_castback_multi_use(float %val, ptr %ptr) {
70 ; CHECK-LABEL: define float @fneg_fabs_as_int_f32_castback_multi_use
71 ; CHECK-SAME: (float [[VAL:%.*]], ptr [[PTR:%.*]]) {
72 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]])
73 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg float [[TMP1]]
74 ; CHECK-NEXT:    store float [[TMP2]], ptr [[PTR]], align 4
75 ; CHECK-NEXT:    ret float [[TMP2]]
77   %bitcast = bitcast float %val to i32
78   %or = or i32 %bitcast, -2147483648
79   store i32 %or, ptr %ptr
80   %fneg = bitcast i32 %or to float
81   ret float %fneg
84 define i64 @fneg_fabs_as_int_f64(double %x) {
85 ; CHECK-LABEL: define i64 @fneg_fabs_as_int_f64
86 ; CHECK-SAME: (double [[X:%.*]]) {
87 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]])
88 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg double [[TMP1]]
89 ; CHECK-NEXT:    [[OR:%.*]] = bitcast double [[TMP2]] to i64
90 ; CHECK-NEXT:    ret i64 [[OR]]
92   %bc = bitcast double %x to i64
93   %or = or i64 %bc, -9223372036854775808
94   ret i64 %or
97 define <2 x i64> @fneg_fabs_as_int_v2f64(<2 x double> %x) {
98 ; CHECK-LABEL: define <2 x i64> @fneg_fabs_as_int_v2f64
99 ; CHECK-SAME: (<2 x double> [[X:%.*]]) {
100 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x double> @llvm.fabs.v2f64(<2 x double> [[X]])
101 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg <2 x double> [[TMP1]]
102 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <2 x double> [[TMP2]] to <2 x i64>
103 ; CHECK-NEXT:    ret <2 x i64> [[OR]]
105   %bc = bitcast <2 x double> %x to <2 x i64>
106   %or = or <2 x i64> %bc, <i64 -9223372036854775808, i64 -9223372036854775808>
107   ret <2 x i64> %or
110 define i64 @fneg_fabs_as_int_f64_swap(double %x) {
111 ; CHECK-LABEL: define i64 @fneg_fabs_as_int_f64_swap
112 ; CHECK-SAME: (double [[X:%.*]]) {
113 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]])
114 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg double [[TMP1]]
115 ; CHECK-NEXT:    [[OR:%.*]] = bitcast double [[TMP2]] to i64
116 ; CHECK-NEXT:    ret i64 [[OR]]
118   %bc = bitcast double %x to i64
119   %or = or i64 -9223372036854775808, %bc
120   ret i64 %or
123 define i32 @fneg_fabs_as_int_f32(float %x) {
124 ; CHECK-LABEL: define i32 @fneg_fabs_as_int_f32
125 ; CHECK-SAME: (float [[X:%.*]]) {
126 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
127 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg float [[TMP1]]
128 ; CHECK-NEXT:    [[OR:%.*]] = bitcast float [[TMP2]] to i32
129 ; CHECK-NEXT:    ret i32 [[OR]]
131   %bc = bitcast float %x to i32
132   %or = or i32 %bc, -2147483648
133   ret i32 %or
136 define <2 x i32> @fneg_fabs_as_int_v2f32(<2 x float> %x) {
137 ; CHECK-LABEL: define <2 x i32> @fneg_fabs_as_int_v2f32
138 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
139 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
140 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg <2 x float> [[TMP1]]
141 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <2 x float> [[TMP2]] to <2 x i32>
142 ; CHECK-NEXT:    ret <2 x i32> [[OR]]
144   %bc = bitcast <2 x float> %x to <2 x i32>
145   %or = or <2 x i32> %bc, <i32 -2147483648, i32 -2147483648>
146   ret <2 x i32> %or
149 define <2 x i32> @not_fneg_fabs_as_int_v2f32_nonsplat(<2 x float> %x) {
150 ; CHECK-LABEL: define <2 x i32> @not_fneg_fabs_as_int_v2f32_nonsplat
151 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
152 ; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
153 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483647>
154 ; CHECK-NEXT:    ret <2 x i32> [[OR]]
156   %bc = bitcast <2 x float> %x to <2 x i32>
157   %or = or <2 x i32> %bc, <i32 -2147483648, i32 -2147483647>
158   ret <2 x i32> %or
161 define <3 x i32> @fneg_fabs_as_int_v3f32_poison(<3 x float> %x) {
162 ; CHECK-LABEL: define <3 x i32> @fneg_fabs_as_int_v3f32_poison
163 ; CHECK-SAME: (<3 x float> [[X:%.*]]) {
164 ; CHECK-NEXT:    [[TMP1:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[X]])
165 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg <3 x float> [[TMP1]]
166 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <3 x float> [[TMP2]] to <3 x i32>
167 ; CHECK-NEXT:    ret <3 x i32> [[OR]]
169   %bc = bitcast <3 x float> %x to <3 x i32>
170   %or = or <3 x i32> %bc, <i32 -2147483648, i32 poison, i32 -2147483648>
171   ret <3 x i32> %or
174 ; Make sure that only a bitcast is transformed.
175 define i64 @fneg_fabs_as_int_f64_not_bitcast(double %x) {
176 ; CHECK-LABEL: define i64 @fneg_fabs_as_int_f64_not_bitcast
177 ; CHECK-SAME: (double [[X:%.*]]) {
178 ; CHECK-NEXT:    [[BC:%.*]] = fptoui double [[X]] to i64
179 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[BC]], -9223372036854775808
180 ; CHECK-NEXT:    ret i64 [[OR]]
182   %bc = fptoui double %x to i64
183   %or = or i64 %bc, -9223372036854775808
184   ret i64 %or
187 define float @not_fneg_fabs_as_int_f32_bitcast_from_v2f16(<2 x half> %val) {
188 ; CHECK-LABEL: define float @not_fneg_fabs_as_int_f32_bitcast_from_v2f16
189 ; CHECK-SAME: (<2 x half> [[VAL:%.*]]) {
190 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x half> [[VAL]] to i32
191 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BITCAST]], -2147483648
192 ; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[OR]] to float
193 ; CHECK-NEXT:    ret float [[FNEG]]
195   %bitcast = bitcast <2 x half> %val to i32
196   %or = or i32 %bitcast, -2147483648
197   %fneg = bitcast i32 %or to float
198   ret float %fneg
201 define float @not_fneg_fabs_as_int_f32_bitcast_from_v2i16(<2 x i16> %val) {
202 ; CHECK-LABEL: define float @not_fneg_fabs_as_int_f32_bitcast_from_v2i16
203 ; CHECK-SAME: (<2 x i16> [[VAL:%.*]]) {
204 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x i16> [[VAL]] to i32
205 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[BITCAST]], -2147483648
206 ; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[OR]] to float
207 ; CHECK-NEXT:    ret float [[FNEG]]
209   %bitcast = bitcast <2 x i16> %val to i32
210   %or = or i32 %bitcast, -2147483648
211   %fneg = bitcast i32 %or to float
212   ret float %fneg
215 define i128 @fneg_fabs_as_int_fp128_f64_mask(fp128 %x) {
216 ; CHECK-LABEL: define i128 @fneg_fabs_as_int_fp128_f64_mask
217 ; CHECK-SAME: (fp128 [[X:%.*]]) {
218 ; CHECK-NEXT:    [[BC:%.*]] = bitcast fp128 [[X]] to i128
219 ; CHECK-NEXT:    [[OR:%.*]] = or i128 [[BC]], -9223372036854775808
220 ; CHECK-NEXT:    ret i128 [[OR]]
222   %bc = bitcast fp128 %x to i128
223   %or = or i128 %bc, -9223372036854775808
224   ret i128 %or
227 define i128 @fneg_fabs_as_int_fp128_f128_mask(fp128 %x) {
228 ; CHECK-LABEL: define i128 @fneg_fabs_as_int_fp128_f128_mask
229 ; CHECK-SAME: (fp128 [[X:%.*]]) {
230 ; CHECK-NEXT:    [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X]])
231 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg fp128 [[TMP1]]
232 ; CHECK-NEXT:    [[OR:%.*]] = bitcast fp128 [[TMP2]] to i128
233 ; CHECK-NEXT:    ret i128 [[OR]]
235   %bc = bitcast fp128 %x to i128
236   %or = or i128 %bc, -170141183460469231731687303715884105728
237   ret i128 %or
240 define i16 @fneg_fabs_as_int_f16(half %x) {
241 ; CHECK-LABEL: define i16 @fneg_fabs_as_int_f16
242 ; CHECK-SAME: (half [[X:%.*]]) {
243 ; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X]])
244 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg half [[TMP1]]
245 ; CHECK-NEXT:    [[OR:%.*]] = bitcast half [[TMP2]] to i16
246 ; CHECK-NEXT:    ret i16 [[OR]]
248   %bc = bitcast half %x to i16
249   %or = or i16 %bc, -32768
250   ret i16 %or
253 define <2 x i16> @fneg_fabs_as_int_v2f16(<2 x half> %x) {
254 ; CHECK-LABEL: define <2 x i16> @fneg_fabs_as_int_v2f16
255 ; CHECK-SAME: (<2 x half> [[X:%.*]]) {
256 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X]])
257 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg <2 x half> [[TMP1]]
258 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <2 x half> [[TMP2]] to <2 x i16>
259 ; CHECK-NEXT:    ret <2 x i16> [[OR]]
261   %bc = bitcast <2 x half> %x to <2 x i16>
262   %or = or <2 x i16> %bc, <i16 -32768, i16 -32768>
263   ret <2 x i16> %or
266 define i16 @fneg_fabs_as_int_bf16(bfloat %x) {
267 ; CHECK-LABEL: define i16 @fneg_fabs_as_int_bf16
268 ; CHECK-SAME: (bfloat [[X:%.*]]) {
269 ; CHECK-NEXT:    [[TMP1:%.*]] = call bfloat @llvm.fabs.bf16(bfloat [[X]])
270 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg bfloat [[TMP1]]
271 ; CHECK-NEXT:    [[OR:%.*]] = bitcast bfloat [[TMP2]] to i16
272 ; CHECK-NEXT:    ret i16 [[OR]]
274   %bc = bitcast bfloat %x to i16
275   %or = or i16 %bc, -32768
276   ret i16 %or
279 define <2 x i16> @fneg_fabs_as_int_v2bf16(<2 x bfloat> %x) {
280 ; CHECK-LABEL: define <2 x i16> @fneg_fabs_as_int_v2bf16
281 ; CHECK-SAME: (<2 x bfloat> [[X:%.*]]) {
282 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x bfloat> @llvm.fabs.v2bf16(<2 x bfloat> [[X]])
283 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg <2 x bfloat> [[TMP1]]
284 ; CHECK-NEXT:    [[OR:%.*]] = bitcast <2 x bfloat> [[TMP2]] to <2 x i16>
285 ; CHECK-NEXT:    ret <2 x i16> [[OR]]
287   %bc = bitcast <2 x bfloat> %x to <2 x i16>
288   %or = or <2 x i16> %bc, <i16 -32768, i16 -32768>
289   ret <2 x i16> %or
292 define i80 @fneg_fabs_as_int_x86_fp80_f64_mask(x86_fp80 %x) {
293 ; CHECK-LABEL: define i80 @fneg_fabs_as_int_x86_fp80_f64_mask
294 ; CHECK-SAME: (x86_fp80 [[X:%.*]]) {
295 ; CHECK-NEXT:    [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[X]])
296 ; CHECK-NEXT:    [[TMP2:%.*]] = fneg x86_fp80 [[TMP1]]
297 ; CHECK-NEXT:    [[OR:%.*]] = bitcast x86_fp80 [[TMP2]] to i80
298 ; CHECK-NEXT:    ret i80 [[OR]]
300   %bc = bitcast x86_fp80 %x to i80
301   %or = or i80 %bc, -604462909807314587353088
302   ret i80 %or
305 define i128 @fneg_fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
306 ; CHECK-LABEL: define i128 @fneg_fabs_as_int_ppc_fp128_f64_mask
307 ; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
308 ; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
309 ; CHECK-NEXT:    [[OR:%.*]] = or i128 [[BC]], -9223372036854775808
310 ; CHECK-NEXT:    ret i128 [[OR]]
312   %bc = bitcast ppc_fp128 %x to i128
313   %or = or i128 %bc, -9223372036854775808
314   ret i128 %or
317 define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
318 ; CHECK-LABEL: define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask
319 ; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
320 ; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
321 ; CHECK-NEXT:    [[OR:%.*]] = or i128 [[BC]], -170141183460469231731687303715884105728
322 ; CHECK-NEXT:    ret i128 [[OR]]
324   %bc = bitcast ppc_fp128 %x to i128
325   %or = or i128 %bc, -170141183460469231731687303715884105728
326   ret i128 %or