• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instcombine -S < %s                        | FileCheck %s --check-prefixes=CHECK,SQRT
3; RUN: opt -instcombine -S < %s -disable-builtin sqrt  | FileCheck %s --check-prefixes=CHECK,NOSQRT
4
5declare double @llvm.pow.f64(double, double)
6declare float @llvm.pow.f32(float, float)
7declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>)
8declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>)
9declare <4 x float> @llvm.pow.v4f32(<4 x float>, <4 x float>)
10declare double @pow(double, double)
11
12; pow(x, 3.0)
13define double @test_simplify_3(double %x) {
14; CHECK-LABEL: @test_simplify_3(
15; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast double [[X:%.*]], [[X]]
16; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[X]]
17; CHECK-NEXT:    ret double [[TMP1]]
18;
19  %1 = call fast double @llvm.pow.f64(double %x, double 3.000000e+00)
20  ret double %1
21}
22
23; powf(x, 4.0)
24define float @test_simplify_4f(float %x) {
25; CHECK-LABEL: @test_simplify_4f(
26; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
27; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[SQUARE]], [[SQUARE]]
28; CHECK-NEXT:    ret float [[TMP1]]
29;
30  %1 = call fast float @llvm.pow.f32(float %x, float 4.000000e+00)
31  ret float %1
32}
33
34; pow(x, 4.0)
35define double @test_simplify_4(double %x) {
36; CHECK-LABEL: @test_simplify_4(
37; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast double [[X:%.*]], [[X]]
38; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]]
39; CHECK-NEXT:    ret double [[TMP1]]
40;
41  %1 = call fast double @llvm.pow.f64(double %x, double 4.000000e+00)
42  ret double %1
43}
44
45; powf(x, <15.0, 15.0>)
46define <2 x float> @test_simplify_15(<2 x float> %x) {
47; CHECK-LABEL: @test_simplify_15(
48; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast <2 x float> [[X:%.*]], [[X]]
49; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast <2 x float> [[SQUARE]], [[X]]
50; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast <2 x float> [[TMP1]], [[TMP1]]
51; CHECK-NEXT:    [[TMP3:%.*]] = fmul fast <2 x float> [[TMP2]], [[TMP2]]
52; CHECK-NEXT:    [[TMP4:%.*]] = fmul fast <2 x float> [[TMP1]], [[TMP3]]
53; CHECK-NEXT:    ret <2 x float> [[TMP4]]
54;
55  %1 = call fast <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.500000e+01, float 1.500000e+01>)
56  ret <2 x float> %1
57}
58
59; pow(x, -7.0)
60define <2 x double> @test_simplify_neg_7(<2 x double> %x) {
61; CHECK-LABEL: @test_simplify_neg_7(
62; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast <2 x double> [[X:%.*]], [[X]]
63; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast <2 x double> [[SQUARE]], [[SQUARE]]
64; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast <2 x double> [[TMP1]], [[X]]
65; CHECK-NEXT:    [[TMP3:%.*]] = fmul fast <2 x double> [[SQUARE]], [[TMP2]]
66; CHECK-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[TMP3]]
67; CHECK-NEXT:    ret <2 x double> [[RECIPROCAL]]
68;
69  %1 = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -7.000000e+00, double -7.000000e+00>)
70  ret <2 x double> %1
71}
72
73; powf(x, -19.0)
74define float @test_simplify_neg_19(float %x) {
75; CHECK-LABEL: @test_simplify_neg_19(
76; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
77; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[SQUARE]], [[SQUARE]]
78; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast float [[TMP1]], [[TMP1]]
79; CHECK-NEXT:    [[TMP3:%.*]] = fmul fast float [[TMP2]], [[TMP2]]
80; CHECK-NEXT:    [[TMP4:%.*]] = fmul fast float [[SQUARE]], [[TMP3]]
81; CHECK-NEXT:    [[TMP5:%.*]] = fmul fast float [[TMP4]], [[X]]
82; CHECK-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast float 1.000000e+00, [[TMP5]]
83; CHECK-NEXT:    ret float [[RECIPROCAL]]
84;
85  %1 = call fast float @llvm.pow.f32(float %x, float -1.900000e+01)
86  ret float %1
87}
88
89; pow(x, 11.23)
90define double @test_simplify_11_23(double %x) {
91; CHECK-LABEL: @test_simplify_11_23(
92; CHECK-NEXT:    [[TMP1:%.*]] = call fast double @llvm.pow.f64(double [[X:%.*]], double 1.123000e+01)
93; CHECK-NEXT:    ret double [[TMP1]]
94;
95  %1 = call fast double @llvm.pow.f64(double %x, double 1.123000e+01)
96  ret double %1
97}
98
99; powf(x, 32.0)
100define float @test_simplify_32(float %x) {
101; CHECK-LABEL: @test_simplify_32(
102; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
103; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[SQUARE]], [[SQUARE]]
104; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast float [[TMP1]], [[TMP1]]
105; CHECK-NEXT:    [[TMP3:%.*]] = fmul fast float [[TMP2]], [[TMP2]]
106; CHECK-NEXT:    [[TMP4:%.*]] = fmul fast float [[TMP3]], [[TMP3]]
107; CHECK-NEXT:    ret float [[TMP4]]
108;
109  %1 = call fast float @llvm.pow.f32(float %x, float 3.200000e+01)
110  ret float %1
111}
112
113; pow(x, 33.0)
114define double @test_simplify_33(double %x) {
115; CHECK-LABEL: @test_simplify_33(
116; CHECK-NEXT:    [[TMP1:%.*]] = call fast double @llvm.powi.f64(double [[X:%.*]], i32 33)
117; CHECK-NEXT:    ret double [[TMP1]]
118;
119  %1 = call fast double @llvm.pow.f64(double %x, double 3.300000e+01)
120  ret double %1
121}
122
123; pow(x, 16.5) with double
124define double @test_simplify_16_5(double %x) {
125; CHECK-LABEL: @test_simplify_16_5(
126; CHECK-NEXT:    [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[X:%.*]])
127; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast double [[X]], [[X]]
128; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]]
129; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast double [[TMP1]], [[TMP1]]
130; CHECK-NEXT:    [[TMP3:%.*]] = fmul fast double [[TMP2]], [[TMP2]]
131; CHECK-NEXT:    [[TMP4:%.*]] = fmul fast double [[TMP3]], [[SQRT]]
132; CHECK-NEXT:    ret double [[TMP4]]
133;
134  %1 = call fast double @llvm.pow.f64(double %x, double 1.650000e+01)
135  ret double %1
136}
137
138; pow(x, -16.5) with double
139define double @test_simplify_neg_16_5(double %x) {
140; CHECK-LABEL: @test_simplify_neg_16_5(
141; CHECK-NEXT:    [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[X:%.*]])
142; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast double [[X]], [[X]]
143; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]]
144; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast double [[TMP1]], [[TMP1]]
145; CHECK-NEXT:    [[TMP3:%.*]] = fmul fast double [[TMP2]], [[TMP2]]
146; CHECK-NEXT:    [[TMP4:%.*]] = fmul fast double [[TMP3]], [[SQRT]]
147; CHECK-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[TMP4]]
148; CHECK-NEXT:    ret double [[RECIPROCAL]]
149;
150  %1 = call fast double @llvm.pow.f64(double %x, double -1.650000e+01)
151  ret double %1
152}
153
154; pow(x, 16.5) with double
155
156define double @test_simplify_16_5_libcall(double %x) {
157; SQRT-LABEL: @test_simplify_16_5_libcall(
158; SQRT-NEXT:    [[SQRT:%.*]] = call fast double @sqrt(double [[X:%.*]])
159; SQRT-NEXT:    [[SQUARE:%.*]] = fmul fast double [[X]], [[X]]
160; SQRT-NEXT:    [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]]
161; SQRT-NEXT:    [[TMP2:%.*]] = fmul fast double [[TMP1]], [[TMP1]]
162; SQRT-NEXT:    [[TMP3:%.*]] = fmul fast double [[TMP2]], [[TMP2]]
163; SQRT-NEXT:    [[TMP4:%.*]] = fmul fast double [[TMP3]], [[SQRT]]
164; SQRT-NEXT:    ret double [[TMP4]]
165;
166; NOSQRT-LABEL: @test_simplify_16_5_libcall(
167; NOSQRT-NEXT:    [[TMP1:%.*]] = call fast double @pow(double [[X:%.*]], double 1.650000e+01)
168; NOSQRT-NEXT:    ret double [[TMP1]]
169;
170  %1 = call fast double @pow(double %x, double 1.650000e+01)
171  ret double %1
172}
173
174; pow(x, -16.5) with double
175
176define double @test_simplify_neg_16_5_libcall(double %x) {
177; SQRT-LABEL: @test_simplify_neg_16_5_libcall(
178; SQRT-NEXT:    [[SQRT:%.*]] = call fast double @sqrt(double [[X:%.*]])
179; SQRT-NEXT:    [[SQUARE:%.*]] = fmul fast double [[X]], [[X]]
180; SQRT-NEXT:    [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]]
181; SQRT-NEXT:    [[TMP2:%.*]] = fmul fast double [[TMP1]], [[TMP1]]
182; SQRT-NEXT:    [[TMP3:%.*]] = fmul fast double [[TMP2]], [[TMP2]]
183; SQRT-NEXT:    [[TMP4:%.*]] = fmul fast double [[TMP3]], [[SQRT]]
184; SQRT-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[TMP4]]
185; SQRT-NEXT:    ret double [[RECIPROCAL]]
186;
187; NOSQRT-LABEL: @test_simplify_neg_16_5_libcall(
188; NOSQRT-NEXT:    [[TMP1:%.*]] = call fast double @pow(double [[X:%.*]], double -1.650000e+01)
189; NOSQRT-NEXT:    ret double [[TMP1]]
190;
191  %1 = call fast double @pow(double %x, double -1.650000e+01)
192  ret double %1
193}
194
195; pow(x, -8.5) with float
196define float @test_simplify_neg_8_5(float %x) {
197; CHECK-LABEL: @test_simplify_neg_8_5(
198; CHECK-NEXT:    [[SQRT:%.*]] = call fast float @llvm.sqrt.f32(float [[X:%.*]])
199; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
200; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[SQUARE]], [[SQUARE]]
201; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast float [[TMP1]], [[SQRT]]
202; CHECK-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast float 1.000000e+00, [[TMP2]]
203; CHECK-NEXT:    ret float [[RECIPROCAL]]
204;
205  %1 = call fast float @llvm.pow.f32(float %x, float -0.450000e+01)
206  ret float %1
207}
208
209; pow(x, 7.5) with <2 x double>
210define <2 x double> @test_simplify_7_5(<2 x double> %x) {
211; CHECK-LABEL: @test_simplify_7_5(
212; CHECK-NEXT:    [[SQRT:%.*]] = call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> [[X:%.*]])
213; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast <2 x double> [[X]], [[X]]
214; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast <2 x double> [[SQUARE]], [[SQUARE]]
215; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast <2 x double> [[TMP1]], [[X]]
216; CHECK-NEXT:    [[TMP3:%.*]] = fmul fast <2 x double> [[SQUARE]], [[TMP2]]
217; CHECK-NEXT:    [[TMP4:%.*]] = fmul fast <2 x double> [[TMP3]], [[SQRT]]
218; CHECK-NEXT:    ret <2 x double> [[TMP4]]
219;
220  %1 = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 7.500000e+00, double 7.500000e+00>)
221  ret <2 x double> %1
222}
223
224; pow(x, 3.5) with <4 x float>
225define <4 x float> @test_simplify_3_5(<4 x float> %x) {
226; CHECK-LABEL: @test_simplify_3_5(
227; CHECK-NEXT:    [[SQRT:%.*]] = call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> [[X:%.*]])
228; CHECK-NEXT:    [[SQUARE:%.*]] = fmul fast <4 x float> [[X]], [[X]]
229; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast <4 x float> [[SQUARE]], [[X]]
230; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast <4 x float> [[TMP1]], [[SQRT]]
231; CHECK-NEXT:    ret <4 x float> [[TMP2]]
232;
233  %1 = call fast <4 x float> @llvm.pow.v4f32(<4 x float> %x, <4 x float> <float 3.500000e+00, float 3.500000e+00, float 3.500000e+00, float 3.500000e+00>)
234  ret <4 x float> %1
235}
236
237; (float)pow((double)(float)x, 0.5)
238; FIXME: One call to `sqrtf` would suffice (PR47613).
239define float @shrink_pow_libcall_half(float %x) {
240; SQRT-LABEL: @shrink_pow_libcall_half(
241; SQRT-NEXT:    [[SQRTF:%.*]] = call fast float @sqrtf(float [[X:%.*]])
242; SQRT-NEXT:    [[SQRTF1:%.*]] = call fast float @sqrtf(float [[X]])
243; SQRT-NEXT:    ret float [[SQRTF1]]
244;
245; NOSQRT-LABEL: @shrink_pow_libcall_half(
246; NOSQRT-NEXT:    [[SQRTF:%.*]] = call fast float @sqrtf(float [[X:%.*]])
247; NOSQRT-NEXT:    ret float [[SQRTF]]
248;
249  %dx = fpext float %x to double
250  %call = call fast double @pow(double %dx, double 0.5)
251  %fr = fptrunc double %call to float
252  ret float %fr
253}
254
255; Make sure that -0.0 exponent is always simplified.
256
257define double @PR43233(double %x) {
258; CHECK-LABEL: @PR43233(
259; CHECK-NEXT:    ret double 1.000000e+00
260;
261  %r = call fast double @llvm.pow.f64(double %x, double -0.0)
262  ret double %r
263}
264
265