xref: /llvm-project/llvm/test/Transforms/InstCombine/fabs-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 @fabs_as_int_f32_castback_noimplicitfloat(float %val) noimplicitfloat {
5; CHECK-LABEL: define float @fabs_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:    [[AND:%.*]] = and i32 [[BITCAST]], 2147483647
9; CHECK-NEXT:    [[FABS:%.*]] = bitcast i32 [[AND]] to float
10; CHECK-NEXT:    ret float [[FABS]]
11;
12  %bitcast = bitcast float %val to i32
13  %and = and i32 %bitcast, 2147483647
14  %fabs = bitcast i32 %and to float
15  ret float %fabs
16}
17
18define <2 x i32> @fabs_as_int_v2f32_noimplicitfloat(<2 x float> %x) noimplicitfloat {
19; CHECK-LABEL: define <2 x i32> @fabs_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:    [[AND:%.*]] = and <2 x i32> [[BC]], splat (i32 2147483647)
23; CHECK-NEXT:    ret <2 x i32> [[AND]]
24;
25  %bc = bitcast <2 x float> %x to <2 x i32>
26  %and = and <2 x i32> %bc, <i32 2147483647, i32 2147483647>
27  ret <2 x i32> %and
28}
29
30define float @fabs_as_int_f32_castback(float %val) {
31; CHECK-LABEL: define float @fabs_as_int_f32_castback
32; CHECK-SAME: (float [[VAL:%.*]]) {
33; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]])
34; CHECK-NEXT:    ret float [[TMP1]]
35;
36  %bitcast = bitcast float %val to i32
37  %and = and i32 %bitcast, 2147483647
38  %fabs = bitcast i32 %and to float
39  ret float %fabs
40}
41
42define float @not_fabs_as_int_f32_castback_wrongconst(float %val) {
43; CHECK-LABEL: define float @not_fabs_as_int_f32_castback_wrongconst
44; CHECK-SAME: (float [[VAL:%.*]]) {
45; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]])
46; CHECK-NEXT:    ret float [[TMP1]]
47;
48  %bitcast = bitcast float %val to i32
49  %and = and i32 %bitcast, 2147483647
50  %fabs = bitcast i32 %and to float
51  ret float %fabs
52}
53
54define float @fabs_as_int_f32_castback_multi_use(float %val, ptr %ptr) {
55; CHECK-LABEL: define float @fabs_as_int_f32_castback_multi_use
56; CHECK-SAME: (float [[VAL:%.*]], ptr [[PTR:%.*]]) {
57; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[VAL]])
58; CHECK-NEXT:    store float [[TMP1]], ptr [[PTR]], align 4
59; CHECK-NEXT:    ret float [[TMP1]]
60;
61  %bitcast = bitcast float %val to i32
62  %and = and i32 %bitcast, 2147483647
63  store i32 %and, ptr %ptr
64  %fabs = bitcast i32 %and to float
65  ret float %fabs
66}
67
68define i64 @fabs_as_int_f64(double %x) {
69; CHECK-LABEL: define i64 @fabs_as_int_f64
70; CHECK-SAME: (double [[X:%.*]]) {
71; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]])
72; CHECK-NEXT:    [[AND:%.*]] = bitcast double [[TMP1]] to i64
73; CHECK-NEXT:    ret i64 [[AND]]
74;
75  %bc = bitcast double %x to i64
76  %and = and i64 %bc, 9223372036854775807
77  ret i64 %and
78}
79
80define <2 x i64> @fabs_as_int_v2f64(<2 x double> %x) {
81; CHECK-LABEL: define <2 x i64> @fabs_as_int_v2f64
82; CHECK-SAME: (<2 x double> [[X:%.*]]) {
83; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x double> @llvm.fabs.v2f64(<2 x double> [[X]])
84; CHECK-NEXT:    [[AND:%.*]] = bitcast <2 x double> [[TMP1]] to <2 x i64>
85; CHECK-NEXT:    ret <2 x i64> [[AND]]
86;
87  %bc = bitcast <2 x double> %x to <2 x i64>
88  %and = and <2 x i64> %bc, <i64 9223372036854775807, i64 9223372036854775807>
89  ret <2 x i64> %and
90}
91
92define i64 @fabs_as_int_f64_swap(double %x) {
93; CHECK-LABEL: define i64 @fabs_as_int_f64_swap
94; CHECK-SAME: (double [[X:%.*]]) {
95; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[X]])
96; CHECK-NEXT:    [[AND:%.*]] = bitcast double [[TMP1]] to i64
97; CHECK-NEXT:    ret i64 [[AND]]
98;
99  %bc = bitcast double %x to i64
100  %and = and i64 9223372036854775807, %bc
101  ret i64 %and
102}
103
104define i32 @fabs_as_int_f32(float %x) {
105; CHECK-LABEL: define i32 @fabs_as_int_f32
106; CHECK-SAME: (float [[X:%.*]]) {
107; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
108; CHECK-NEXT:    [[AND:%.*]] = bitcast float [[TMP1]] to i32
109; CHECK-NEXT:    ret i32 [[AND]]
110;
111  %bc = bitcast float %x to i32
112  %and = and i32 %bc, 2147483647
113  ret i32 %and
114}
115
116define <2 x i32> @fabs_as_int_v2f32(<2 x float> %x) {
117; CHECK-LABEL: define <2 x i32> @fabs_as_int_v2f32
118; CHECK-SAME: (<2 x float> [[X:%.*]]) {
119; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])
120; CHECK-NEXT:    [[AND:%.*]] = bitcast <2 x float> [[TMP1]] to <2 x i32>
121; CHECK-NEXT:    ret <2 x i32> [[AND]]
122;
123  %bc = bitcast <2 x float> %x to <2 x i32>
124  %and = and <2 x i32> %bc, <i32 2147483647, i32 2147483647>
125  ret <2 x i32> %and
126}
127
128define <2 x i32> @not_fabs_as_int_v2f32_nonsplat(<2 x float> %x) {
129; CHECK-LABEL: define <2 x i32> @not_fabs_as_int_v2f32_nonsplat
130; CHECK-SAME: (<2 x float> [[X:%.*]]) {
131; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x float> [[X]] to <2 x i32>
132; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[BC]], <i32 2147483647, i32 2147483646>
133; CHECK-NEXT:    ret <2 x i32> [[AND]]
134;
135  %bc = bitcast <2 x float> %x to <2 x i32>
136  %and = and <2 x i32> %bc, <i32 2147483647, i32 2147483646>
137  ret <2 x i32> %and
138}
139
140define <3 x i32> @fabs_as_int_v3f32_poison(<3 x float> %x) {
141; CHECK-LABEL: define <3 x i32> @fabs_as_int_v3f32_poison
142; CHECK-SAME: (<3 x float> [[X:%.*]]) {
143; CHECK-NEXT:    [[TMP1:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[X]])
144; CHECK-NEXT:    [[AND:%.*]] = bitcast <3 x float> [[TMP1]] to <3 x i32>
145; CHECK-NEXT:    ret <3 x i32> [[AND]]
146;
147  %bc = bitcast <3 x float> %x to <3 x i32>
148  %and = and <3 x i32> %bc, <i32 2147483647, i32 poison, i32 2147483647>
149  ret <3 x i32> %and
150}
151
152; Make sure that only a bitcast is transformed.
153define i64 @fabs_as_int_f64_not_bitcast(double %x) {
154; CHECK-LABEL: define i64 @fabs_as_int_f64_not_bitcast
155; CHECK-SAME: (double [[X:%.*]]) {
156; CHECK-NEXT:    [[BC:%.*]] = fptoui double [[X]] to i64
157; CHECK-NEXT:    [[AND:%.*]] = and i64 [[BC]], 9223372036854775807
158; CHECK-NEXT:    ret i64 [[AND]]
159;
160  %bc = fptoui double %x to i64
161  %and = and i64 %bc, 9223372036854775807
162  ret i64 %and
163}
164
165define float @not_fabs_as_int_f32_bitcast_from_v2f16(<2 x half> %val) {
166; CHECK-LABEL: define float @not_fabs_as_int_f32_bitcast_from_v2f16
167; CHECK-SAME: (<2 x half> [[VAL:%.*]]) {
168; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x half> [[VAL]] to i32
169; CHECK-NEXT:    [[AND:%.*]] = and i32 [[BITCAST]], 2147483647
170; CHECK-NEXT:    [[FABS:%.*]] = bitcast i32 [[AND]] to float
171; CHECK-NEXT:    ret float [[FABS]]
172;
173  %bitcast = bitcast <2 x half> %val to i32
174  %and = and i32 %bitcast, 2147483647
175  %fabs = bitcast i32 %and to float
176  ret float %fabs
177}
178
179define float @not_fabs_as_int_f32_bitcast_from_v2i16(<2 x i16> %val) {
180; CHECK-LABEL: define float @not_fabs_as_int_f32_bitcast_from_v2i16
181; CHECK-SAME: (<2 x i16> [[VAL:%.*]]) {
182; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast <2 x i16> [[VAL]] to i32
183; CHECK-NEXT:    [[AND:%.*]] = and i32 [[BITCAST]], 2147483647
184; CHECK-NEXT:    [[FABS:%.*]] = bitcast i32 [[AND]] to float
185; CHECK-NEXT:    ret float [[FABS]]
186;
187  %bitcast = bitcast <2 x i16> %val to i32
188  %and = and i32 %bitcast, 2147483647
189  %fabs = bitcast i32 %and to float
190  ret float %fabs
191}
192
193define i128 @fabs_as_int_fp128_f64_mask(fp128 %x) {
194; CHECK-LABEL: define i128 @fabs_as_int_fp128_f64_mask
195; CHECK-SAME: (fp128 [[X:%.*]]) {
196; CHECK-NEXT:    [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X]])
197; CHECK-NEXT:    [[AND:%.*]] = bitcast fp128 [[TMP1]] to i128
198; CHECK-NEXT:    ret i128 [[AND]]
199;
200  %bc = bitcast fp128 %x to i128
201  %and = and i128 %bc, 170141183460469231731687303715884105727
202  ret i128 %and
203}
204
205define i128 @fabs_as_int_fp128_f128_mask(fp128 %x) {
206; CHECK-LABEL: define i128 @fabs_as_int_fp128_f128_mask
207; CHECK-SAME: (fp128 [[X:%.*]]) {
208; CHECK-NEXT:    [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X]])
209; CHECK-NEXT:    [[AND:%.*]] = bitcast fp128 [[TMP1]] to i128
210; CHECK-NEXT:    ret i128 [[AND]]
211;
212  %bc = bitcast fp128 %x to i128
213  %and = and i128 %bc, 170141183460469231731687303715884105727
214  ret i128 %and
215}
216
217define i16 @fabs_as_int_f16(half %x) {
218; CHECK-LABEL: define i16 @fabs_as_int_f16
219; CHECK-SAME: (half [[X:%.*]]) {
220; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X]])
221; CHECK-NEXT:    [[AND:%.*]] = bitcast half [[TMP1]] to i16
222; CHECK-NEXT:    ret i16 [[AND]]
223;
224  %bc = bitcast half %x to i16
225  %and = and i16 %bc, 32767
226  ret i16 %and
227}
228
229define <2 x i16> @fabs_as_int_v2f16(<2 x half> %x) {
230; CHECK-LABEL: define <2 x i16> @fabs_as_int_v2f16
231; CHECK-SAME: (<2 x half> [[X:%.*]]) {
232; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X]])
233; CHECK-NEXT:    [[AND:%.*]] = bitcast <2 x half> [[TMP1]] to <2 x i16>
234; CHECK-NEXT:    ret <2 x i16> [[AND]]
235;
236  %bc = bitcast <2 x half> %x to <2 x i16>
237  %and = and <2 x i16> %bc, <i16 32767, i16 32767>
238  ret <2 x i16> %and
239}
240
241define i16 @fabs_as_int_bf16(bfloat %x) {
242; CHECK-LABEL: define i16 @fabs_as_int_bf16
243; CHECK-SAME: (bfloat [[X:%.*]]) {
244; CHECK-NEXT:    [[TMP1:%.*]] = call bfloat @llvm.fabs.bf16(bfloat [[X]])
245; CHECK-NEXT:    [[AND:%.*]] = bitcast bfloat [[TMP1]] to i16
246; CHECK-NEXT:    ret i16 [[AND]]
247;
248  %bc = bitcast bfloat %x to i16
249  %and = and i16 %bc, 32767
250  ret i16 %and
251}
252
253define <2 x i16> @fabs_as_int_v2bf16(<2 x bfloat> %x) {
254; CHECK-LABEL: define <2 x i16> @fabs_as_int_v2bf16
255; CHECK-SAME: (<2 x bfloat> [[X:%.*]]) {
256; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x bfloat> @llvm.fabs.v2bf16(<2 x bfloat> [[X]])
257; CHECK-NEXT:    [[AND:%.*]] = bitcast <2 x bfloat> [[TMP1]] to <2 x i16>
258; CHECK-NEXT:    ret <2 x i16> [[AND]]
259;
260  %bc = bitcast <2 x bfloat> %x to <2 x i16>
261  %and = and <2 x i16> %bc, <i16 32767, i16 32767>
262  ret <2 x i16> %and
263}
264
265define i80 @fabs_as_int_x86_fp80_f64_mask(x86_fp80 %x) {
266; CHECK-LABEL: define i80 @fabs_as_int_x86_fp80_f64_mask
267; CHECK-SAME: (x86_fp80 [[X:%.*]]) {
268; CHECK-NEXT:    [[BC:%.*]] = bitcast x86_fp80 [[X]] to i80
269; CHECK-NEXT:    [[AND:%.*]] = and i80 [[BC]], 9223372036854775807
270; CHECK-NEXT:    ret i80 [[AND]]
271;
272  %bc = bitcast x86_fp80 %x to i80
273  %and = and i80 %bc, 9223372036854775807
274  ret i80 %and
275}
276
277define i128 @fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
278; CHECK-LABEL: define i128 @fabs_as_int_ppc_fp128_f64_mask
279; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
280; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
281; CHECK-NEXT:    [[AND:%.*]] = and i128 [[BC]], 9223372036854775807
282; CHECK-NEXT:    ret i128 [[AND]]
283;
284  %bc = bitcast ppc_fp128 %x to i128
285  %and = and i128 %bc, 9223372036854775807
286  ret i128 %and
287}
288
289define i128 @fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
290; CHECK-LABEL: define i128 @fabs_as_int_ppc_fp128_f128_mask
291; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
292; CHECK-NEXT:    [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
293; CHECK-NEXT:    [[AND:%.*]] = and i128 [[BC]], 170141183460469231731687303715884105727
294; CHECK-NEXT:    ret i128 [[AND]]
295;
296  %bc = bitcast ppc_fp128 %x to i128
297  %and = and i128 %bc, 170141183460469231731687303715884105727
298  ret i128 %and
299}
300