xref: /llvm-project/llvm/test/Transforms/InstCombine/pow-1.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; Test that the pow library call simplifier works correctly.
3;
4; RUN: opt -passes=instcombine -S < %s                                   | FileCheck %s --check-prefixes=CHECK,LIB,ANY
5; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.9  | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
6; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios7.0         | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
7; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.8  | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10
8; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios6.0         | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10
9; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-netbsd            | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10
10; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-tvos9.0        | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
11; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-watchos2.0     | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
12; rdar://7251832
13; RUN: opt -passes=instcombine -S < %s -mtriple=i386-pc-windows-msvc18   | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC32
14; RUN: opt -passes=instcombine -S < %s -mtriple=i386-pc-windows-msvc     | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC19,VC51
15; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC64
16; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-pc-windows-msvc   | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC19,VC83
17; RUN: opt -passes=instcombine -S < %s -mtriple=amdgcn--                 | FileCheck %s --check-prefixes=CHECK,CHECK-NO-EXP10,NOLIB
18
19; NOTE: The readonly attribute on the pow call should be preserved
20; in the cases below where pow is transformed into another function call.
21
22declare float @powf(float, float)
23declare float @llvm.pow.f32(float, float)
24declare float @llvm.fabs.f32(float)
25declare double @pow(double, double)
26declare double @llvm.pow.f64(double, double)
27declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>) nounwind readonly
28declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) nounwind readonly
29declare void @llvm.assume(i1 noundef)
30
31; Check pow(1.0, x) -> 1.0.
32
33define float @test_simplify1(float %x) {
34; ANY-LABEL: define float @test_simplify1(
35; ANY-SAME: float [[X:%.*]]) {
36; ANY-NEXT:    ret float 1.000000e+00
37;
38; VC32-LABEL: define float @test_simplify1(
39; VC32-SAME: float [[X:%.*]]) {
40; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]])
41; VC32-NEXT:    ret float [[RETVAL]]
42;
43; VC51-LABEL: define float @test_simplify1(
44; VC51-SAME: float [[X:%.*]]) {
45; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]])
46; VC51-NEXT:    ret float [[RETVAL]]
47;
48; VC64-LABEL: define float @test_simplify1(
49; VC64-SAME: float [[X:%.*]]) {
50; VC64-NEXT:    ret float 1.000000e+00
51;
52; VC83-LABEL: define float @test_simplify1(
53; VC83-SAME: float [[X:%.*]]) {
54; VC83-NEXT:    ret float 1.000000e+00
55;
56; NOLIB-LABEL: define float @test_simplify1(
57; NOLIB-SAME: float [[X:%.*]]) {
58; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]])
59; NOLIB-NEXT:    ret float [[RETVAL]]
60;
61  %retval = call float @powf(float 1.0, float %x)
62  ret float %retval
63}
64
65define float @test_simplify1_noerrno(float %x) {
66; ANY-LABEL: define float @test_simplify1_noerrno(
67; ANY-SAME: float [[X:%.*]]) {
68; ANY-NEXT:    ret float 1.000000e+00
69;
70; VC32-LABEL: define float @test_simplify1_noerrno(
71; VC32-SAME: float [[X:%.*]]) {
72; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]]
73; VC32-NEXT:    ret float [[RETVAL]]
74;
75; VC51-LABEL: define float @test_simplify1_noerrno(
76; VC51-SAME: float [[X:%.*]]) {
77; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]]
78; VC51-NEXT:    ret float [[RETVAL]]
79;
80; VC64-LABEL: define float @test_simplify1_noerrno(
81; VC64-SAME: float [[X:%.*]]) {
82; VC64-NEXT:    ret float 1.000000e+00
83;
84; VC83-LABEL: define float @test_simplify1_noerrno(
85; VC83-SAME: float [[X:%.*]]) {
86; VC83-NEXT:    ret float 1.000000e+00
87;
88; NOLIB-LABEL: define float @test_simplify1_noerrno(
89; NOLIB-SAME: float [[X:%.*]]) {
90; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]]
91; NOLIB-NEXT:    ret float [[RETVAL]]
92;
93  %retval = call float @powf(float 1.0, float %x) #0
94  ret float %retval
95}
96
97define <2 x float> @test_simplify1v(<2 x float> %x) {
98; CHECK-LABEL: define <2 x float> @test_simplify1v(
99; CHECK-SAME: <2 x float> [[X:%.*]]) {
100; CHECK-NEXT:    ret <2 x float> splat (float 1.000000e+00)
101;
102  %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.0, float 1.0>, <2 x float> %x)
103  ret <2 x float> %retval
104}
105
106define double @test_simplify2(double %x) {
107; LIB-LABEL: define double @test_simplify2(
108; LIB-SAME: double [[X:%.*]]) {
109; LIB-NEXT:    ret double 1.000000e+00
110;
111; NOLIB-LABEL: define double @test_simplify2(
112; NOLIB-SAME: double [[X:%.*]]) {
113; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double 1.000000e+00, double [[X]])
114; NOLIB-NEXT:    ret double [[RETVAL]]
115;
116  %retval = call double @pow(double 1.0, double %x)
117  ret double %retval
118}
119
120define double @test_simplify2_noerrno(double %x) {
121; LIB-LABEL: define double @test_simplify2_noerrno(
122; LIB-SAME: double [[X:%.*]]) {
123; LIB-NEXT:    ret double 1.000000e+00
124;
125; NOLIB-LABEL: define double @test_simplify2_noerrno(
126; NOLIB-SAME: double [[X:%.*]]) {
127; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double 1.000000e+00, double [[X]]) #[[ATTR2]]
128; NOLIB-NEXT:    ret double [[RETVAL]]
129;
130  %retval = call double @pow(double 1.0, double %x) #0
131  ret double %retval
132}
133
134define <2 x double> @test_simplify2v(<2 x double> %x) {
135; CHECK-LABEL: define <2 x double> @test_simplify2v(
136; CHECK-SAME: <2 x double> [[X:%.*]]) {
137; CHECK-NEXT:    ret <2 x double> splat (double 1.000000e+00)
138;
139  %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> %x)
140  ret <2 x double> %retval
141}
142
143; Check pow(2.0 ** n, x) -> exp2(n * x).
144
145define float @test_simplify3(float %x) {
146; ANY-LABEL: define float @test_simplify3(
147; ANY-SAME: float [[X:%.*]]) {
148; ANY-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[X]])
149; ANY-NEXT:    ret float [[EXP2F]]
150;
151; VC32-LABEL: define float @test_simplify3(
152; VC32-SAME: float [[X:%.*]]) {
153; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]])
154; VC32-NEXT:    ret float [[RETVAL]]
155;
156; VC51-LABEL: define float @test_simplify3(
157; VC51-SAME: float [[X:%.*]]) {
158; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]])
159; VC51-NEXT:    ret float [[RETVAL]]
160;
161; VC64-LABEL: define float @test_simplify3(
162; VC64-SAME: float [[X:%.*]]) {
163; VC64-NEXT:    [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]])
164; VC64-NEXT:    ret float [[RETVAL]]
165;
166; VC83-LABEL: define float @test_simplify3(
167; VC83-SAME: float [[X:%.*]]) {
168; VC83-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[X]])
169; VC83-NEXT:    ret float [[EXP2F]]
170;
171; NOLIB-LABEL: define float @test_simplify3(
172; NOLIB-SAME: float [[X:%.*]]) {
173; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]])
174; NOLIB-NEXT:    ret float [[RETVAL]]
175;
176  %retval = call float @powf(float 2.0, float %x)
177  ret float %retval
178}
179
180define float @test_simplify3_noerrno(float %x) {
181; ANY-LABEL: define float @test_simplify3_noerrno(
182; ANY-SAME: float [[X:%.*]]) {
183; ANY-NEXT:    [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[X]])
184; ANY-NEXT:    ret float [[EXP2]]
185;
186; VC32-LABEL: define float @test_simplify3_noerrno(
187; VC32-SAME: float [[X:%.*]]) {
188; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2]]
189; VC32-NEXT:    ret float [[RETVAL]]
190;
191; VC51-LABEL: define float @test_simplify3_noerrno(
192; VC51-SAME: float [[X:%.*]]) {
193; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2]]
194; VC51-NEXT:    ret float [[RETVAL]]
195;
196; VC64-LABEL: define float @test_simplify3_noerrno(
197; VC64-SAME: float [[X:%.*]]) {
198; VC64-NEXT:    [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]]
199; VC64-NEXT:    ret float [[RETVAL]]
200;
201; VC83-LABEL: define float @test_simplify3_noerrno(
202; VC83-SAME: float [[X:%.*]]) {
203; VC83-NEXT:    [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[X]])
204; VC83-NEXT:    ret float [[EXP2]]
205;
206; NOLIB-LABEL: define float @test_simplify3_noerrno(
207; NOLIB-SAME: float [[X:%.*]]) {
208; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2]]
209; NOLIB-NEXT:    ret float [[RETVAL]]
210;
211  %retval = call float @powf(float 2.0, float %x) #0
212  ret float %retval
213}
214
215define double @test_simplify3n_noerrno(double %x) {
216; ANY-LABEL: define double @test_simplify3n_noerrno(
217; ANY-SAME: double [[X:%.*]]) {
218; ANY-NEXT:    [[MUL:%.*]] = fmul double [[X]], -2.000000e+00
219; ANY-NEXT:    [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[MUL]])
220; ANY-NEXT:    ret double [[EXP2]]
221;
222; VC32-LABEL: define double @test_simplify3n_noerrno(
223; VC32-SAME: double [[X:%.*]]) {
224; VC32-NEXT:    [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X]]) #[[ATTR2]]
225; VC32-NEXT:    ret double [[RETVAL]]
226;
227; VC19-LABEL: define double @test_simplify3n_noerrno(
228; VC19-SAME: double [[X:%.*]]) {
229; VC19-NEXT:    [[MUL:%.*]] = fmul double [[X]], -2.000000e+00
230; VC19-NEXT:    [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[MUL]])
231; VC19-NEXT:    ret double [[EXP2]]
232;
233; VC64-LABEL: define double @test_simplify3n_noerrno(
234; VC64-SAME: double [[X:%.*]]) {
235; VC64-NEXT:    [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X]]) #[[ATTR2]]
236; VC64-NEXT:    ret double [[RETVAL]]
237;
238; NOLIB-LABEL: define double @test_simplify3n_noerrno(
239; NOLIB-SAME: double [[X:%.*]]) {
240; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X]]) #[[ATTR2]]
241; NOLIB-NEXT:    ret double [[RETVAL]]
242;
243  %retval = call double @pow(double 0.25, double %x) #0
244  ret double %retval
245}
246
247; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
248define <2 x float> @test_simplify3v(<2 x float> %x) {
249; ANY-LABEL: define <2 x float> @test_simplify3v(
250; ANY-SAME: <2 x float> [[X:%.*]]) {
251; ANY-NEXT:    [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X]])
252; ANY-NEXT:    ret <2 x float> [[EXP2]]
253;
254; VC32-LABEL: define <2 x float> @test_simplify3v(
255; VC32-SAME: <2 x float> [[X:%.*]]) {
256; VC32-NEXT:    [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]])
257; VC32-NEXT:    ret <2 x float> [[RETVAL]]
258;
259; VC19-LABEL: define <2 x float> @test_simplify3v(
260; VC19-SAME: <2 x float> [[X:%.*]]) {
261; VC19-NEXT:    [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]])
262; VC19-NEXT:    ret <2 x float> [[RETVAL]]
263;
264; VC64-LABEL: define <2 x float> @test_simplify3v(
265; VC64-SAME: <2 x float> [[X:%.*]]) {
266; VC64-NEXT:    [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]])
267; VC64-NEXT:    ret <2 x float> [[RETVAL]]
268;
269; NOLIB-LABEL: define <2 x float> @test_simplify3v(
270; NOLIB-SAME: <2 x float> [[X:%.*]]) {
271; NOLIB-NEXT:    [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]])
272; NOLIB-NEXT:    ret <2 x float> [[RETVAL]]
273;
274  %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.0, float 2.0>, <2 x float> %x)
275  ret <2 x float> %retval
276}
277
278; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
279define <2 x double> @test_simplify3vn(<2 x double> %x) {
280; ANY-LABEL: define <2 x double> @test_simplify3vn(
281; ANY-SAME: <2 x double> [[X:%.*]]) {
282; ANY-NEXT:    [[MUL:%.*]] = fmul <2 x double> [[X]], splat (double 2.000000e+00)
283; ANY-NEXT:    [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]])
284; ANY-NEXT:    ret <2 x double> [[EXP2]]
285;
286; VC32-LABEL: define <2 x double> @test_simplify3vn(
287; VC32-SAME: <2 x double> [[X:%.*]]) {
288; VC32-NEXT:    [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]])
289; VC32-NEXT:    ret <2 x double> [[RETVAL]]
290;
291; VC19-LABEL: define <2 x double> @test_simplify3vn(
292; VC19-SAME: <2 x double> [[X:%.*]]) {
293; VC19-NEXT:    [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]])
294; VC19-NEXT:    ret <2 x double> [[RETVAL]]
295;
296; VC64-LABEL: define <2 x double> @test_simplify3vn(
297; VC64-SAME: <2 x double> [[X:%.*]]) {
298; VC64-NEXT:    [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]])
299; VC64-NEXT:    ret <2 x double> [[RETVAL]]
300;
301; NOLIB-LABEL: define <2 x double> @test_simplify3vn(
302; NOLIB-SAME: <2 x double> [[X:%.*]]) {
303; NOLIB-NEXT:    [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]])
304; NOLIB-NEXT:    ret <2 x double> [[RETVAL]]
305;
306  %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.0, double 4.0>, <2 x double> %x)
307  ret <2 x double> %retval
308}
309
310define double @test_simplify4(double %x) {
311; ANY-LABEL: define double @test_simplify4(
312; ANY-SAME: double [[X:%.*]]) {
313; ANY-NEXT:    [[EXP2:%.*]] = call double @exp2(double [[X]])
314; ANY-NEXT:    ret double [[EXP2]]
315;
316; VC32-LABEL: define double @test_simplify4(
317; VC32-SAME: double [[X:%.*]]) {
318; VC32-NEXT:    [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]])
319; VC32-NEXT:    ret double [[RETVAL]]
320;
321; VC19-LABEL: define double @test_simplify4(
322; VC19-SAME: double [[X:%.*]]) {
323; VC19-NEXT:    [[EXP2:%.*]] = call double @exp2(double [[X]])
324; VC19-NEXT:    ret double [[EXP2]]
325;
326; VC64-LABEL: define double @test_simplify4(
327; VC64-SAME: double [[X:%.*]]) {
328; VC64-NEXT:    [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]])
329; VC64-NEXT:    ret double [[RETVAL]]
330;
331; NOLIB-LABEL: define double @test_simplify4(
332; NOLIB-SAME: double [[X:%.*]]) {
333; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]])
334; NOLIB-NEXT:    ret double [[RETVAL]]
335;
336  %retval = call double @pow(double 2.0, double %x)
337  ret double %retval
338}
339
340define double @test_simplify4_noerrno(double %x) {
341; ANY-LABEL: define double @test_simplify4_noerrno(
342; ANY-SAME: double [[X:%.*]]) {
343; ANY-NEXT:    [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[X]])
344; ANY-NEXT:    ret double [[EXP2]]
345;
346; VC32-LABEL: define double @test_simplify4_noerrno(
347; VC32-SAME: double [[X:%.*]]) {
348; VC32-NEXT:    [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) #[[ATTR2]]
349; VC32-NEXT:    ret double [[RETVAL]]
350;
351; VC19-LABEL: define double @test_simplify4_noerrno(
352; VC19-SAME: double [[X:%.*]]) {
353; VC19-NEXT:    [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[X]])
354; VC19-NEXT:    ret double [[EXP2]]
355;
356; VC64-LABEL: define double @test_simplify4_noerrno(
357; VC64-SAME: double [[X:%.*]]) {
358; VC64-NEXT:    [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) #[[ATTR2]]
359; VC64-NEXT:    ret double [[RETVAL]]
360;
361; NOLIB-LABEL: define double @test_simplify4_noerrno(
362; NOLIB-SAME: double [[X:%.*]]) {
363; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) #[[ATTR2]]
364; NOLIB-NEXT:    ret double [[RETVAL]]
365;
366  %retval = call double @pow(double 2.0, double %x) #0
367  ret double %retval
368}
369
370define float @test_simplify4n(float %x) {
371; ANY-LABEL: define float @test_simplify4n(
372; ANY-SAME: float [[X:%.*]]) {
373; ANY-NEXT:    [[MUL:%.*]] = fmul float [[X]], 3.000000e+00
374; ANY-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[MUL]])
375; ANY-NEXT:    ret float [[EXP2F]]
376;
377; VC32-LABEL: define float @test_simplify4n(
378; VC32-SAME: float [[X:%.*]]) {
379; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]])
380; VC32-NEXT:    ret float [[RETVAL]]
381;
382; VC51-LABEL: define float @test_simplify4n(
383; VC51-SAME: float [[X:%.*]]) {
384; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]])
385; VC51-NEXT:    ret float [[RETVAL]]
386;
387; VC64-LABEL: define float @test_simplify4n(
388; VC64-SAME: float [[X:%.*]]) {
389; VC64-NEXT:    [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]])
390; VC64-NEXT:    ret float [[RETVAL]]
391;
392; VC83-LABEL: define float @test_simplify4n(
393; VC83-SAME: float [[X:%.*]]) {
394; VC83-NEXT:    [[MUL:%.*]] = fmul float [[X]], 3.000000e+00
395; VC83-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[MUL]])
396; VC83-NEXT:    ret float [[EXP2F]]
397;
398; NOLIB-LABEL: define float @test_simplify4n(
399; NOLIB-SAME: float [[X:%.*]]) {
400; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]])
401; NOLIB-NEXT:    ret float [[RETVAL]]
402;
403  %retval = call float @powf(float 8.0, float %x)
404  ret float %retval
405}
406
407define float @test_simplify4n_noerrno(float %x) {
408; ANY-LABEL: define float @test_simplify4n_noerrno(
409; ANY-SAME: float [[X:%.*]]) {
410; ANY-NEXT:    [[MUL:%.*]] = fmul float [[X]], 3.000000e+00
411; ANY-NEXT:    [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[MUL]])
412; ANY-NEXT:    ret float [[EXP2]]
413;
414; VC32-LABEL: define float @test_simplify4n_noerrno(
415; VC32-SAME: float [[X:%.*]]) {
416; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]]
417; VC32-NEXT:    ret float [[RETVAL]]
418;
419; VC51-LABEL: define float @test_simplify4n_noerrno(
420; VC51-SAME: float [[X:%.*]]) {
421; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]]
422; VC51-NEXT:    ret float [[RETVAL]]
423;
424; VC64-LABEL: define float @test_simplify4n_noerrno(
425; VC64-SAME: float [[X:%.*]]) {
426; VC64-NEXT:    [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]]
427; VC64-NEXT:    ret float [[RETVAL]]
428;
429; VC83-LABEL: define float @test_simplify4n_noerrno(
430; VC83-SAME: float [[X:%.*]]) {
431; VC83-NEXT:    [[MUL:%.*]] = fmul float [[X]], 3.000000e+00
432; VC83-NEXT:    [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[MUL]])
433; VC83-NEXT:    ret float [[EXP2]]
434;
435; NOLIB-LABEL: define float @test_simplify4n_noerrno(
436; NOLIB-SAME: float [[X:%.*]]) {
437; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]]
438; NOLIB-NEXT:    ret float [[RETVAL]]
439;
440  %retval = call float @powf(float 8.0, float %x) #0
441  ret float %retval
442}
443
444; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
445define <2 x double> @test_simplify4v(<2 x double> %x) {
446; ANY-LABEL: define <2 x double> @test_simplify4v(
447; ANY-SAME: <2 x double> [[X:%.*]]) {
448; ANY-NEXT:    [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X]])
449; ANY-NEXT:    ret <2 x double> [[EXP2]]
450;
451; VC32-LABEL: define <2 x double> @test_simplify4v(
452; VC32-SAME: <2 x double> [[X:%.*]]) {
453; VC32-NEXT:    [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]])
454; VC32-NEXT:    ret <2 x double> [[RETVAL]]
455;
456; VC19-LABEL: define <2 x double> @test_simplify4v(
457; VC19-SAME: <2 x double> [[X:%.*]]) {
458; VC19-NEXT:    [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]])
459; VC19-NEXT:    ret <2 x double> [[RETVAL]]
460;
461; VC64-LABEL: define <2 x double> @test_simplify4v(
462; VC64-SAME: <2 x double> [[X:%.*]]) {
463; VC64-NEXT:    [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]])
464; VC64-NEXT:    ret <2 x double> [[RETVAL]]
465;
466; NOLIB-LABEL: define <2 x double> @test_simplify4v(
467; NOLIB-SAME: <2 x double> [[X:%.*]]) {
468; NOLIB-NEXT:    [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]])
469; NOLIB-NEXT:    ret <2 x double> [[RETVAL]]
470;
471  %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.0, double 2.0>, <2 x double> %x)
472  ret <2 x double> %retval
473}
474
475; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
476define <2 x float> @test_simplify4vn(<2 x float> %x) {
477; ANY-LABEL: define <2 x float> @test_simplify4vn(
478; ANY-SAME: <2 x float> [[X:%.*]]) {
479; ANY-NEXT:    [[MUL:%.*]] = fneg <2 x float> [[X]]
480; ANY-NEXT:    [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]])
481; ANY-NEXT:    ret <2 x float> [[EXP2]]
482;
483; VC32-LABEL: define <2 x float> @test_simplify4vn(
484; VC32-SAME: <2 x float> [[X:%.*]]) {
485; VC32-NEXT:    [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]])
486; VC32-NEXT:    ret <2 x float> [[RETVAL]]
487;
488; VC19-LABEL: define <2 x float> @test_simplify4vn(
489; VC19-SAME: <2 x float> [[X:%.*]]) {
490; VC19-NEXT:    [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]])
491; VC19-NEXT:    ret <2 x float> [[RETVAL]]
492;
493; VC64-LABEL: define <2 x float> @test_simplify4vn(
494; VC64-SAME: <2 x float> [[X:%.*]]) {
495; VC64-NEXT:    [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]])
496; VC64-NEXT:    ret <2 x float> [[RETVAL]]
497;
498; NOLIB-LABEL: define <2 x float> @test_simplify4vn(
499; NOLIB-SAME: <2 x float> [[X:%.*]]) {
500; NOLIB-NEXT:    [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]])
501; NOLIB-NEXT:    ret <2 x float> [[RETVAL]]
502;
503  %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 0.5, float 0.5>, <2 x float> %x)
504  ret <2 x float> %retval
505}
506
507; Check pow(x, 0.0) -> 1.0.
508
509define float @test_simplify5(float %x) {
510; ANY-LABEL: define float @test_simplify5(
511; ANY-SAME: float [[X:%.*]]) {
512; ANY-NEXT:    ret float 1.000000e+00
513;
514; VC32-LABEL: define float @test_simplify5(
515; VC32-SAME: float [[X:%.*]]) {
516; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00)
517; VC32-NEXT:    ret float [[RETVAL]]
518;
519; VC51-LABEL: define float @test_simplify5(
520; VC51-SAME: float [[X:%.*]]) {
521; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00)
522; VC51-NEXT:    ret float [[RETVAL]]
523;
524; VC64-LABEL: define float @test_simplify5(
525; VC64-SAME: float [[X:%.*]]) {
526; VC64-NEXT:    ret float 1.000000e+00
527;
528; VC83-LABEL: define float @test_simplify5(
529; VC83-SAME: float [[X:%.*]]) {
530; VC83-NEXT:    ret float 1.000000e+00
531;
532; NOLIB-LABEL: define float @test_simplify5(
533; NOLIB-SAME: float [[X:%.*]]) {
534; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00)
535; NOLIB-NEXT:    ret float [[RETVAL]]
536;
537  %retval = call float @powf(float %x, float 0.0)
538  ret float %retval
539}
540
541define float @test_simplify5_noerrno(float %x) {
542; ANY-LABEL: define float @test_simplify5_noerrno(
543; ANY-SAME: float [[X:%.*]]) {
544; ANY-NEXT:    ret float 1.000000e+00
545;
546; VC32-LABEL: define float @test_simplify5_noerrno(
547; VC32-SAME: float [[X:%.*]]) {
548; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) #[[ATTR2]]
549; VC32-NEXT:    ret float [[RETVAL]]
550;
551; VC51-LABEL: define float @test_simplify5_noerrno(
552; VC51-SAME: float [[X:%.*]]) {
553; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) #[[ATTR2]]
554; VC51-NEXT:    ret float [[RETVAL]]
555;
556; VC64-LABEL: define float @test_simplify5_noerrno(
557; VC64-SAME: float [[X:%.*]]) {
558; VC64-NEXT:    ret float 1.000000e+00
559;
560; VC83-LABEL: define float @test_simplify5_noerrno(
561; VC83-SAME: float [[X:%.*]]) {
562; VC83-NEXT:    ret float 1.000000e+00
563;
564; NOLIB-LABEL: define float @test_simplify5_noerrno(
565; NOLIB-SAME: float [[X:%.*]]) {
566; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) #[[ATTR2]]
567; NOLIB-NEXT:    ret float [[RETVAL]]
568;
569  %retval = call float @powf(float %x, float 0.0) #0
570  ret float %retval
571}
572
573define <2 x float> @test_simplify5v(<2 x float> %x) {
574; CHECK-LABEL: define <2 x float> @test_simplify5v(
575; CHECK-SAME: <2 x float> [[X:%.*]]) {
576; CHECK-NEXT:    ret <2 x float> splat (float 1.000000e+00)
577;
578  %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 0.0, float 0.0>)
579  ret <2 x float> %retval
580}
581
582define double @test_simplify6(double %x) {
583; LIB-LABEL: define double @test_simplify6(
584; LIB-SAME: double [[X:%.*]]) {
585; LIB-NEXT:    ret double 1.000000e+00
586;
587; NOLIB-LABEL: define double @test_simplify6(
588; NOLIB-SAME: double [[X:%.*]]) {
589; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double [[X]], double 0.000000e+00)
590; NOLIB-NEXT:    ret double [[RETVAL]]
591;
592  %retval = call double @pow(double %x, double 0.0)
593  ret double %retval
594}
595
596define double @test_simplify6_noerrno(double %x) {
597; LIB-LABEL: define double @test_simplify6_noerrno(
598; LIB-SAME: double [[X:%.*]]) {
599; LIB-NEXT:    ret double 1.000000e+00
600;
601; NOLIB-LABEL: define double @test_simplify6_noerrno(
602; NOLIB-SAME: double [[X:%.*]]) {
603; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double [[X]], double 0.000000e+00) #[[ATTR2]]
604; NOLIB-NEXT:    ret double [[RETVAL]]
605;
606  %retval = call double @pow(double %x, double 0.0) #0
607  ret double %retval
608}
609
610define <2 x double> @test_simplify6v(<2 x double> %x) {
611; CHECK-LABEL: define <2 x double> @test_simplify6v(
612; CHECK-SAME: <2 x double> [[X:%.*]]) {
613; CHECK-NEXT:    ret <2 x double> splat (double 1.000000e+00)
614;
615  %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 0.0, double 0.0>)
616  ret <2 x double> %retval
617}
618
619; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity.
620
621define float @powf_libcall_half_ninf(float %x) {
622; ANY-LABEL: define float @powf_libcall_half_ninf(
623; ANY-SAME: float [[X:%.*]]) {
624; ANY-NEXT:    [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
625; ANY-NEXT:    [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]])
626; ANY-NEXT:    ret float [[ABS]]
627;
628; VC32-LABEL: define float @powf_libcall_half_ninf(
629; VC32-SAME: float [[X:%.*]]) {
630; VC32-NEXT:    [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01)
631; VC32-NEXT:    ret float [[RETVAL]]
632;
633; VC51-LABEL: define float @powf_libcall_half_ninf(
634; VC51-SAME: float [[X:%.*]]) {
635; VC51-NEXT:    [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01)
636; VC51-NEXT:    ret float [[RETVAL]]
637;
638; VC64-LABEL: define float @powf_libcall_half_ninf(
639; VC64-SAME: float [[X:%.*]]) {
640; VC64-NEXT:    [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
641; VC64-NEXT:    [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]])
642; VC64-NEXT:    ret float [[ABS]]
643;
644; VC83-LABEL: define float @powf_libcall_half_ninf(
645; VC83-SAME: float [[X:%.*]]) {
646; VC83-NEXT:    [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
647; VC83-NEXT:    [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]])
648; VC83-NEXT:    ret float [[ABS]]
649;
650; NOLIB-LABEL: define float @powf_libcall_half_ninf(
651; NOLIB-SAME: float [[X:%.*]]) {
652; NOLIB-NEXT:    [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01)
653; NOLIB-NEXT:    ret float [[RETVAL]]
654;
655  %retval = call ninf float @powf(float %x, float 0.5)
656  ret float %retval
657}
658
659define float @powf_libcall_half_ninf_noerrno(float %x) {
660; ANY-LABEL: define float @powf_libcall_half_ninf_noerrno(
661; ANY-SAME: float [[X:%.*]]) {
662; ANY-NEXT:    [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
663; ANY-NEXT:    [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRT]])
664; ANY-NEXT:    ret float [[ABS]]
665;
666; VC32-LABEL: define float @powf_libcall_half_ninf_noerrno(
667; VC32-SAME: float [[X:%.*]]) {
668; VC32-NEXT:    [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
669; VC32-NEXT:    ret float [[RETVAL]]
670;
671; VC51-LABEL: define float @powf_libcall_half_ninf_noerrno(
672; VC51-SAME: float [[X:%.*]]) {
673; VC51-NEXT:    [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
674; VC51-NEXT:    ret float [[RETVAL]]
675;
676; VC64-LABEL: define float @powf_libcall_half_ninf_noerrno(
677; VC64-SAME: float [[X:%.*]]) {
678; VC64-NEXT:    [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
679; VC64-NEXT:    [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRT]])
680; VC64-NEXT:    ret float [[ABS]]
681;
682; VC83-LABEL: define float @powf_libcall_half_ninf_noerrno(
683; VC83-SAME: float [[X:%.*]]) {
684; VC83-NEXT:    [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
685; VC83-NEXT:    [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRT]])
686; VC83-NEXT:    ret float [[ABS]]
687;
688; NOLIB-LABEL: define float @powf_libcall_half_ninf_noerrno(
689; NOLIB-SAME: float [[X:%.*]]) {
690; NOLIB-NEXT:    [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
691; NOLIB-NEXT:    ret float [[RETVAL]]
692;
693  %retval = call ninf float @powf(float %x, float 0.5) #0
694  ret float %retval
695}
696
697; Make sure assume works when inferring no infinities
698define float @powf_libcall_half_assume_ninf_noerrno(float %x) {
699; ANY-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
700; ANY-SAME: float [[X:%.*]]) {
701; ANY-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
702; ANY-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
703; ANY-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
704; ANY-NEXT:    [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[X]])
705; ANY-NEXT:    [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
706; ANY-NEXT:    ret float [[ABS]]
707;
708; VC32-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
709; VC32-SAME: float [[X:%.*]]) {
710; VC32-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
711; VC32-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
712; VC32-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
713; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
714; VC32-NEXT:    ret float [[RETVAL]]
715;
716; VC51-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
717; VC51-SAME: float [[X:%.*]]) {
718; VC51-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
719; VC51-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
720; VC51-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
721; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
722; VC51-NEXT:    ret float [[RETVAL]]
723;
724; VC64-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
725; VC64-SAME: float [[X:%.*]]) {
726; VC64-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
727; VC64-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
728; VC64-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
729; VC64-NEXT:    [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[X]])
730; VC64-NEXT:    [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
731; VC64-NEXT:    ret float [[ABS]]
732;
733; VC83-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
734; VC83-SAME: float [[X:%.*]]) {
735; VC83-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
736; VC83-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
737; VC83-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
738; VC83-NEXT:    [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[X]])
739; VC83-NEXT:    [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
740; VC83-NEXT:    ret float [[ABS]]
741;
742; NOLIB-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
743; NOLIB-SAME: float [[X:%.*]]) {
744; NOLIB-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
745; NOLIB-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
746; NOLIB-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
747; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
748; NOLIB-NEXT:    ret float [[RETVAL]]
749;
750  %fabs = call float @llvm.fabs.f32(float %x)
751  %not.inf = fcmp one float %fabs, 0x7FF0000000000000
752  call void @llvm.assume(i1 %not.inf)
753  %retval = call float @powf(float %x, float 0.5) #0
754  ret float %retval
755}
756
757define float @powf_libcall_half_ninf_tail(float %x) {
758; ANY-LABEL: define float @powf_libcall_half_ninf_tail(
759; ANY-SAME: float [[X:%.*]]) {
760; ANY-NEXT:    [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
761; ANY-NEXT:    [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRTF]])
762; ANY-NEXT:    ret float [[ABS]]
763;
764; VC32-LABEL: define float @powf_libcall_half_ninf_tail(
765; VC32-SAME: float [[X:%.*]]) {
766; VC32-NEXT:    [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01)
767; VC32-NEXT:    ret float [[RETVAL]]
768;
769; VC51-LABEL: define float @powf_libcall_half_ninf_tail(
770; VC51-SAME: float [[X:%.*]]) {
771; VC51-NEXT:    [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01)
772; VC51-NEXT:    ret float [[RETVAL]]
773;
774; VC64-LABEL: define float @powf_libcall_half_ninf_tail(
775; VC64-SAME: float [[X:%.*]]) {
776; VC64-NEXT:    [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
777; VC64-NEXT:    [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRTF]])
778; VC64-NEXT:    ret float [[ABS]]
779;
780; VC83-LABEL: define float @powf_libcall_half_ninf_tail(
781; VC83-SAME: float [[X:%.*]]) {
782; VC83-NEXT:    [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
783; VC83-NEXT:    [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRTF]])
784; VC83-NEXT:    ret float [[ABS]]
785;
786; NOLIB-LABEL: define float @powf_libcall_half_ninf_tail(
787; NOLIB-SAME: float [[X:%.*]]) {
788; NOLIB-NEXT:    [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01)
789; NOLIB-NEXT:    ret float [[RETVAL]]
790;
791  %retval = tail call ninf float @powf(float %x, float 0.5)
792  ret float %retval
793}
794
795define float @powf_libcall_half_ninf_tail_noerrno(float %x) {
796; ANY-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
797; ANY-SAME: float [[X:%.*]]) {
798; ANY-NEXT:    [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
799; ANY-NEXT:    [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRT]])
800; ANY-NEXT:    ret float [[ABS]]
801;
802; VC32-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
803; VC32-SAME: float [[X:%.*]]) {
804; VC32-NEXT:    [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
805; VC32-NEXT:    ret float [[RETVAL]]
806;
807; VC51-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
808; VC51-SAME: float [[X:%.*]]) {
809; VC51-NEXT:    [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
810; VC51-NEXT:    ret float [[RETVAL]]
811;
812; VC64-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
813; VC64-SAME: float [[X:%.*]]) {
814; VC64-NEXT:    [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
815; VC64-NEXT:    [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRT]])
816; VC64-NEXT:    ret float [[ABS]]
817;
818; VC83-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
819; VC83-SAME: float [[X:%.*]]) {
820; VC83-NEXT:    [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
821; VC83-NEXT:    [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRT]])
822; VC83-NEXT:    ret float [[ABS]]
823;
824; NOLIB-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
825; NOLIB-SAME: float [[X:%.*]]) {
826; NOLIB-NEXT:    [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
827; NOLIB-NEXT:    ret float [[RETVAL]]
828;
829  %retval = tail call ninf float @powf(float %x, float 0.5) #0
830  ret float %retval
831}
832
833define float @powf_libcall_half_ninf_musttail(float %x, float %y) {
834; CHECK-LABEL: define float @powf_libcall_half_ninf_musttail(
835; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
836; CHECK-NEXT:    [[RETVAL:%.*]] = musttail call ninf float @powf(float [[X]], float 5.000000e-01)
837; CHECK-NEXT:    ret float [[RETVAL]]
838;
839  %retval = musttail call ninf float @powf(float %x, float 0.5)
840  ret float %retval
841}
842
843define float @powf_libcall_half_ninf_musttail_noerrno(float %x, float %y) {
844; CHECK-LABEL: define float @powf_libcall_half_ninf_musttail_noerrno(
845; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
846; CHECK-NEXT:    [[RETVAL:%.*]] = musttail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2:[0-9]+]]
847; CHECK-NEXT:    ret float [[RETVAL]]
848;
849  %retval = musttail call ninf float @powf(float %x, float 0.5) #0
850  ret float %retval
851}
852
853; Check pow(x, 0.5) where x may be -infinity does not call a library sqrt function.
854
855define double @pow_libcall_half_no_FMF(double %x) {
856; CHECK-LABEL: define double @pow_libcall_half_no_FMF(
857; CHECK-SAME: double [[X:%.*]]) {
858; CHECK-NEXT:    [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01)
859; CHECK-NEXT:    ret double [[RETVAL]]
860;
861  %retval = call double @pow(double %x, double 0.5)
862  ret double %retval
863}
864
865define double @pow_libcall_half_fromdomcondition(double %x) {
866; LIB-LABEL: define double @pow_libcall_half_fromdomcondition(
867; LIB-SAME: double [[X:%.*]]) {
868; LIB-NEXT:    [[A:%.*]] = call double @llvm.fabs.f64(double [[X]])
869; LIB-NEXT:    [[C:%.*]] = fcmp oeq double [[A]], 0x7FF0000000000000
870; LIB-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
871; LIB:       then:
872; LIB-NEXT:    ret double 0.000000e+00
873; LIB:       else:
874; LIB-NEXT:    [[SQRT:%.*]] = call double @sqrt(double [[X]])
875; LIB-NEXT:    [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
876; LIB-NEXT:    ret double [[ABS]]
877;
878; NOLIB-LABEL: define double @pow_libcall_half_fromdomcondition(
879; NOLIB-SAME: double [[X:%.*]]) {
880; NOLIB-NEXT:    [[A:%.*]] = call double @llvm.fabs.f64(double [[X]])
881; NOLIB-NEXT:    [[C:%.*]] = fcmp oeq double [[A]], 0x7FF0000000000000
882; NOLIB-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
883; NOLIB:       then:
884; NOLIB-NEXT:    ret double 0.000000e+00
885; NOLIB:       else:
886; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01)
887; NOLIB-NEXT:    ret double [[RETVAL]]
888;
889  %a = call double @llvm.fabs.f64(double %x)
890  %c = fcmp oeq double %a, 0x7FF0000000000000
891  br i1 %c, label %then, label %else
892
893then:
894  ret double 0.0
895
896else:
897  %retval = call double @pow(double %x, double 0.5)
898  ret double %retval
899}
900
901define double @pow_libcall_half_no_FMF_noerrno(double %x) {
902; LIB-LABEL: define double @pow_libcall_half_no_FMF_noerrno(
903; LIB-SAME: double [[X:%.*]]) {
904; LIB-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X]])
905; LIB-NEXT:    [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
906; LIB-NEXT:    [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
907; LIB-NEXT:    [[RETVAL:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
908; LIB-NEXT:    ret double [[RETVAL]]
909;
910; NOLIB-LABEL: define double @pow_libcall_half_no_FMF_noerrno(
911; NOLIB-SAME: double [[X:%.*]]) {
912; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01) #[[ATTR2]]
913; NOLIB-NEXT:    ret double [[RETVAL]]
914;
915  %retval = call double @pow(double %x, double 0.5) #0
916  ret double %retval
917}
918
919; Check pow(-infinity, 0.5) -> +infinity.
920
921define float @test_simplify9(float %x) {
922; CHECK-LABEL: define float @test_simplify9(
923; CHECK-SAME: float [[X:%.*]]) {
924; CHECK-NEXT:    ret float 0x7FF0000000000000
925;
926  %retval = call float @llvm.pow.f32(float 0xFFF0000000000000, float 0.5)
927  ret float %retval
928}
929
930define double @test_simplify10(double %x) {
931; CHECK-LABEL: define double @test_simplify10(
932; CHECK-SAME: double [[X:%.*]]) {
933; CHECK-NEXT:    ret double 0x7FF0000000000000
934;
935  %retval = call double @llvm.pow.f64(double 0xFFF0000000000000, double 0.5)
936  ret double %retval
937}
938
939; Check pow(x, 1.0) -> x.
940
941define float @test_simplify11(float %x) {
942; ANY-LABEL: define float @test_simplify11(
943; ANY-SAME: float [[X:%.*]]) {
944; ANY-NEXT:    ret float [[X]]
945;
946; VC32-LABEL: define float @test_simplify11(
947; VC32-SAME: float [[X:%.*]]) {
948; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00)
949; VC32-NEXT:    ret float [[RETVAL]]
950;
951; VC51-LABEL: define float @test_simplify11(
952; VC51-SAME: float [[X:%.*]]) {
953; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00)
954; VC51-NEXT:    ret float [[RETVAL]]
955;
956; VC64-LABEL: define float @test_simplify11(
957; VC64-SAME: float [[X:%.*]]) {
958; VC64-NEXT:    ret float [[X]]
959;
960; VC83-LABEL: define float @test_simplify11(
961; VC83-SAME: float [[X:%.*]]) {
962; VC83-NEXT:    ret float [[X]]
963;
964; NOLIB-LABEL: define float @test_simplify11(
965; NOLIB-SAME: float [[X:%.*]]) {
966; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00)
967; NOLIB-NEXT:    ret float [[RETVAL]]
968;
969  %retval = call float @powf(float %x, float 1.0)
970  ret float %retval
971}
972
973define float @test_simplify11_noerrno(float %x) {
974; ANY-LABEL: define float @test_simplify11_noerrno(
975; ANY-SAME: float [[X:%.*]]) {
976; ANY-NEXT:    ret float [[X]]
977;
978; VC32-LABEL: define float @test_simplify11_noerrno(
979; VC32-SAME: float [[X:%.*]]) {
980; VC32-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]]
981; VC32-NEXT:    ret float [[RETVAL]]
982;
983; VC51-LABEL: define float @test_simplify11_noerrno(
984; VC51-SAME: float [[X:%.*]]) {
985; VC51-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]]
986; VC51-NEXT:    ret float [[RETVAL]]
987;
988; VC64-LABEL: define float @test_simplify11_noerrno(
989; VC64-SAME: float [[X:%.*]]) {
990; VC64-NEXT:    ret float [[X]]
991;
992; VC83-LABEL: define float @test_simplify11_noerrno(
993; VC83-SAME: float [[X:%.*]]) {
994; VC83-NEXT:    ret float [[X]]
995;
996; NOLIB-LABEL: define float @test_simplify11_noerrno(
997; NOLIB-SAME: float [[X:%.*]]) {
998; NOLIB-NEXT:    [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]]
999; NOLIB-NEXT:    ret float [[RETVAL]]
1000;
1001  %retval = call float @powf(float %x, float 1.0) #0
1002  ret float %retval
1003}
1004
1005define <2 x float> @test_simplify11v(<2 x float> %x) {
1006; CHECK-LABEL: define <2 x float> @test_simplify11v(
1007; CHECK-SAME: <2 x float> [[X:%.*]]) {
1008; CHECK-NEXT:    ret <2 x float> [[X]]
1009;
1010  %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>)
1011  ret <2 x float> %retval
1012}
1013
1014define double @test_simplify12(double %x) {
1015; LIB-LABEL: define double @test_simplify12(
1016; LIB-SAME: double [[X:%.*]]) {
1017; LIB-NEXT:    ret double [[X]]
1018;
1019; NOLIB-LABEL: define double @test_simplify12(
1020; NOLIB-SAME: double [[X:%.*]]) {
1021; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double [[X]], double 1.000000e+00)
1022; NOLIB-NEXT:    ret double [[RETVAL]]
1023;
1024  %retval = call double @pow(double %x, double 1.0)
1025  ret double %retval
1026}
1027
1028define double @test_simplify12_noerrno(double %x) {
1029; LIB-LABEL: define double @test_simplify12_noerrno(
1030; LIB-SAME: double [[X:%.*]]) {
1031; LIB-NEXT:    ret double [[X]]
1032;
1033; NOLIB-LABEL: define double @test_simplify12_noerrno(
1034; NOLIB-SAME: double [[X:%.*]]) {
1035; NOLIB-NEXT:    [[RETVAL:%.*]] = call double @pow(double [[X]], double 1.000000e+00) #[[ATTR2]]
1036; NOLIB-NEXT:    ret double [[RETVAL]]
1037;
1038  %retval = call double @pow(double %x, double 1.0) #0
1039  ret double %retval
1040}
1041
1042define <2 x double> @test_simplify12v(<2 x double> %x) {
1043; CHECK-LABEL: define <2 x double> @test_simplify12v(
1044; CHECK-SAME: <2 x double> [[X:%.*]]) {
1045; CHECK-NEXT:    ret <2 x double> [[X]]
1046;
1047  %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 1.0, double 1.0>)
1048  ret <2 x double> %retval
1049}
1050
1051; Check pow(x, 2.0) -> x*x.
1052
1053define float @pow2_strict(float %x) {
1054; ANY-LABEL: define float @pow2_strict(
1055; ANY-SAME: float [[X:%.*]]) {
1056; ANY-NEXT:    [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1057; ANY-NEXT:    ret float [[SQUARE]]
1058;
1059; VC32-LABEL: define float @pow2_strict(
1060; VC32-SAME: float [[X:%.*]]) {
1061; VC32-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00)
1062; VC32-NEXT:    ret float [[R]]
1063;
1064; VC51-LABEL: define float @pow2_strict(
1065; VC51-SAME: float [[X:%.*]]) {
1066; VC51-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00)
1067; VC51-NEXT:    ret float [[R]]
1068;
1069; VC64-LABEL: define float @pow2_strict(
1070; VC64-SAME: float [[X:%.*]]) {
1071; VC64-NEXT:    [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1072; VC64-NEXT:    ret float [[SQUARE]]
1073;
1074; VC83-LABEL: define float @pow2_strict(
1075; VC83-SAME: float [[X:%.*]]) {
1076; VC83-NEXT:    [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1077; VC83-NEXT:    ret float [[SQUARE]]
1078;
1079; NOLIB-LABEL: define float @pow2_strict(
1080; NOLIB-SAME: float [[X:%.*]]) {
1081; NOLIB-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00)
1082; NOLIB-NEXT:    ret float [[R]]
1083;
1084  %r = call float @powf(float %x, float 2.0)
1085  ret float %r
1086}
1087
1088define float @pow2_strict_noerrno(float %x) {
1089; ANY-LABEL: define float @pow2_strict_noerrno(
1090; ANY-SAME: float [[X:%.*]]) {
1091; ANY-NEXT:    [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1092; ANY-NEXT:    ret float [[SQUARE]]
1093;
1094; VC32-LABEL: define float @pow2_strict_noerrno(
1095; VC32-SAME: float [[X:%.*]]) {
1096; VC32-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1097; VC32-NEXT:    ret float [[R]]
1098;
1099; VC51-LABEL: define float @pow2_strict_noerrno(
1100; VC51-SAME: float [[X:%.*]]) {
1101; VC51-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1102; VC51-NEXT:    ret float [[R]]
1103;
1104; VC64-LABEL: define float @pow2_strict_noerrno(
1105; VC64-SAME: float [[X:%.*]]) {
1106; VC64-NEXT:    [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1107; VC64-NEXT:    ret float [[SQUARE]]
1108;
1109; VC83-LABEL: define float @pow2_strict_noerrno(
1110; VC83-SAME: float [[X:%.*]]) {
1111; VC83-NEXT:    [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1112; VC83-NEXT:    ret float [[SQUARE]]
1113;
1114; NOLIB-LABEL: define float @pow2_strict_noerrno(
1115; NOLIB-SAME: float [[X:%.*]]) {
1116; NOLIB-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1117; NOLIB-NEXT:    ret float [[R]]
1118;
1119  %r = call float @powf(float %x, float 2.0) #0
1120  ret float %r
1121}
1122
1123define <2 x float> @pow2_strictv(<2 x float> %x) {
1124; CHECK-LABEL: define <2 x float> @pow2_strictv(
1125; CHECK-SAME: <2 x float> [[X:%.*]]) {
1126; CHECK-NEXT:    [[SQUARE:%.*]] = fmul <2 x float> [[X]], [[X]]
1127; CHECK-NEXT:    ret <2 x float> [[SQUARE]]
1128;
1129  %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 2.0, float 2.0>)
1130  ret <2 x float> %r
1131}
1132
1133define double @pow2_double_strict(double %x) {
1134; LIB-LABEL: define double @pow2_double_strict(
1135; LIB-SAME: double [[X:%.*]]) {
1136; LIB-NEXT:    [[SQUARE:%.*]] = fmul double [[X]], [[X]]
1137; LIB-NEXT:    ret double [[SQUARE]]
1138;
1139; NOLIB-LABEL: define double @pow2_double_strict(
1140; NOLIB-SAME: double [[X:%.*]]) {
1141; NOLIB-NEXT:    [[R:%.*]] = call double @pow(double [[X]], double 2.000000e+00)
1142; NOLIB-NEXT:    ret double [[R]]
1143;
1144  %r = call double @pow(double %x, double 2.0)
1145  ret double %r
1146}
1147
1148define double @pow2_double_strict_noerrno(double %x) {
1149; LIB-LABEL: define double @pow2_double_strict_noerrno(
1150; LIB-SAME: double [[X:%.*]]) {
1151; LIB-NEXT:    [[SQUARE:%.*]] = fmul double [[X]], [[X]]
1152; LIB-NEXT:    ret double [[SQUARE]]
1153;
1154; NOLIB-LABEL: define double @pow2_double_strict_noerrno(
1155; NOLIB-SAME: double [[X:%.*]]) {
1156; NOLIB-NEXT:    [[R:%.*]] = call double @pow(double [[X]], double 2.000000e+00) #[[ATTR2]]
1157; NOLIB-NEXT:    ret double [[R]]
1158;
1159  %r = call double @pow(double %x, double 2.0) #0
1160  ret double %r
1161}
1162
1163define <2 x double> @pow2_double_strictv(<2 x double> %x) {
1164; CHECK-LABEL: define <2 x double> @pow2_double_strictv(
1165; CHECK-SAME: <2 x double> [[X:%.*]]) {
1166; CHECK-NEXT:    [[SQUARE:%.*]] = fmul <2 x double> [[X]], [[X]]
1167; CHECK-NEXT:    ret <2 x double> [[SQUARE]]
1168;
1169  %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.0, double 2.0>)
1170  ret <2 x double> %r
1171}
1172
1173; Don't drop the FMF - PR35601 ( https://bugs.llvm.org/show_bug.cgi?id=35601 )
1174
1175define float @pow2_fast(float %x) {
1176; ANY-LABEL: define float @pow2_fast(
1177; ANY-SAME: float [[X:%.*]]) {
1178; ANY-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1179; ANY-NEXT:    ret float [[SQUARE]]
1180;
1181; VC32-LABEL: define float @pow2_fast(
1182; VC32-SAME: float [[X:%.*]]) {
1183; VC32-NEXT:    [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00)
1184; VC32-NEXT:    ret float [[R]]
1185;
1186; VC51-LABEL: define float @pow2_fast(
1187; VC51-SAME: float [[X:%.*]]) {
1188; VC51-NEXT:    [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00)
1189; VC51-NEXT:    ret float [[R]]
1190;
1191; VC64-LABEL: define float @pow2_fast(
1192; VC64-SAME: float [[X:%.*]]) {
1193; VC64-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1194; VC64-NEXT:    ret float [[SQUARE]]
1195;
1196; VC83-LABEL: define float @pow2_fast(
1197; VC83-SAME: float [[X:%.*]]) {
1198; VC83-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1199; VC83-NEXT:    ret float [[SQUARE]]
1200;
1201; NOLIB-LABEL: define float @pow2_fast(
1202; NOLIB-SAME: float [[X:%.*]]) {
1203; NOLIB-NEXT:    [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00)
1204; NOLIB-NEXT:    ret float [[R]]
1205;
1206  %r = call fast float @powf(float %x, float 2.0)
1207  ret float %r
1208}
1209
1210define float @pow2_fast_noerrno(float %x) {
1211; ANY-LABEL: define float @pow2_fast_noerrno(
1212; ANY-SAME: float [[X:%.*]]) {
1213; ANY-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1214; ANY-NEXT:    ret float [[SQUARE]]
1215;
1216; VC32-LABEL: define float @pow2_fast_noerrno(
1217; VC32-SAME: float [[X:%.*]]) {
1218; VC32-NEXT:    [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1219; VC32-NEXT:    ret float [[R]]
1220;
1221; VC51-LABEL: define float @pow2_fast_noerrno(
1222; VC51-SAME: float [[X:%.*]]) {
1223; VC51-NEXT:    [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1224; VC51-NEXT:    ret float [[R]]
1225;
1226; VC64-LABEL: define float @pow2_fast_noerrno(
1227; VC64-SAME: float [[X:%.*]]) {
1228; VC64-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1229; VC64-NEXT:    ret float [[SQUARE]]
1230;
1231; VC83-LABEL: define float @pow2_fast_noerrno(
1232; VC83-SAME: float [[X:%.*]]) {
1233; VC83-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1234; VC83-NEXT:    ret float [[SQUARE]]
1235;
1236; NOLIB-LABEL: define float @pow2_fast_noerrno(
1237; NOLIB-SAME: float [[X:%.*]]) {
1238; NOLIB-NEXT:    [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1239; NOLIB-NEXT:    ret float [[R]]
1240;
1241  %r = call fast float @powf(float %x, float 2.0) #0
1242  ret float %r
1243}
1244
1245; Check pow(x, -1.0) -> 1.0/x.
1246
1247define float @pow_neg1_strict(float %x) {
1248; ANY-LABEL: define float @pow_neg1_strict(
1249; ANY-SAME: float [[X:%.*]]) {
1250; ANY-NEXT:    [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1251; ANY-NEXT:    ret float [[RECIPROCAL]]
1252;
1253; VC32-LABEL: define float @pow_neg1_strict(
1254; VC32-SAME: float [[X:%.*]]) {
1255; VC32-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00)
1256; VC32-NEXT:    ret float [[R]]
1257;
1258; VC51-LABEL: define float @pow_neg1_strict(
1259; VC51-SAME: float [[X:%.*]]) {
1260; VC51-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00)
1261; VC51-NEXT:    ret float [[R]]
1262;
1263; VC64-LABEL: define float @pow_neg1_strict(
1264; VC64-SAME: float [[X:%.*]]) {
1265; VC64-NEXT:    [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1266; VC64-NEXT:    ret float [[RECIPROCAL]]
1267;
1268; VC83-LABEL: define float @pow_neg1_strict(
1269; VC83-SAME: float [[X:%.*]]) {
1270; VC83-NEXT:    [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1271; VC83-NEXT:    ret float [[RECIPROCAL]]
1272;
1273; NOLIB-LABEL: define float @pow_neg1_strict(
1274; NOLIB-SAME: float [[X:%.*]]) {
1275; NOLIB-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00)
1276; NOLIB-NEXT:    ret float [[R]]
1277;
1278  %r = call float @powf(float %x, float -1.0)
1279  ret float %r
1280}
1281
1282define float @pow_neg1_strict_noerrno(float %x) {
1283; ANY-LABEL: define float @pow_neg1_strict_noerrno(
1284; ANY-SAME: float [[X:%.*]]) {
1285; ANY-NEXT:    [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1286; ANY-NEXT:    ret float [[RECIPROCAL]]
1287;
1288; VC32-LABEL: define float @pow_neg1_strict_noerrno(
1289; VC32-SAME: float [[X:%.*]]) {
1290; VC32-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]]
1291; VC32-NEXT:    ret float [[R]]
1292;
1293; VC51-LABEL: define float @pow_neg1_strict_noerrno(
1294; VC51-SAME: float [[X:%.*]]) {
1295; VC51-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]]
1296; VC51-NEXT:    ret float [[R]]
1297;
1298; VC64-LABEL: define float @pow_neg1_strict_noerrno(
1299; VC64-SAME: float [[X:%.*]]) {
1300; VC64-NEXT:    [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1301; VC64-NEXT:    ret float [[RECIPROCAL]]
1302;
1303; VC83-LABEL: define float @pow_neg1_strict_noerrno(
1304; VC83-SAME: float [[X:%.*]]) {
1305; VC83-NEXT:    [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1306; VC83-NEXT:    ret float [[RECIPROCAL]]
1307;
1308; NOLIB-LABEL: define float @pow_neg1_strict_noerrno(
1309; NOLIB-SAME: float [[X:%.*]]) {
1310; NOLIB-NEXT:    [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]]
1311; NOLIB-NEXT:    ret float [[R]]
1312;
1313  %r = call float @powf(float %x, float -1.0) #0
1314  ret float %r
1315}
1316
1317define <2 x float> @pow_neg1_strictv(<2 x float> %x) {
1318; CHECK-LABEL: define <2 x float> @pow_neg1_strictv(
1319; CHECK-SAME: <2 x float> [[X:%.*]]) {
1320; CHECK-NEXT:    [[RECIPROCAL:%.*]] = fdiv <2 x float> splat (float 1.000000e+00), [[X]]
1321; CHECK-NEXT:    ret <2 x float> [[RECIPROCAL]]
1322;
1323  %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float -1.0, float -1.0>)
1324  ret <2 x float> %r
1325}
1326
1327define double @pow_neg1_double_fast(double %x) {
1328; LIB-LABEL: define double @pow_neg1_double_fast(
1329; LIB-SAME: double [[X:%.*]]) {
1330; LIB-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X]]
1331; LIB-NEXT:    ret double [[RECIPROCAL]]
1332;
1333; NOLIB-LABEL: define double @pow_neg1_double_fast(
1334; NOLIB-SAME: double [[X:%.*]]) {
1335; NOLIB-NEXT:    [[R:%.*]] = call fast double @pow(double [[X]], double -1.000000e+00)
1336; NOLIB-NEXT:    ret double [[R]]
1337;
1338  %r = call fast double @pow(double %x, double -1.0)
1339  ret double %r
1340}
1341
1342define double @pow_neg1_double_fast_noerrno(double %x) {
1343; LIB-LABEL: define double @pow_neg1_double_fast_noerrno(
1344; LIB-SAME: double [[X:%.*]]) {
1345; LIB-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X]]
1346; LIB-NEXT:    ret double [[RECIPROCAL]]
1347;
1348; NOLIB-LABEL: define double @pow_neg1_double_fast_noerrno(
1349; NOLIB-SAME: double [[X:%.*]]) {
1350; NOLIB-NEXT:    [[R:%.*]] = call fast double @pow(double [[X]], double -1.000000e+00) #[[ATTR2]]
1351; NOLIB-NEXT:    ret double [[R]]
1352;
1353  %r = call fast double @pow(double %x, double -1.0) #0
1354  ret double %r
1355}
1356
1357define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) {
1358; CHECK-LABEL: define <2 x double> @pow_neg1_double_fastv(
1359; CHECK-SAME: <2 x double> [[X:%.*]]) {
1360; CHECK-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast <2 x double> splat (double 1.000000e+00), [[X]]
1361; CHECK-NEXT:    ret <2 x double> [[RECIPROCAL]]
1362;
1363  %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -1.0, double -1.0>)
1364  ret <2 x double> %r
1365}
1366
1367define double @pow_intrinsic_half_no_FMF(double %x) {
1368; CHECK-LABEL: define double @pow_intrinsic_half_no_FMF(
1369; CHECK-SAME: double [[X:%.*]]) {
1370; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X]])
1371; CHECK-NEXT:    [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
1372; CHECK-NEXT:    [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
1373; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
1374; CHECK-NEXT:    ret double [[RETVAL]]
1375;
1376  %retval = call double @llvm.pow.f64(double %x, double 0.5)
1377  ret double %retval
1378}
1379
1380; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+.
1381
1382define float @test_simplify18(float %x) {
1383; CHECK-EXP10-LABEL: define float @test_simplify18(
1384; CHECK-EXP10-SAME: float [[X:%.*]]) {
1385; CHECK-EXP10-NEXT:    [[__EXP10F:%.*]] = call float @__exp10f(float [[X]])
1386; CHECK-EXP10-NEXT:    ret float [[__EXP10F]]
1387;
1388; CHECK-NO-EXP10-LABEL: define float @test_simplify18(
1389; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1390; CHECK-NO-EXP10-NEXT:    [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]])
1391; CHECK-NO-EXP10-NEXT:    ret float [[RETVAL]]
1392;
1393  %retval = call float @powf(float 10.0, float %x)
1394  ret float %retval
1395}
1396
1397define float @test_simplify18_noerrno(float %x) {
1398; CHECK-EXP10-LABEL: define float @test_simplify18_noerrno(
1399; CHECK-EXP10-SAME: float [[X:%.*]]) {
1400; CHECK-EXP10-NEXT:    [[EXP10:%.*]] = call float @llvm.exp10.f32(float [[X]])
1401; CHECK-EXP10-NEXT:    ret float [[EXP10]]
1402;
1403; CHECK-NO-EXP10-LABEL: define float @test_simplify18_noerrno(
1404; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1405; CHECK-NO-EXP10-NEXT:    [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) #[[ATTR2]]
1406; CHECK-NO-EXP10-NEXT:    ret float [[RETVAL]]
1407;
1408  %retval = call float @powf(float 10.0, float %x) #0
1409  ret float %retval
1410}
1411
1412define double @test_simplify19(double %x) {
1413; CHECK-EXP10-LABEL: define double @test_simplify19(
1414; CHECK-EXP10-SAME: double [[X:%.*]]) {
1415; CHECK-EXP10-NEXT:    [[__EXP10:%.*]] = call double @__exp10(double [[X]])
1416; CHECK-EXP10-NEXT:    ret double [[__EXP10]]
1417;
1418; CHECK-NO-EXP10-LABEL: define double @test_simplify19(
1419; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1420; CHECK-NO-EXP10-NEXT:    [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]])
1421; CHECK-NO-EXP10-NEXT:    ret double [[RETVAL]]
1422;
1423  %retval = call double @pow(double 10.0, double %x)
1424  ret double %retval
1425}
1426
1427define double @test_simplify19_noerrno(double %x) {
1428; CHECK-EXP10-LABEL: define double @test_simplify19_noerrno(
1429; CHECK-EXP10-SAME: double [[X:%.*]]) {
1430; CHECK-EXP10-NEXT:    [[EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]])
1431; CHECK-EXP10-NEXT:    ret double [[EXP10]]
1432;
1433; CHECK-NO-EXP10-LABEL: define double @test_simplify19_noerrno(
1434; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1435; CHECK-NO-EXP10-NEXT:    [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) #[[ATTR2]]
1436; CHECK-NO-EXP10-NEXT:    ret double [[RETVAL]]
1437;
1438  %retval = call double @pow(double 10.0, double %x) #0
1439  ret double %retval
1440}
1441
1442define float @test_libcall_powf_10_f32_noerrno(float %x) {
1443; CHECK-EXP10-LABEL: define float @test_libcall_powf_10_f32_noerrno(
1444; CHECK-EXP10-SAME: float [[X:%.*]]) {
1445; CHECK-EXP10-NEXT:    [[__EXP10F:%.*]] = call float @llvm.exp10.f32(float [[X]])
1446; CHECK-EXP10-NEXT:    ret float [[__EXP10F]]
1447;
1448; CHECK-NO-EXP10-LABEL: define float @test_libcall_powf_10_f32_noerrno(
1449; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1450; CHECK-NO-EXP10-NEXT:    [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) #[[ATTR2]]
1451; CHECK-NO-EXP10-NEXT:    ret float [[RETVAL]]
1452;
1453  %retval = call float @powf(float 10.0, float %x) #0
1454  ret float %retval
1455}
1456
1457define double @test_libcall_pow_10_f64_noerrno(double %x) {
1458; CHECK-EXP10-LABEL: define double @test_libcall_pow_10_f64_noerrno(
1459; CHECK-EXP10-SAME: double [[X:%.*]]) {
1460; CHECK-EXP10-NEXT:    [[__EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]])
1461; CHECK-EXP10-NEXT:    ret double [[__EXP10]]
1462;
1463; CHECK-NO-EXP10-LABEL: define double @test_libcall_pow_10_f64_noerrno(
1464; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1465; CHECK-NO-EXP10-NEXT:    [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) #[[ATTR2]]
1466; CHECK-NO-EXP10-NEXT:    ret double [[RETVAL]]
1467;
1468  %retval = call double @pow(double 10.0, double %x) #0
1469  ret double %retval
1470}
1471
1472define half @test_pow_10_f16(half %x) {
1473; CHECK-LABEL: define half @test_pow_10_f16(
1474; CHECK-SAME: half [[X:%.*]]) {
1475; CHECK-NEXT:    [[RETVAL:%.*]] = call half @llvm.pow.f16(half 0xH4900, half [[X]])
1476; CHECK-NEXT:    ret half [[RETVAL]]
1477;
1478  %retval = call half @llvm.pow.f16(half 10.0, half %x)
1479  ret half %retval
1480}
1481
1482define float @test_pow_10_f32(float %x) {
1483; CHECK-EXP10-LABEL: define float @test_pow_10_f32(
1484; CHECK-EXP10-SAME: float [[X:%.*]]) {
1485; CHECK-EXP10-NEXT:    [[__EXP10F:%.*]] = call float @llvm.exp10.f32(float [[X]])
1486; CHECK-EXP10-NEXT:    ret float [[__EXP10F]]
1487;
1488; CHECK-NO-EXP10-LABEL: define float @test_pow_10_f32(
1489; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1490; CHECK-NO-EXP10-NEXT:    [[RETVAL:%.*]] = call float @llvm.pow.f32(float 1.000000e+01, float [[X]])
1491; CHECK-NO-EXP10-NEXT:    ret float [[RETVAL]]
1492;
1493  %retval = call float @llvm.pow.f32(float 10.0, float %x)
1494  ret float %retval
1495}
1496
1497define double @test_pow_10_f64(double %x) {
1498; CHECK-EXP10-LABEL: define double @test_pow_10_f64(
1499; CHECK-EXP10-SAME: double [[X:%.*]]) {
1500; CHECK-EXP10-NEXT:    [[__EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]])
1501; CHECK-EXP10-NEXT:    ret double [[__EXP10]]
1502;
1503; CHECK-NO-EXP10-LABEL: define double @test_pow_10_f64(
1504; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1505; CHECK-NO-EXP10-NEXT:    [[RETVAL:%.*]] = call double @llvm.pow.f64(double 1.000000e+01, double [[X]])
1506; CHECK-NO-EXP10-NEXT:    ret double [[RETVAL]]
1507;
1508  %retval = call double @llvm.pow.f64(double 10.0, double %x)
1509  ret double %retval
1510}
1511
1512define fp128 @test_pow_10_fp128(fp128 %x) {
1513; CHECK-LABEL: define fp128 @test_pow_10_fp128(
1514; CHECK-SAME: fp128 [[X:%.*]]) {
1515; CHECK-NEXT:    [[RETVAL:%.*]] = call fp128 @llvm.pow.f128(fp128 0xL00000000000000004002400000000000, fp128 [[X]])
1516; CHECK-NEXT:    ret fp128 [[RETVAL]]
1517;
1518  %ten = fpext double 10.0 to fp128
1519  %retval = call fp128 @llvm.pow.fp128(fp128 %ten, fp128 %x)
1520  ret fp128 %retval
1521}
1522
1523define bfloat @test_pow_10_bf16(bfloat %x) {
1524; CHECK-LABEL: define bfloat @test_pow_10_bf16(
1525; CHECK-SAME: bfloat [[X:%.*]]) {
1526; CHECK-NEXT:    [[RETVAL:%.*]] = call bfloat @llvm.pow.bf16(bfloat 0xR4120, bfloat [[X]])
1527; CHECK-NEXT:    ret bfloat [[RETVAL]]
1528;
1529  %retval = call bfloat @llvm.pow.bf16(bfloat 10.0, bfloat %x)
1530  ret bfloat %retval
1531}
1532
1533define <2 x half> @test_pow_10_v2f16(<2 x half> %x) {
1534; CHECK-LABEL: define <2 x half> @test_pow_10_v2f16(
1535; CHECK-SAME: <2 x half> [[X:%.*]]) {
1536; CHECK-NEXT:    [[RETVAL:%.*]] = call <2 x half> @llvm.pow.v2f16(<2 x half> splat (half 0xH4900), <2 x half> [[X]])
1537; CHECK-NEXT:    ret <2 x half> [[RETVAL]]
1538;
1539  %retval = call <2 x half> @llvm.pow.v2f16(<2 x half> <half 10.0, half 10.0>, <2 x half> %x)
1540  ret <2 x half> %retval
1541}
1542
1543define <2 x float> @test_pow_10_v2f32(<2 x float> %x) {
1544; CHECK-LABEL: define <2 x float> @test_pow_10_v2f32(
1545; CHECK-SAME: <2 x float> [[X:%.*]]) {
1546; CHECK-NEXT:    [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 1.000000e+01), <2 x float> [[X]])
1547; CHECK-NEXT:    ret <2 x float> [[RETVAL]]
1548;
1549  %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 10.0, float 10.0>, <2 x float> %x)
1550  ret <2 x float> %retval
1551}
1552
1553define <2 x double> @test_pow_10_v2f64(<2 x double> %x) {
1554; CHECK-LABEL: define <2 x double> @test_pow_10_v2f64(
1555; CHECK-SAME: <2 x double> [[X:%.*]]) {
1556; CHECK-NEXT:    [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 1.000000e+01), <2 x double> [[X]])
1557; CHECK-NEXT:    ret <2 x double> [[RETVAL]]
1558;
1559  %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 10.0, double 10.0>, <2 x double> %x)
1560  ret <2 x double> %retval
1561}
1562
1563define <2 x bfloat> @test_pow_10_v2bf16(<2 x bfloat> %x) {
1564; CHECK-LABEL: define <2 x bfloat> @test_pow_10_v2bf16(
1565; CHECK-SAME: <2 x bfloat> [[X:%.*]]) {
1566; CHECK-NEXT:    [[RETVAL:%.*]] = call <2 x bfloat> @llvm.pow.v2bf16(<2 x bfloat> splat (bfloat 0xR4120), <2 x bfloat> [[X]])
1567; CHECK-NEXT:    ret <2 x bfloat> [[RETVAL]]
1568;
1569  %retval = call <2 x bfloat> @llvm.pow.v2bf16(<2 x bfloat> <bfloat 10.0, bfloat 10.0>, <2 x bfloat> %x)
1570  ret <2 x bfloat> %retval
1571}
1572
1573attributes #0 = { nounwind memory(none) }
1574