xref: /aosp_15_r20/external/llvm/test/Transforms/Float2Int/basic.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -float2int -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -passes='float2int' -S | FileCheck %s
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker;
5*9880d681SAndroid Build Coastguard Worker; Positive tests
6*9880d681SAndroid Build Coastguard Worker;
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple1
9*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = zext i8 %a to i32
10*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = add i32 %1, 1
11*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = trunc i32 %2 to i16
12*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i16 %3
13*9880d681SAndroid Build Coastguard Workerdefine i16 @simple1(i8 %a) {
14*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i8 %a to float
15*9880d681SAndroid Build Coastguard Worker  %2 = fadd float %1, 1.0
16*9880d681SAndroid Build Coastguard Worker  %3 = fptoui float %2 to i16
17*9880d681SAndroid Build Coastguard Worker  ret i16 %3
18*9880d681SAndroid Build Coastguard Worker}
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple2
21*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = zext i8 %a to i32
22*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = sub i32 %1, 1
23*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = trunc i32 %2 to i8
24*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i8 %3
25*9880d681SAndroid Build Coastguard Workerdefine i8 @simple2(i8 %a) {
26*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i8 %a to float
27*9880d681SAndroid Build Coastguard Worker  %2 = fsub float %1, 1.0
28*9880d681SAndroid Build Coastguard Worker  %3 = fptoui float %2 to i8
29*9880d681SAndroid Build Coastguard Worker  ret i8 %3
30*9880d681SAndroid Build Coastguard Worker}
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple3
33*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = zext i8 %a to i32
34*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = sub i32 %1, 1
35*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i32 %2
36*9880d681SAndroid Build Coastguard Workerdefine i32 @simple3(i8 %a) {
37*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i8 %a to float
38*9880d681SAndroid Build Coastguard Worker  %2 = fsub float %1, 1.0
39*9880d681SAndroid Build Coastguard Worker  %3 = fptoui float %2 to i32
40*9880d681SAndroid Build Coastguard Worker  ret i32 %3
41*9880d681SAndroid Build Coastguard Worker}
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @cmp
44*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = zext i8 %a to i32
45*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = zext i8 %b to i32
46*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = icmp slt i32 %1, %2
47*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i1 %3
48*9880d681SAndroid Build Coastguard Workerdefine i1 @cmp(i8 %a, i8 %b) {
49*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i8 %a to float
50*9880d681SAndroid Build Coastguard Worker  %2 = uitofp i8 %b to float
51*9880d681SAndroid Build Coastguard Worker  %3 = fcmp ult float %1, %2
52*9880d681SAndroid Build Coastguard Worker  ret i1 %3
53*9880d681SAndroid Build Coastguard Worker}
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple4
56*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = zext i32 %a to i64
57*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = add i64 %1, 1
58*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = trunc i64 %2 to i32
59*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i32 %3
60*9880d681SAndroid Build Coastguard Workerdefine i32 @simple4(i32 %a) {
61*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i32 %a to double
62*9880d681SAndroid Build Coastguard Worker  %2 = fadd double %1, 1.0
63*9880d681SAndroid Build Coastguard Worker  %3 = fptoui double %2 to i32
64*9880d681SAndroid Build Coastguard Worker  ret i32 %3
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple5
68*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = zext i8 %a to i32
69*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = zext i8 %b to i32
70*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = add i32 %1, 1
71*9880d681SAndroid Build Coastguard Worker; CHECK:  %4 = mul i32 %3, %2
72*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i32 %4
73*9880d681SAndroid Build Coastguard Workerdefine i32 @simple5(i8 %a, i8 %b) {
74*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i8 %a to float
75*9880d681SAndroid Build Coastguard Worker  %2 = uitofp i8 %b to float
76*9880d681SAndroid Build Coastguard Worker  %3 = fadd float %1, 1.0
77*9880d681SAndroid Build Coastguard Worker  %4 = fmul float %3, %2
78*9880d681SAndroid Build Coastguard Worker  %5 = fptoui float %4 to i32
79*9880d681SAndroid Build Coastguard Worker  ret i32 %5
80*9880d681SAndroid Build Coastguard Worker}
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker; The two chains don't interact - failure of one shouldn't
83*9880d681SAndroid Build Coastguard Worker; cause failure of the other.
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @multi1
86*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = zext i8 %a to i32
87*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = zext i8 %b to i32
88*9880d681SAndroid Build Coastguard Worker; CHECK:  %fc = uitofp i8 %c to float
89*9880d681SAndroid Build Coastguard Worker; CHECK:  %x1 = add i32 %1, %2
90*9880d681SAndroid Build Coastguard Worker; CHECK:  %z = fadd float %fc, %d
91*9880d681SAndroid Build Coastguard Worker; CHECK:  %w = fptoui float %z to i32
92*9880d681SAndroid Build Coastguard Worker; CHECK:  %r = add i32 %x1, %w
93*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i32 %r
94*9880d681SAndroid Build Coastguard Workerdefine i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) {
95*9880d681SAndroid Build Coastguard Worker  %fa = uitofp i8 %a to float
96*9880d681SAndroid Build Coastguard Worker  %fb = uitofp i8 %b to float
97*9880d681SAndroid Build Coastguard Worker  %fc = uitofp i8 %c to float
98*9880d681SAndroid Build Coastguard Worker  %x = fadd float %fa, %fb
99*9880d681SAndroid Build Coastguard Worker  %y = fptoui float %x to i32
100*9880d681SAndroid Build Coastguard Worker  %z = fadd float %fc, %d
101*9880d681SAndroid Build Coastguard Worker  %w = fptoui float %z to i32
102*9880d681SAndroid Build Coastguard Worker  %r = add i32 %y, %w
103*9880d681SAndroid Build Coastguard Worker  ret i32 %r
104*9880d681SAndroid Build Coastguard Worker}
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple_negzero
107*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = zext i8 %a to i32
108*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = add i32 %1, 0
109*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = trunc i32 %2 to i16
110*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i16 %3
111*9880d681SAndroid Build Coastguard Workerdefine i16 @simple_negzero(i8 %a) {
112*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i8 %a to float
113*9880d681SAndroid Build Coastguard Worker  %2 = fadd fast float %1, -0.0
114*9880d681SAndroid Build Coastguard Worker  %3 = fptoui float %2 to i16
115*9880d681SAndroid Build Coastguard Worker  ret i16 %3
116*9880d681SAndroid Build Coastguard Worker}
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple_negative
119*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = sext i8 %call to i32
120*9880d681SAndroid Build Coastguard Worker; CHECK: %mul1 = mul i32 %1, -3
121*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = trunc i32 %mul1 to i8
122*9880d681SAndroid Build Coastguard Worker; CHECK: %conv3 = sext i8 %2 to i32
123*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %conv3
124*9880d681SAndroid Build Coastguard Workerdefine i32 @simple_negative(i8 %call) {
125*9880d681SAndroid Build Coastguard Worker  %conv1 = sitofp i8 %call to float
126*9880d681SAndroid Build Coastguard Worker  %mul = fmul float %conv1, -3.000000e+00
127*9880d681SAndroid Build Coastguard Worker  %conv2 = fptosi float %mul to i8
128*9880d681SAndroid Build Coastguard Worker  %conv3 = sext i8 %conv2 to i32
129*9880d681SAndroid Build Coastguard Worker  ret i32 %conv3
130*9880d681SAndroid Build Coastguard Worker}
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Worker;
133*9880d681SAndroid Build Coastguard Worker; Negative tests
134*9880d681SAndroid Build Coastguard Worker;
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_multi1
137*9880d681SAndroid Build Coastguard Worker; CHECK:  %fa = uitofp i8 %a to float
138*9880d681SAndroid Build Coastguard Worker; CHECK:  %fc = uitofp i8 %c to float
139*9880d681SAndroid Build Coastguard Worker; CHECK:  %x = fadd float %fa, %fc
140*9880d681SAndroid Build Coastguard Worker; CHECK:  %y = fptoui float %x to i32
141*9880d681SAndroid Build Coastguard Worker; CHECK:  %z = fadd float %fc, %d
142*9880d681SAndroid Build Coastguard Worker; CHECK:  %w = fptoui float %z to i32
143*9880d681SAndroid Build Coastguard Worker; CHECK:  %r = add i32 %y, %w
144*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i32 %r
145*9880d681SAndroid Build Coastguard Worker; The two chains intersect, which means because one fails, no
146*9880d681SAndroid Build Coastguard Worker; transform can occur.
147*9880d681SAndroid Build Coastguard Workerdefine i32 @neg_multi1(i8 %a, i8 %b, i8 %c, float %d) {
148*9880d681SAndroid Build Coastguard Worker  %fa = uitofp i8 %a to float
149*9880d681SAndroid Build Coastguard Worker  %fc = uitofp i8 %c to float
150*9880d681SAndroid Build Coastguard Worker  %x = fadd float %fa, %fc
151*9880d681SAndroid Build Coastguard Worker  %y = fptoui float %x to i32
152*9880d681SAndroid Build Coastguard Worker  %z = fadd float %fc, %d
153*9880d681SAndroid Build Coastguard Worker  %w = fptoui float %z to i32
154*9880d681SAndroid Build Coastguard Worker  %r = add i32 %y, %w
155*9880d681SAndroid Build Coastguard Worker  ret i32 %r
156*9880d681SAndroid Build Coastguard Worker}
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_muld
159*9880d681SAndroid Build Coastguard Worker; CHECK:  %fa = uitofp i32 %a to double
160*9880d681SAndroid Build Coastguard Worker; CHECK:  %fb = uitofp i32 %b to double
161*9880d681SAndroid Build Coastguard Worker; CHECK:  %mul = fmul double %fa, %fb
162*9880d681SAndroid Build Coastguard Worker; CHECK:  %r = fptoui double %mul to i64
163*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i64 %r
164*9880d681SAndroid Build Coastguard Worker; The i32 * i32 = i64, which has 64 bits, which is greater than the 52 bits
165*9880d681SAndroid Build Coastguard Worker; that can be exactly represented in a double.
166*9880d681SAndroid Build Coastguard Workerdefine i64 @neg_muld(i32 %a, i32 %b) {
167*9880d681SAndroid Build Coastguard Worker  %fa = uitofp i32 %a to double
168*9880d681SAndroid Build Coastguard Worker  %fb = uitofp i32 %b to double
169*9880d681SAndroid Build Coastguard Worker  %mul = fmul double %fa, %fb
170*9880d681SAndroid Build Coastguard Worker  %r = fptoui double %mul to i64
171*9880d681SAndroid Build Coastguard Worker  ret i64 %r
172*9880d681SAndroid Build Coastguard Worker}
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_mulf
175*9880d681SAndroid Build Coastguard Worker; CHECK:  %fa = uitofp i16 %a to float
176*9880d681SAndroid Build Coastguard Worker; CHECK:  %fb = uitofp i16 %b to float
177*9880d681SAndroid Build Coastguard Worker; CHECK:  %mul = fmul float %fa, %fb
178*9880d681SAndroid Build Coastguard Worker; CHECK:  %r = fptoui float %mul to i32
179*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i32 %r
180*9880d681SAndroid Build Coastguard Worker; The i16 * i16 = i32, which can't be represented in a float, but can in a
181*9880d681SAndroid Build Coastguard Worker; double. This should fail, as the written code uses floats, not doubles so
182*9880d681SAndroid Build Coastguard Worker; the original result may be inaccurate.
183*9880d681SAndroid Build Coastguard Workerdefine i32 @neg_mulf(i16 %a, i16 %b) {
184*9880d681SAndroid Build Coastguard Worker  %fa = uitofp i16 %a to float
185*9880d681SAndroid Build Coastguard Worker  %fb = uitofp i16 %b to float
186*9880d681SAndroid Build Coastguard Worker  %mul = fmul float %fa, %fb
187*9880d681SAndroid Build Coastguard Worker  %r = fptoui float %mul to i32
188*9880d681SAndroid Build Coastguard Worker  ret i32 %r
189*9880d681SAndroid Build Coastguard Worker}
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_cmp
192*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = uitofp i8 %a to float
193*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = uitofp i8 %b to float
194*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = fcmp false float %1, %2
195*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i1 %3
196*9880d681SAndroid Build Coastguard Worker; "false" doesn't have an icmp equivalent.
197*9880d681SAndroid Build Coastguard Workerdefine i1 @neg_cmp(i8 %a, i8 %b) {
198*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i8 %a to float
199*9880d681SAndroid Build Coastguard Worker  %2 = uitofp i8 %b to float
200*9880d681SAndroid Build Coastguard Worker  %3 = fcmp false float %1, %2
201*9880d681SAndroid Build Coastguard Worker  ret i1 %3
202*9880d681SAndroid Build Coastguard Worker}
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_div
205*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = uitofp i8 %a to float
206*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = fdiv float %1, 1.0
207*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = fptoui float %2 to i16
208*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i16 %3
209*9880d681SAndroid Build Coastguard Worker; Division isn't a supported operator.
210*9880d681SAndroid Build Coastguard Workerdefine i16 @neg_div(i8 %a) {
211*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i8 %a to float
212*9880d681SAndroid Build Coastguard Worker  %2 = fdiv float %1, 1.0
213*9880d681SAndroid Build Coastguard Worker  %3 = fptoui float %2 to i16
214*9880d681SAndroid Build Coastguard Worker  ret i16 %3
215*9880d681SAndroid Build Coastguard Worker}
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_remainder
218*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = uitofp i8 %a to float
219*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = fadd float %1, 1.2
220*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = fptoui float %2 to i16
221*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i16 %3
222*9880d681SAndroid Build Coastguard Worker; 1.2 is not an integer.
223*9880d681SAndroid Build Coastguard Workerdefine i16 @neg_remainder(i8 %a) {
224*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i8 %a to float
225*9880d681SAndroid Build Coastguard Worker  %2 = fadd float %1, 1.25
226*9880d681SAndroid Build Coastguard Worker  %3 = fptoui float %2 to i16
227*9880d681SAndroid Build Coastguard Worker  ret i16 %3
228*9880d681SAndroid Build Coastguard Worker}
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_toolarge
231*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = uitofp i80 %a to fp128
232*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = fadd fp128 %1, %1
233*9880d681SAndroid Build Coastguard Worker; CHECK:  %3 = fptoui fp128 %2 to i80
234*9880d681SAndroid Build Coastguard Worker; CHECK:  ret i80 %3
235*9880d681SAndroid Build Coastguard Worker; i80 > i64, which is the largest bitwidth handleable by default.
236*9880d681SAndroid Build Coastguard Workerdefine i80 @neg_toolarge(i80 %a) {
237*9880d681SAndroid Build Coastguard Worker  %1 = uitofp i80 %a to fp128
238*9880d681SAndroid Build Coastguard Worker  %2 = fadd fp128 %1, %1
239*9880d681SAndroid Build Coastguard Worker  %3 = fptoui fp128 %2 to i80
240*9880d681SAndroid Build Coastguard Worker  ret i80 %3
241*9880d681SAndroid Build Coastguard Worker}
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_calluser
244*9880d681SAndroid Build Coastguard Worker; CHECK: sitofp
245*9880d681SAndroid Build Coastguard Worker; CHECK: fcmp
246*9880d681SAndroid Build Coastguard Worker; The sequence %1..%3 cannot be converted because %4 uses %2.
247*9880d681SAndroid Build Coastguard Workerdefine i32 @neg_calluser(i32 %value) {
248*9880d681SAndroid Build Coastguard Worker  %1 = sitofp i32 %value to double
249*9880d681SAndroid Build Coastguard Worker  %2 = fadd double %1, 1.0
250*9880d681SAndroid Build Coastguard Worker  %3 = fcmp olt double %2, 0.000000e+00
251*9880d681SAndroid Build Coastguard Worker  %4 = tail call double @g(double %2)
252*9880d681SAndroid Build Coastguard Worker  %5 = fptosi double %4 to i32
253*9880d681SAndroid Build Coastguard Worker  %6 = zext i1 %3 to i32
254*9880d681SAndroid Build Coastguard Worker  %7 = add i32 %6, %5
255*9880d681SAndroid Build Coastguard Worker  ret i32 %7
256*9880d681SAndroid Build Coastguard Worker}
257*9880d681SAndroid Build Coastguard Workerdeclare double @g(double)
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_vector
260*9880d681SAndroid Build Coastguard Worker; CHECK:  %1 = uitofp <4 x i8> %a to <4 x float>
261*9880d681SAndroid Build Coastguard Worker; CHECK:  %2 = fptoui <4 x float> %1 to <4 x i16>
262*9880d681SAndroid Build Coastguard Worker; CHECK:  ret <4 x i16> %2
263*9880d681SAndroid Build Coastguard Workerdefine <4 x i16> @neg_vector(<4 x i8> %a) {
264*9880d681SAndroid Build Coastguard Worker  %1 = uitofp <4 x i8> %a to <4 x float>
265*9880d681SAndroid Build Coastguard Worker  %2 = fptoui <4 x float> %1 to <4 x i16>
266*9880d681SAndroid Build Coastguard Worker  ret <4 x i16> %2
267*9880d681SAndroid Build Coastguard Worker}
268