xref: /llvm-project/llvm/test/Transforms/InstCombine/fneg-as-int.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
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
3
4define float @fneg_as_int_f32_castback_noimplicitfloat(float %val) noimplicitfloat {
5; CHECK-LABEL: define float @fneg_as_int_f32_castback_noimplicitfloat
6; CHECK-SAME: (float [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {
7; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
8; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648
9; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
10; CHECK-NEXT:    ret float [[FNEG]]
11;
12  %bitcast = bitcast float %val to i32
13  %xor = xor i32 %bitcast, -2147483648
14  %fneg = bitcast i32 %xor to float
15  ret float %fneg
16}
17
18define <2 x i32> @fneg_as_int_v2f32_noimplicitfloat(<2 x float> %x) noimplicitfloat {
19; CHECK-LABEL: define <2 x i32> @fneg_as_int_v2f32_noimplicitfloat
20; CHECK-SAME: (<2 x float> [[X:%.*]]) #[[ATTR0]] {
21; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
22; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[BC]], splat (i32 -2147483648)
23; CHECK-NEXT:    ret <2 x i32> [[XOR]]
24;
25  %bc = bitcast <2 x float> %x to <2 x i32>
26  %xor = xor <2 x i32> %bc, <i32 -2147483648, i32 -2147483648>
27  ret <2 x i32> %xor
28}
29
30define float @fneg_as_int_f32_castback(float %val) {
31; CHECK-LABEL: define float @fneg_as_int_f32_castback
32; CHECK-SAME: (float [[VAL:%.*]]) {
33; CHECK-NEXT:    [[TMP1:%.*]] = fneg float [[VAL]]
34; CHECK-NEXT:    ret float [[TMP1]]
35;
36  %bitcast = bitcast float %val to i32
37  %xor = xor i32 %bitcast, -2147483648
38  %fneg = bitcast i32 %xor to float
39  ret float %fneg
40}
41
42define float @not_fneg_as_int_f32_castback_wrongconst(float %val) {
43; CHECK-LABEL: define float @not_fneg_as_int_f32_castback_wrongconst
44; CHECK-SAME: (float [[VAL:%.*]]) {
45; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast float [[VAL]] to i32
46; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483647
47; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
48; CHECK-NEXT:    ret float [[FNEG]]
49;
50  %bitcast = bitcast float %val to i32
51  %xor = xor i32 %bitcast, -2147483647
52  %fneg = bitcast i32 %xor to float
53  ret float %fneg
54}
55
56define float @fneg_as_int_f32_castback_multi_use(float %val, ptr %ptr) {
57; CHECK-LABEL: define float @fneg_as_int_f32_castback_multi_use
58; CHECK-SAME: (float [[VAL:%.*]], ptr [[PTR:%.*]]) {
59; CHECK-NEXT:    [[TMP1:%.*]] = fneg float [[VAL]]
60; CHECK-NEXT:    store float [[TMP1]], ptr [[PTR]], align 4
61; CHECK-NEXT:    ret float [[TMP1]]
62;
63  %bitcast = bitcast float %val to i32
64  %xor = xor i32 %bitcast, -2147483648
65  store i32 %xor, ptr %ptr
66  %fneg = bitcast i32 %xor to float
67  ret float %fneg
68}
69
70define i64 @fneg_as_int_f64(double %x) {
71; CHECK-LABEL: define i64 @fneg_as_int_f64
72; CHECK-SAME: (double [[X:%.*]]) {
73; CHECK-NEXT:    [[TMP1:%.*]] = fneg double [[X]]
74; CHECK-NEXT:    [[XOR:%.*]] = bitcast double [[TMP1]] to i64
75; CHECK-NEXT:    ret i64 [[XOR]]
76;
77  %bc = bitcast double %x to i64
78  %xor = xor i64 %bc, -9223372036854775808
79  ret i64 %xor
80}
81
82define <2 x i64> @fneg_as_int_v2f64(<2 x double> %x) {
83; CHECK-LABEL: define <2 x i64> @fneg_as_int_v2f64
84; CHECK-SAME: (<2 x double> [[X:%.*]]) {
85; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x double> [[X]]
86; CHECK-NEXT:    [[XOR:%.*]] = bitcast <2 x double> [[TMP1]] to <2 x i64>
87; CHECK-NEXT:    ret <2 x i64> [[XOR]]
88;
89  %bc = bitcast <2 x double> %x to <2 x i64>
90  %xor = xor <2 x i64> %bc, <i64 -9223372036854775808, i64 -9223372036854775808>
91  ret <2 x i64> %xor
92}
93
94define i64 @fneg_as_int_f64_swap(double %x) {
95; CHECK-LABEL: define i64 @fneg_as_int_f64_swap
96; CHECK-SAME: (double [[X:%.*]]) {
97; CHECK-NEXT:    [[TMP1:%.*]] = fneg double [[X]]
98; CHECK-NEXT:    [[XOR:%.*]] = bitcast double [[TMP1]] to i64
99; CHECK-NEXT:    ret i64 [[XOR]]
100;
101  %bc = bitcast double %x to i64
102  %xor = xor i64 -9223372036854775808, %bc
103  ret i64 %xor
104}
105
106define i32 @fneg_as_int_f32(float %x) {
107; CHECK-LABEL: define i32 @fneg_as_int_f32
108; CHECK-SAME: (float [[X:%.*]]) {
109; CHECK-NEXT:    [[TMP1:%.*]] = fneg float [[X]]
110; CHECK-NEXT:    [[XOR:%.*]] = bitcast float [[TMP1]] to i32
111; CHECK-NEXT:    ret i32 [[XOR]]
112;
113  %bc = bitcast float %x to i32
114  %xor = xor i32 %bc, -2147483648
115  ret i32 %xor
116}
117
118define <2 x i32> @fneg_as_int_v2f32(<2 x float> %x) {
119; CHECK-LABEL: define <2 x i32> @fneg_as_int_v2f32
120; CHECK-SAME: (<2 x float> [[X:%.*]]) {
121; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x float> [[X]]
122; CHECK-NEXT:    [[XOR:%.*]] = bitcast <2 x float> [[TMP1]] to <2 x i32>
123; CHECK-NEXT:    ret <2 x i32> [[XOR]]
124;
125  %bc = bitcast <2 x float> %x to <2 x i32>
126  %xor = xor <2 x i32> %bc, <i32 -2147483648, i32 -2147483648>
127  ret <2 x i32> %xor
128}
129
130define <2 x i32> @not_fneg_as_int_v2f32_nonsplat(<2 x float> %x) {
131; CHECK-LABEL: define <2 x i32> @not_fneg_as_int_v2f32_nonsplat
132; CHECK-SAME: (<2 x float> [[X:%.*]]) {
133; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
134; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[BC]], <i32 -2147483648, i32 -2147483647>
135; CHECK-NEXT:    ret <2 x i32> [[XOR]]
136;
137  %bc = bitcast <2 x float> %x to <2 x i32>
138  %xor = xor <2 x i32> %bc, <i32 -2147483648, i32 -2147483647>
139  ret <2 x i32> %xor
140}
141
142define <3 x i32> @fneg_as_int_v3f32_poison(<3 x float> %x) {
143; CHECK-LABEL: define <3 x i32> @fneg_as_int_v3f32_poison
144; CHECK-SAME: (<3 x float> [[X:%.*]]) {
145; CHECK-NEXT:    [[TMP1:%.*]] = fneg <3 x float> [[X]]
146; CHECK-NEXT:    [[XOR:%.*]] = bitcast <3 x float> [[TMP1]] to <3 x i32>
147; CHECK-NEXT:    ret <3 x i32> [[XOR]]
148;
149  %bc = bitcast <3 x float> %x to <3 x i32>
150  %xor = xor <3 x i32> %bc, <i32 -2147483648, i32 poison, i32 -2147483648>
151  ret <3 x i32> %xor
152}
153
154; Make sure that only a bitcast is transformed.
155define i64 @fneg_as_int_f64_not_bitcast(double %x) {
156; CHECK-LABEL: define i64 @fneg_as_int_f64_not_bitcast
157; CHECK-SAME: (double [[X:%.*]]) {
158; CHECK-NEXT:    [[BC:%.*]] = fptoui double [[X]] to i64
159; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[BC]], -9223372036854775808
160; CHECK-NEXT:    ret i64 [[XOR]]
161;
162  %bc = fptoui double %x to i64
163  %xor = xor i64 %bc, -9223372036854775808
164  ret i64 %xor
165}
166
167define float @not_fneg_as_int_f32_bitcast_from_v2f16(<2 x half> %val) {
168; CHECK-LABEL: define float @not_fneg_as_int_f32_bitcast_from_v2f16
169; CHECK-SAME: (<2 x half> [[VAL:%.*]]) {
170; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x half> [[VAL]] to i32
171; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648
172; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
173; CHECK-NEXT:    ret float [[FNEG]]
174;
175  %bitcast = bitcast <2 x half> %val to i32
176  %xor = xor i32 %bitcast, -2147483648
177  %fneg = bitcast i32 %xor to float
178  ret float %fneg
179}
180
181define float @not_fneg_as_int_f32_bitcast_from_v2i16(<2 x i16> %val) {
182; CHECK-LABEL: define float @not_fneg_as_int_f32_bitcast_from_v2i16
183; CHECK-SAME: (<2 x i16> [[VAL:%.*]]) {
184; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x i16> [[VAL]] to i32
185; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[BITCAST]], -2147483648
186; CHECK-NEXT:    [[FNEG:%.*]] = bitcast i32 [[XOR]] to float
187; CHECK-NEXT:    ret float [[FNEG]]
188;
189  %bitcast = bitcast <2 x i16> %val to i32
190  %xor = xor i32 %bitcast, -2147483648
191  %fneg = bitcast i32 %xor to float
192  ret float %fneg
193}
194
195define i128 @fneg_as_int_fp128_f64_mask(fp128 %x) {
196; CHECK-LABEL: define i128 @fneg_as_int_fp128_f64_mask
197; CHECK-SAME: (fp128 [[X:%.*]]) {
198; CHECK-NEXT:    [[BC:%.*]] = bitcast fp128 [[X]] to i128
199; CHECK-NEXT:    [[XOR:%.*]] = xor i128 [[BC]], -9223372036854775808
200; CHECK-NEXT:    ret i128 [[XOR]]
201;
202  %bc = bitcast fp128 %x to i128
203  %xor = xor i128 %bc, -9223372036854775808
204  ret i128 %xor
205}
206
207define i128 @fneg_as_int_fp128_f128_mask(fp128 %x) {
208; CHECK-LABEL: define i128 @fneg_as_int_fp128_f128_mask
209; CHECK-SAME: (fp128 [[X:%.*]]) {
210; CHECK-NEXT:    [[TMP1:%.*]] = fneg fp128 [[X]]
211; CHECK-NEXT:    [[XOR:%.*]] = bitcast fp128 [[TMP1]] to i128
212; CHECK-NEXT:    ret i128 [[XOR]]
213;
214  %bc = bitcast fp128 %x to i128
215  %xor = xor i128 %bc, -170141183460469231731687303715884105728
216  ret i128 %xor
217}
218
219define i16 @fneg_as_int_f16(half %x) {
220; CHECK-LABEL: define i16 @fneg_as_int_f16
221; CHECK-SAME: (half [[X:%.*]]) {
222; CHECK-NEXT:    [[TMP1:%.*]] = fneg half [[X]]
223; CHECK-NEXT:    [[XOR:%.*]] = bitcast half [[TMP1]] to i16
224; CHECK-NEXT:    ret i16 [[XOR]]
225;
226  %bc = bitcast half %x to i16
227  %xor = xor i16 %bc, -32768
228  ret i16 %xor
229}
230
231define <2 x i16> @fneg_as_int_v2f16(<2 x half> %x) {
232; CHECK-LABEL: define <2 x i16> @fneg_as_int_v2f16
233; CHECK-SAME: (<2 x half> [[X:%.*]]) {
234; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x half> [[X]]
235; CHECK-NEXT:    [[XOR:%.*]] = bitcast <2 x half> [[TMP1]] to <2 x i16>
236; CHECK-NEXT:    ret <2 x i16> [[XOR]]
237;
238  %bc = bitcast <2 x half> %x to <2 x i16>
239  %xor = xor <2 x i16> %bc, <i16 -32768, i16 -32768>
240  ret <2 x i16> %xor
241}
242
243define i16 @fneg_as_int_bf16(bfloat %x) {
244; CHECK-LABEL: define i16 @fneg_as_int_bf16
245; CHECK-SAME: (bfloat [[X:%.*]]) {
246; CHECK-NEXT:    [[TMP1:%.*]] = fneg bfloat [[X]]
247; CHECK-NEXT:    [[XOR:%.*]] = bitcast bfloat [[TMP1]] to i16
248; CHECK-NEXT:    ret i16 [[XOR]]
249;
250  %bc = bitcast bfloat %x to i16
251  %xor = xor i16 %bc, -32768
252  ret i16 %xor
253}
254
255define <2 x i16> @fneg_as_int_v2bf16(<2 x bfloat> %x) {
256; CHECK-LABEL: define <2 x i16> @fneg_as_int_v2bf16
257; CHECK-SAME: (<2 x bfloat> [[X:%.*]]) {
258; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x bfloat> [[X]]
259; CHECK-NEXT:    [[XOR:%.*]] = bitcast <2 x bfloat> [[TMP1]] to <2 x i16>
260; CHECK-NEXT:    ret <2 x i16> [[XOR]]
261;
262  %bc = bitcast <2 x bfloat> %x to <2 x i16>
263  %xor = xor <2 x i16> %bc, <i16 -32768, i16 -32768>
264  ret <2 x i16> %xor
265}
266
267define i80 @fneg_as_int_x86_fp80_f64_mask(x86_fp80 %x) {
268; CHECK-LABEL: define i80 @fneg_as_int_x86_fp80_f64_mask
269; CHECK-SAME: (x86_fp80 [[X:%.*]]) {
270; CHECK-NEXT:    [[TMP1:%.*]] = fneg x86_fp80 [[X]]
271; CHECK-NEXT:    [[XOR:%.*]] = bitcast x86_fp80 [[TMP1]] to i80
272; CHECK-NEXT:    ret i80 [[XOR]]
273;
274  %bc = bitcast x86_fp80 %x to i80
275  %xor = xor i80 %bc, -604462909807314587353088
276  ret i80 %xor
277}
278
279define i128 @fneg_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
280; CHECK-LABEL: define i128 @fneg_as_int_ppc_fp128_f64_mask
281; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
282; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
283; CHECK-NEXT:    [[XOR:%.*]] = xor i128 [[BC]], -9223372036854775808
284; CHECK-NEXT:    ret i128 [[XOR]]
285;
286  %bc = bitcast ppc_fp128 %x to i128
287  %xor = xor i128 %bc, -9223372036854775808
288  ret i128 %xor
289}
290
291define i128 @fneg_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
292; CHECK-LABEL: define i128 @fneg_as_int_ppc_fp128_f128_mask
293; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
294; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
295; CHECK-NEXT:    [[XOR:%.*]] = xor i128 [[BC]], -170141183460469231731687303715884105728
296; CHECK-NEXT:    ret i128 [[XOR]]
297;
298  %bc = bitcast ppc_fp128 %x to i128
299  %xor = xor i128 %bc, -170141183460469231731687303715884105728
300  ret i128 %xor
301}
302