1574 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; Test that the pow library call simplifier works correctly.3;4; RUN: opt -passes=instcombine -S < %s | FileCheck %s --check-prefixes=CHECK,LIB,ANY5; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP106; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP107; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP108; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP109; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP1010; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-tvos9.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP1011; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-watchos2.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP1012; rdar://725183213; RUN: opt -passes=instcombine -S < %s -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC3214; RUN: opt -passes=instcombine -S < %s -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC19,VC5115; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC6416; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC19,VC8317; RUN: opt -passes=instcombine -S < %s -mtriple=amdgcn-- | FileCheck %s --check-prefixes=CHECK,CHECK-NO-EXP10,NOLIB18 19; NOTE: The readonly attribute on the pow call should be preserved20; 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 readonly28declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) nounwind readonly29declare 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+0037;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+0051;52; VC83-LABEL: define float @test_simplify1(53; VC83-SAME: float [[X:%.*]]) {54; VC83-NEXT: ret float 1.000000e+0055;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 %retval63}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+0069;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+0083;84; VC83-LABEL: define float @test_simplify1_noerrno(85; VC83-SAME: float [[X:%.*]]) {86; VC83-NEXT: ret float 1.000000e+0087;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) #094 ret float %retval95}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> %retval104}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+00110;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 %retval118}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+00124;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) #0131 ret double %retval132}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> %retval141}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 %retval178}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) #0212 ret float %retval213}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+00219; 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+00230; 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) #0244 ret double %retval245}246 247; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls248define <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> %retval276}277 278; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls279define <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> %retval308}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 %retval338}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) #0367 ret double %retval368}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+00374; 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+00395; 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 %retval405}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+00411; 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+00432; 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) #0441 ret float %retval442}443 444; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls445define <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> %retval473}474 475; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls476define <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> %retval505}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+00513;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+00527;528; VC83-LABEL: define float @test_simplify5(529; VC83-SAME: float [[X:%.*]]) {530; VC83-NEXT: ret float 1.000000e+00531;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 %retval539}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+00545;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+00559;560; VC83-LABEL: define float @test_simplify5_noerrno(561; VC83-SAME: float [[X:%.*]]) {562; VC83-NEXT: ret float 1.000000e+00563;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) #0570 ret float %retval571}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> %retval580}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+00586;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 %retval594}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+00600;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) #0607 ret double %retval608}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> %retval617}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 %retval657}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) #0694 ret float %retval695}696 697; Make sure assume works when inferring no infinities698define 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]], 0x7FF0000000000000703; 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]], 0x7FF0000000000000712; 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]], 0x7FF0000000000000720; 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]], 0x7FF0000000000000728; 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]], 0x7FF0000000000000737; 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]], 0x7FF0000000000000746; 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, 0x7FF0000000000000752 call void @llvm.assume(i1 %not.inf)753 %retval = call float @powf(float %x, float 0.5) #0754 ret float %retval755}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 %retval793}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) #0830 ret float %retval831}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 %retval841}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) #0850 ret float %retval851}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 %retval863}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]], 0x7FF0000000000000870; LIB-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]871; LIB: then:872; LIB-NEXT: ret double 0.000000e+00873; 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]], 0x7FF0000000000000882; NOLIB-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]883; NOLIB: then:884; NOLIB-NEXT: ret double 0.000000e+00885; 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, 0x7FF0000000000000891 br i1 %c, label %then, label %else892 893then:894 ret double 0.0895 896else:897 %retval = call double @pow(double %x, double 0.5)898 ret double %retval899}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]], 0xFFF0000000000000907; 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) #0916 ret double %retval917}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 0x7FF0000000000000925;926 %retval = call float @llvm.pow.f32(float 0xFFF0000000000000, float 0.5)927 ret float %retval928}929 930define double @test_simplify10(double %x) {931; CHECK-LABEL: define double @test_simplify10(932; CHECK-SAME: double [[X:%.*]]) {933; CHECK-NEXT: ret double 0x7FF0000000000000934;935 %retval = call double @llvm.pow.f64(double 0xFFF0000000000000, double 0.5)936 ret double %retval937}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 %retval971}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) #01002 ret float %retval1003}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> %retval1012}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 %retval1026}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) #01039 ret double %retval1040}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> %retval1049}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 %r1086}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) #01120 ret float %r1121}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> %r1131}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 %r1146}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) #01160 ret double %r1161}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> %r1171}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 %r1208}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) #01242 ret float %r1243}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 %r1280}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) #01314 ret float %r1315}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> %r1325}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 %r1340}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) #01354 ret double %r1355}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> %r1365}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]], 0xFFF00000000000001373; 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 %retval1378}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 %retval1395}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) #01409 ret float %retval1410}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 %retval1425}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) #01439 ret double %retval1440}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) #01454 ret float %retval1455}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) #01469 ret double %retval1470}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 %retval1480}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 %retval1495}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 %retval1510}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 fp1281519 %retval = call fp128 @llvm.pow.fp128(fp128 %ten, fp128 %x)1520 ret fp128 %retval1521}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 %retval1531}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> %retval1541}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> %retval1551}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> %retval1561}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> %retval1571}1572 1573attributes #0 = { nounwind memory(none) }1574