xref: /llvm-project/llvm/test/Transforms/InstCombine/add-sitofp.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define double @x(i32 %a, i32 %b) {
5; CHECK-LABEL: @x(
6; CHECK-NEXT:    [[M:%.*]] = lshr i32 [[A:%.*]], 24
7; CHECK-NEXT:    [[N:%.*]] = and i32 [[M]], [[B:%.*]]
8; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i32 [[N]], 1
9; CHECK-NEXT:    [[P:%.*]] = uitofp nneg i32 [[TMP1]] to double
10; CHECK-NEXT:    ret double [[P]]
11;
12  %m = lshr i32 %a, 24
13  %n = and i32 %m, %b
14  %o = sitofp i32 %n to double
15  %p = fadd double %o, 1.0
16  ret double %p
17}
18
19define double @test(i32 %a) {
20; CHECK-LABEL: @test(
21; CHECK-NEXT:    [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
22; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], 1
23; CHECK-NEXT:    [[RES:%.*]] = uitofp nneg i32 [[TMP1]] to double
24; CHECK-NEXT:    ret double [[RES]]
25;
26  ; Drop two highest bits to guarantee that %a + 1 doesn't overflow
27  %a_and = and i32 %a, 1073741823
28  %a_and_fp = sitofp i32 %a_and to double
29  %res = fadd double %a_and_fp, 1.0
30  ret double %res
31}
32
33define float @test_neg(i32 %a) {
34; CHECK-LABEL: @test_neg(
35; CHECK-NEXT:    [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
36; CHECK-NEXT:    [[A_AND_FP:%.*]] = uitofp nneg i32 [[A_AND]] to float
37; CHECK-NEXT:    [[RES:%.*]] = fadd float [[A_AND_FP]], 1.000000e+00
38; CHECK-NEXT:    ret float [[RES]]
39;
40  ; Drop two highest bits to guarantee that %a + 1 doesn't overflow
41  %a_and = and i32 %a, 1073741823
42  %a_and_fp = sitofp i32 %a_and to float
43  %res = fadd float %a_and_fp, 1.0
44  ret float %res
45}
46
47define double @test_2(i32 %a, i32 %b) {
48; CHECK-LABEL: @test_2(
49; CHECK-NEXT:    [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
50; CHECK-NEXT:    [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
51; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], [[B_AND]]
52; CHECK-NEXT:    [[RES:%.*]] = uitofp nneg i32 [[TMP1]] to double
53; CHECK-NEXT:    ret double [[RES]]
54;
55  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
56  %a_and = and i32 %a, 1073741823
57  %b_and = and i32 %b, 1073741823
58
59  %a_and_fp = sitofp i32 %a_and to double
60  %b_and_fp = sitofp i32 %b_and to double
61
62  %res = fadd double %a_and_fp, %b_and_fp
63  ret double %res
64}
65
66define float @test_2_neg(i32 %a, i32 %b) {
67; CHECK-LABEL: @test_2_neg(
68; CHECK-NEXT:    [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
69; CHECK-NEXT:    [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
70; CHECK-NEXT:    [[A_AND_FP:%.*]] = uitofp nneg i32 [[A_AND]] to float
71; CHECK-NEXT:    [[B_AND_FP:%.*]] = uitofp nneg i32 [[B_AND]] to float
72; CHECK-NEXT:    [[RES:%.*]] = fadd float [[A_AND_FP]], [[B_AND_FP]]
73; CHECK-NEXT:    ret float [[RES]]
74;
75  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
76  %a_and = and i32 %a, 1073741823
77  %b_and = and i32 %b, 1073741823
78
79  %a_and_fp = sitofp i32 %a_and to float
80  %b_and_fp = sitofp i32 %b_and to float
81
82  %res = fadd float %a_and_fp, %b_and_fp
83  ret float %res
84}
85
86; can be represented in float.
87define float @test_3(i32 %a, i32 %b) {
88; CHECK-LABEL: @test_3(
89; CHECK-NEXT:    [[M:%.*]] = lshr i32 [[A:%.*]], 24
90; CHECK-NEXT:    [[N:%.*]] = and i32 [[M]], [[B:%.*]]
91; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i32 [[N]], 1
92; CHECK-NEXT:    [[P:%.*]] = uitofp nneg i32 [[TMP1]] to float
93; CHECK-NEXT:    ret float [[P]]
94;
95  %m = lshr i32 %a, 24
96  %n = and i32 %m, %b
97  %o = sitofp i32 %n to float
98  %p = fadd float %o, 1.0
99  ret float %p
100}
101
102define <4 x double> @test_4(<4 x i32> %a, <4 x i32> %b) {
103; CHECK-LABEL: @test_4(
104; CHECK-NEXT:    [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], splat (i32 1073741823)
105; CHECK-NEXT:    [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], splat (i32 1073741823)
106; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw <4 x i32> [[A_AND]], [[B_AND]]
107; CHECK-NEXT:    [[RES:%.*]] = uitofp nneg <4 x i32> [[TMP1]] to <4 x double>
108; CHECK-NEXT:    ret <4 x double> [[RES]]
109;
110  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
111  %a_and = and <4 x i32> %a, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
112  %b_and = and <4 x i32> %b, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
113
114  %a_and_fp = sitofp <4 x i32> %a_and to <4 x double>
115  %b_and_fp = sitofp <4 x i32> %b_and to <4 x double>
116
117  %res = fadd <4 x double> %a_and_fp, %b_and_fp
118  ret <4 x double> %res
119}
120
121define <4 x float> @test_4_neg(<4 x i32> %a, <4 x i32> %b) {
122; CHECK-LABEL: @test_4_neg(
123; CHECK-NEXT:    [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], splat (i32 1073741823)
124; CHECK-NEXT:    [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], splat (i32 1073741823)
125; CHECK-NEXT:    [[A_AND_FP:%.*]] = uitofp nneg <4 x i32> [[A_AND]] to <4 x float>
126; CHECK-NEXT:    [[B_AND_FP:%.*]] = uitofp nneg <4 x i32> [[B_AND]] to <4 x float>
127; CHECK-NEXT:    [[RES:%.*]] = fadd <4 x float> [[A_AND_FP]], [[B_AND_FP]]
128; CHECK-NEXT:    ret <4 x float> [[RES]]
129;
130  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
131  %a_and = and <4 x i32> %a, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
132  %b_and = and <4 x i32> %b, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
133
134  %a_and_fp = sitofp <4 x i32> %a_and to <4 x float>
135  %b_and_fp = sitofp <4 x i32> %b_and to <4 x float>
136
137  %res = fadd <4 x float> %a_and_fp, %b_and_fp
138  ret <4 x float> %res
139}
140