xref: /aosp_15_r20/external/llvm/test/Transforms/InstSimplify/fast-math.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; NOTE: Assertions have been autogenerated by update_test_checks.py
2*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instsimplify -S | FileCheck %s
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker;; x * 0 ==> 0 when no-nans and no-signed-zero
5*9880d681SAndroid Build Coastguard Workerdefine float @mul_zero_1(float %a) {
6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_zero_1(
7*9880d681SAndroid Build Coastguard Worker; CHECK:         ret float 0.000000e+00
8*9880d681SAndroid Build Coastguard Worker;
9*9880d681SAndroid Build Coastguard Worker  %b = fmul nsz nnan float %a, 0.0
10*9880d681SAndroid Build Coastguard Worker  ret float %b
11*9880d681SAndroid Build Coastguard Worker}
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Workerdefine float @mul_zero_2(float %a) {
14*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_zero_2(
15*9880d681SAndroid Build Coastguard Worker; CHECK:         ret float 0.000000e+00
16*9880d681SAndroid Build Coastguard Worker;
17*9880d681SAndroid Build Coastguard Worker  %b = fmul fast float 0.0, %a
18*9880d681SAndroid Build Coastguard Worker  ret float %b
19*9880d681SAndroid Build Coastguard Worker}
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker;; x * 0 =/=> 0 when there could be nans or -0
22*9880d681SAndroid Build Coastguard Workerdefine float @no_mul_zero_1(float %a) {
23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @no_mul_zero_1(
24*9880d681SAndroid Build Coastguard Worker; CHECK:         [[B:%.*]] = fmul nsz float %a, 0.000000e+00
25*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    ret float [[B]]
26*9880d681SAndroid Build Coastguard Worker;
27*9880d681SAndroid Build Coastguard Worker  %b = fmul nsz float %a, 0.0
28*9880d681SAndroid Build Coastguard Worker  ret float %b
29*9880d681SAndroid Build Coastguard Worker}
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Workerdefine float @no_mul_zero_2(float %a) {
32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @no_mul_zero_2(
33*9880d681SAndroid Build Coastguard Worker; CHECK:         [[B:%.*]] = fmul nnan float %a, 0.000000e+00
34*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    ret float [[B]]
35*9880d681SAndroid Build Coastguard Worker;
36*9880d681SAndroid Build Coastguard Worker  %b = fmul nnan float %a, 0.0
37*9880d681SAndroid Build Coastguard Worker  ret float %b
38*9880d681SAndroid Build Coastguard Worker}
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Workerdefine float @no_mul_zero_3(float %a) {
41*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @no_mul_zero_3(
42*9880d681SAndroid Build Coastguard Worker; CHECK:         [[B:%.*]] = fmul float %a, 0.000000e+00
43*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    ret float [[B]]
44*9880d681SAndroid Build Coastguard Worker;
45*9880d681SAndroid Build Coastguard Worker  %b = fmul float %a, 0.0
46*9880d681SAndroid Build Coastguard Worker  ret float %b
47*9880d681SAndroid Build Coastguard Worker}
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; fadd [nnan ninf] X, (fsub [nnan ninf] 0, X) ==> 0
50*9880d681SAndroid Build Coastguard Worker;   where nnan and ninf have to occur at least once somewhere in this
51*9880d681SAndroid Build Coastguard Worker;   expression
52*9880d681SAndroid Build Coastguard Workerdefine float @fadd_fsub_0(float %a) {
53*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fadd_fsub_0(
54*9880d681SAndroid Build Coastguard Worker; CHECK:         [[NOFOLD:%.*]] = fsub float 0.000000e+00, %a
55*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    [[NO_ZERO:%.*]] = fadd nnan float [[NOFOLD]], %a
56*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    ret float [[NO_ZERO]]
57*9880d681SAndroid Build Coastguard Worker;
58*9880d681SAndroid Build Coastguard Worker; X + -X ==> 0
59*9880d681SAndroid Build Coastguard Worker  %t1 = fsub nnan ninf float 0.0, %a
60*9880d681SAndroid Build Coastguard Worker  %zero1 = fadd nnan ninf float %t1, %a
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker  %t2 = fsub nnan float 0.0, %a
63*9880d681SAndroid Build Coastguard Worker  %zero2 = fadd ninf float %t2, %a
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker  %t3 = fsub nnan ninf float 0.0, %a
66*9880d681SAndroid Build Coastguard Worker  %zero3 = fadd float %t3, %a
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker  %t4 = fsub float 0.0, %a
69*9880d681SAndroid Build Coastguard Worker  %zero4 = fadd nnan ninf float %t4, %a
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker; Dont fold this
72*9880d681SAndroid Build Coastguard Worker  %nofold = fsub float 0.0, %a
73*9880d681SAndroid Build Coastguard Worker  %no_zero = fadd nnan float %nofold, %a
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker; Coalesce the folded zeros
76*9880d681SAndroid Build Coastguard Worker  %zero5 = fadd float %zero1, %zero2
77*9880d681SAndroid Build Coastguard Worker  %zero6 = fadd float %zero3, %zero4
78*9880d681SAndroid Build Coastguard Worker  %zero7 = fadd float %zero5, %zero6
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker; Should get folded
81*9880d681SAndroid Build Coastguard Worker  %ret = fadd nsz float %no_zero, %zero7
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker  ret float %ret
84*9880d681SAndroid Build Coastguard Worker}
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker; fsub nnan x, x ==> 0.0
87*9880d681SAndroid Build Coastguard Workerdefine float @fsub_x_x(float %a) {
88*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fsub_x_x(
89*9880d681SAndroid Build Coastguard Worker; CHECK:         [[NO_ZERO1:%.*]] = fsub ninf float %a, %a
90*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    [[NO_ZERO2:%.*]] = fsub float %a, %a
91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    [[NO_ZERO:%.*]] = fadd float [[NO_ZERO1:%.*]], [[NO_ZERO2:%.*]]
92*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    ret float [[NO_ZERO]]
93*9880d681SAndroid Build Coastguard Worker;
94*9880d681SAndroid Build Coastguard Worker; X - X ==> 0
95*9880d681SAndroid Build Coastguard Worker  %zero1 = fsub nnan float %a, %a
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker; Dont fold
98*9880d681SAndroid Build Coastguard Worker  %no_zero1 = fsub ninf float %a, %a
99*9880d681SAndroid Build Coastguard Worker  %no_zero2 = fsub float %a, %a
100*9880d681SAndroid Build Coastguard Worker  %no_zero = fadd float %no_zero1, %no_zero2
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker; Should get folded
103*9880d681SAndroid Build Coastguard Worker  %ret = fadd nsz float %no_zero, %zero1
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker  ret float %ret
106*9880d681SAndroid Build Coastguard Worker}
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker; fsub nsz 0.0, (fsub 0.0, X) ==> X
109*9880d681SAndroid Build Coastguard Workerdefine float @fsub_0_0_x(float %a) {
110*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fsub_0_0_x(
111*9880d681SAndroid Build Coastguard Worker; CHECK:         ret float %a
112*9880d681SAndroid Build Coastguard Worker;
113*9880d681SAndroid Build Coastguard Worker  %t1 = fsub float 0.0, %a
114*9880d681SAndroid Build Coastguard Worker  %ret = fsub nsz float 0.0, %t1
115*9880d681SAndroid Build Coastguard Worker  ret float %ret
116*9880d681SAndroid Build Coastguard Worker}
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker; fadd nsz X, 0 ==> X
119*9880d681SAndroid Build Coastguard Workerdefine float @nofold_fadd_x_0(float %a) {
120*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @nofold_fadd_x_0(
121*9880d681SAndroid Build Coastguard Worker; CHECK:         [[NO_ZERO1:%.*]] = fadd ninf float %a, 0.000000e+00
122*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    [[NO_ZERO2:%.*]] = fadd nnan float %a, 0.000000e+00
123*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    [[NO_ZERO:%.*]] = fadd float [[NO_ZERO1:%.*]], [[NO_ZERO2:%.*]]
124*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    ret float [[NO_ZERO]]
125*9880d681SAndroid Build Coastguard Worker;
126*9880d681SAndroid Build Coastguard Worker; Dont fold
127*9880d681SAndroid Build Coastguard Worker  %no_zero1 = fadd ninf float %a, 0.0
128*9880d681SAndroid Build Coastguard Worker  %no_zero2 = fadd nnan float %a, 0.0
129*9880d681SAndroid Build Coastguard Worker  %no_zero = fadd float %no_zero1, %no_zero2
130*9880d681SAndroid Build Coastguard Worker  ret float %no_zero
131*9880d681SAndroid Build Coastguard Worker}
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker; fdiv nsz nnan 0, X ==> 0
134*9880d681SAndroid Build Coastguard Workerdefine double @fdiv_zero_by_x(double %X) {
135*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv_zero_by_x(
136*9880d681SAndroid Build Coastguard Worker; CHECK:         ret double 0.000000e+00
137*9880d681SAndroid Build Coastguard Worker;
138*9880d681SAndroid Build Coastguard Worker; 0 / X -> 0
139*9880d681SAndroid Build Coastguard Worker  %r = fdiv nnan nsz double 0.0, %X
140*9880d681SAndroid Build Coastguard Worker  ret double %r
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Workerdefine float @fdiv_self(float %f) {
144*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv_self(
145*9880d681SAndroid Build Coastguard Worker; CHECK:         ret float 1.000000e+00
146*9880d681SAndroid Build Coastguard Worker;
147*9880d681SAndroid Build Coastguard Worker  %div = fdiv nnan float %f, %f
148*9880d681SAndroid Build Coastguard Worker  ret float %div
149*9880d681SAndroid Build Coastguard Worker}
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Workerdefine float @fdiv_self_invalid(float %f) {
152*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv_self_invalid(
153*9880d681SAndroid Build Coastguard Worker; CHECK:         [[DIV:%.*]] = fdiv float %f, %f
154*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    ret float [[DIV]]
155*9880d681SAndroid Build Coastguard Worker;
156*9880d681SAndroid Build Coastguard Worker  %div = fdiv float %f, %f
157*9880d681SAndroid Build Coastguard Worker  ret float %div
158*9880d681SAndroid Build Coastguard Worker}
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Workerdefine float @fdiv_neg1(float %f) {
161*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv_neg1(
162*9880d681SAndroid Build Coastguard Worker; CHECK:         ret float -1.000000e+00
163*9880d681SAndroid Build Coastguard Worker;
164*9880d681SAndroid Build Coastguard Worker  %neg = fsub fast float -0.000000e+00, %f
165*9880d681SAndroid Build Coastguard Worker  %div = fdiv nnan float %neg, %f
166*9880d681SAndroid Build Coastguard Worker  ret float %div
167*9880d681SAndroid Build Coastguard Worker}
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Workerdefine float @fdiv_neg2(float %f) {
170*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv_neg2(
171*9880d681SAndroid Build Coastguard Worker; CHECK:         ret float -1.000000e+00
172*9880d681SAndroid Build Coastguard Worker;
173*9880d681SAndroid Build Coastguard Worker  %neg = fsub fast float 0.000000e+00, %f
174*9880d681SAndroid Build Coastguard Worker  %div = fdiv nnan float %neg, %f
175*9880d681SAndroid Build Coastguard Worker  ret float %div
176*9880d681SAndroid Build Coastguard Worker}
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Workerdefine float @fdiv_neg_invalid(float %f) {
179*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv_neg_invalid(
180*9880d681SAndroid Build Coastguard Worker; CHECK:         [[NEG:%.*]] = fsub fast float -0.000000e+00, %f
181*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], %f
182*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    ret float [[DIV]]
183*9880d681SAndroid Build Coastguard Worker;
184*9880d681SAndroid Build Coastguard Worker  %neg = fsub fast float -0.000000e+00, %f
185*9880d681SAndroid Build Coastguard Worker  %div = fdiv float %neg, %f
186*9880d681SAndroid Build Coastguard Worker  ret float %div
187*9880d681SAndroid Build Coastguard Worker}
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Workerdefine float @fdiv_neg_swapped1(float %f) {
190*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv_neg_swapped1(
191*9880d681SAndroid Build Coastguard Worker; CHECK:         ret float -1.000000e+00
192*9880d681SAndroid Build Coastguard Worker;
193*9880d681SAndroid Build Coastguard Worker  %neg = fsub float -0.000000e+00, %f
194*9880d681SAndroid Build Coastguard Worker  %div = fdiv nnan float %f, %neg
195*9880d681SAndroid Build Coastguard Worker  ret float %div
196*9880d681SAndroid Build Coastguard Worker}
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Workerdefine float @fdiv_neg_swapped2(float %f) {
199*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv_neg_swapped2(
200*9880d681SAndroid Build Coastguard Worker; CHECK:         ret float -1.000000e+00
201*9880d681SAndroid Build Coastguard Worker;
202*9880d681SAndroid Build Coastguard Worker  %neg = fsub float 0.000000e+00, %f
203*9880d681SAndroid Build Coastguard Worker  %div = fdiv nnan float %f, %neg
204*9880d681SAndroid Build Coastguard Worker  ret float %div
205*9880d681SAndroid Build Coastguard Worker}
206