1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -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:    [[ADDCONV:%.*]] = add nuw nsw i32 [[N]], 1
9; CHECK-NEXT:    [[P:%.*]] = sitofp i32 [[ADDCONV]] 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:    [[ADDCONV:%.*]] = add nuw nsw i32 [[A_AND]], 1
23; CHECK-NEXT:    [[RES:%.*]] = sitofp i32 [[ADDCONV]] 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:%.*]] = sitofp 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:    [[ADDCONV:%.*]] = add nuw nsw i32 [[A_AND]], [[B_AND]]
52; CHECK-NEXT:    [[RES:%.*]] = sitofp i32 [[ADDCONV]] 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:%.*]] = sitofp i32 [[A_AND]] to float
71; CHECK-NEXT:    [[B_AND_FP:%.*]] = sitofp 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; This test demonstrates overly conservative legality check. The float addition
87; can be replaced with the integer addition because the result of the operation
88; can be represented in float, but we don't do that now.
89define float @test_3(i32 %a, i32 %b) {
90; CHECK-LABEL: @test_3(
91; CHECK-NEXT:    [[M:%.*]] = lshr i32 [[A:%.*]], 24
92; CHECK-NEXT:    [[N:%.*]] = and i32 [[M]], [[B:%.*]]
93; CHECK-NEXT:    [[O:%.*]] = sitofp i32 [[N]] to float
94; CHECK-NEXT:    [[P:%.*]] = fadd float [[O]], 1.000000e+00
95; CHECK-NEXT:    ret float [[P]]
96;
97  %m = lshr i32 %a, 24
98  %n = and i32 %m, %b
99  %o = sitofp i32 %n to float
100  %p = fadd float %o, 1.0
101  ret float %p
102}
103
104define <4 x double> @test_4(<4 x i32> %a, <4 x i32> %b) {
105; CHECK-LABEL: @test_4(
106; CHECK-NEXT:    [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
107; CHECK-NEXT:    [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
108; CHECK-NEXT:    [[ADDCONV:%.*]] = add nuw nsw <4 x i32> [[A_AND]], [[B_AND]]
109; CHECK-NEXT:    [[RES:%.*]] = sitofp <4 x i32> [[ADDCONV]] to <4 x double>
110; CHECK-NEXT:    ret <4 x double> [[RES]]
111;
112  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
113  %a_and = and <4 x i32> %a, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
114  %b_and = and <4 x i32> %b, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
115
116  %a_and_fp = sitofp <4 x i32> %a_and to <4 x double>
117  %b_and_fp = sitofp <4 x i32> %b_and to <4 x double>
118
119  %res = fadd <4 x double> %a_and_fp, %b_and_fp
120  ret <4 x double> %res
121}
122
123define <4 x float> @test_4_neg(<4 x i32> %a, <4 x i32> %b) {
124; CHECK-LABEL: @test_4_neg(
125; CHECK-NEXT:    [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
126; CHECK-NEXT:    [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
127; CHECK-NEXT:    [[A_AND_FP:%.*]] = sitofp <4 x i32> [[A_AND]] to <4 x float>
128; CHECK-NEXT:    [[B_AND_FP:%.*]] = sitofp <4 x i32> [[B_AND]] to <4 x float>
129; CHECK-NEXT:    [[RES:%.*]] = fadd <4 x float> [[A_AND_FP]], [[B_AND_FP]]
130; CHECK-NEXT:    ret <4 x float> [[RES]]
131;
132  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
133  %a_and = and <4 x i32> %a, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
134  %b_and = and <4 x i32> %b, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
135
136  %a_and_fp = sitofp <4 x i32> %a_and to <4 x float>
137  %b_and_fp = sitofp <4 x i32> %b_and to <4 x float>
138
139  %res = fadd <4 x float> %a_and_fp, %b_and_fp
140  ret <4 x float> %res
141}
142