1; Test that the pow library call simplifier works correctly. 2; 3; RUN: opt < %s -instcombine -S | FileCheck %s 4; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefix=CHECK-EXP10 5; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefix=CHECK-EXP10 6; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefix=CHECK-NO-EXP10 7; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefix=CHECK-NO-EXP10 8; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefix=CHECK-NO-EXP10 9; rdar://7251832 10 11; NOTE: The readonly attribute on the pow call should be preserved 12; in the cases below where pow is transformed into another function call. 13 14declare float @powf(float, float) nounwind readonly 15declare double @pow(double, double) nounwind readonly 16 17; Check pow(1.0, x) -> 1.0. 18 19define float @test_simplify1(float %x) { 20; CHECK-LABEL: @test_simplify1( 21 %retval = call float @powf(float 1.0, float %x) 22 ret float %retval 23; CHECK-NEXT: ret float 1.000000e+00 24} 25 26define double @test_simplify2(double %x) { 27; CHECK-LABEL: @test_simplify2( 28 %retval = call double @pow(double 1.0, double %x) 29 ret double %retval 30; CHECK-NEXT: ret double 1.000000e+00 31} 32 33; Check pow(2.0, x) -> exp2(x). 34 35define float @test_simplify3(float %x) { 36; CHECK-LABEL: @test_simplify3( 37 %retval = call float @powf(float 2.0, float %x) 38; CHECK-NEXT: [[EXP2F:%[a-z0-9]+]] = call float @exp2f(float %x) [[NUW_RO:#[0-9]+]] 39 ret float %retval 40; CHECK-NEXT: ret float [[EXP2F]] 41} 42 43define double @test_simplify4(double %x) { 44; CHECK-LABEL: @test_simplify4( 45 %retval = call double @pow(double 2.0, double %x) 46; CHECK-NEXT: [[EXP2:%[a-z0-9]+]] = call double @exp2(double %x) [[NUW_RO]] 47 ret double %retval 48; CHECK-NEXT: ret double [[EXP2]] 49} 50 51; Check pow(x, 0.0) -> 1.0. 52 53define float @test_simplify5(float %x) { 54; CHECK-LABEL: @test_simplify5( 55 %retval = call float @powf(float %x, float 0.0) 56 ret float %retval 57; CHECK-NEXT: ret float 1.000000e+00 58} 59 60define double @test_simplify6(double %x) { 61; CHECK-LABEL: @test_simplify6( 62 %retval = call double @pow(double %x, double 0.0) 63 ret double %retval 64; CHECK-NEXT: ret double 1.000000e+00 65} 66 67; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity. 68 69define float @test_simplify7(float %x) { 70; CHECK-LABEL: @test_simplify7( 71 %retval = call float @powf(float %x, float 0.5) 72; CHECK-NEXT: [[SQRTF:%[a-z0-9]+]] = call float @sqrtf(float %x) [[NUW_RO]] 73; CHECK-NEXT: [[FABSF:%[a-z0-9]+]] = call float @fabsf(float [[SQRTF]]) [[NUW_RO]] 74; CHECK-NEXT: [[FCMP:%[a-z0-9]+]] = fcmp oeq float %x, 0xFFF0000000000000 75; CHECK-NEXT: [[SELECT:%[a-z0-9]+]] = select i1 [[FCMP]], float 0x7FF0000000000000, float [[FABSF]] 76 ret float %retval 77; CHECK-NEXT: ret float [[SELECT]] 78} 79 80define double @test_simplify8(double %x) { 81; CHECK-LABEL: @test_simplify8( 82 %retval = call double @pow(double %x, double 0.5) 83; CHECK-NEXT: [[SQRT:%[a-z0-9]+]] = call double @sqrt(double %x) [[NUW_RO]] 84; CHECK-NEXT: [[FABS:%[a-z0-9]+]] = call double @fabs(double [[SQRT]]) [[NUW_RO]] 85; CHECK-NEXT: [[FCMP:%[a-z0-9]+]] = fcmp oeq double %x, 0xFFF0000000000000 86; CHECK-NEXT: [[SELECT:%[a-z0-9]+]] = select i1 [[FCMP]], double 0x7FF0000000000000, double [[FABS]] 87 ret double %retval 88; CHECK-NEXT: ret double [[SELECT]] 89} 90 91; Check pow(-infinity, 0.5) -> +infinity. 92 93define float @test_simplify9(float %x) { 94; CHECK-LABEL: @test_simplify9( 95 %retval = call float @powf(float 0xFFF0000000000000, float 0.5) 96 ret float %retval 97; CHECK-NEXT: ret float 0x7FF0000000000000 98} 99 100define double @test_simplify10(double %x) { 101; CHECK-LABEL: @test_simplify10( 102 %retval = call double @pow(double 0xFFF0000000000000, double 0.5) 103 ret double %retval 104; CHECK-NEXT: ret double 0x7FF0000000000000 105} 106 107; Check pow(x, 1.0) -> x. 108 109define float @test_simplify11(float %x) { 110; CHECK-LABEL: @test_simplify11( 111 %retval = call float @powf(float %x, float 1.0) 112 ret float %retval 113; CHECK-NEXT: ret float %x 114} 115 116define double @test_simplify12(double %x) { 117; CHECK-LABEL: @test_simplify12( 118 %retval = call double @pow(double %x, double 1.0) 119 ret double %retval 120; CHECK-NEXT: ret double %x 121} 122 123; Check pow(x, 2.0) -> x*x. 124 125define float @test_simplify13(float %x) { 126; CHECK-LABEL: @test_simplify13( 127 %retval = call float @powf(float %x, float 2.0) 128; CHECK-NEXT: [[SQUARE:%[a-z0-9]+]] = fmul float %x, %x 129 ret float %retval 130; CHECK-NEXT: ret float [[SQUARE]] 131} 132 133define double @test_simplify14(double %x) { 134; CHECK-LABEL: @test_simplify14( 135 %retval = call double @pow(double %x, double 2.0) 136; CHECK-NEXT: [[SQUARE:%[a-z0-9]+]] = fmul double %x, %x 137 ret double %retval 138; CHECK-NEXT: ret double [[SQUARE]] 139} 140 141; Check pow(x, -1.0) -> 1.0/x. 142 143define float @test_simplify15(float %x) { 144; CHECK-LABEL: @test_simplify15( 145 %retval = call float @powf(float %x, float -1.0) 146; CHECK-NEXT: [[RECIPROCAL:%[a-z0-9]+]] = fdiv float 1.000000e+00, %x 147 ret float %retval 148; CHECK-NEXT: ret float [[RECIPROCAL]] 149} 150 151define double @test_simplify16(double %x) { 152; CHECK-LABEL: @test_simplify16( 153 %retval = call double @pow(double %x, double -1.0) 154; CHECK-NEXT: [[RECIPROCAL:%[a-z0-9]+]] = fdiv double 1.000000e+00, %x 155 ret double %retval 156; CHECK-NEXT: ret double [[RECIPROCAL]] 157} 158 159declare double @llvm.pow.f64(double %Val, double %Power) 160define double @test_simplify17(double %x) { 161; CHECK-LABEL: @test_simplify17( 162 %retval = call double @llvm.pow.f64(double %x, double 0.5) 163; CHECK-NEXT: [[SQRT:%[a-z0-9]+]] = call double @sqrt(double %x) 164; CHECK-NEXT: [[FABS:%[a-z0-9]+]] = call double @fabs(double [[SQRT]]) 165; CHECK-NEXT: [[FCMP:%[a-z0-9]+]] = fcmp oeq double %x, 0xFFF0000000000000 166; CHECK-NEXT: [[SELECT:%[a-z0-9]+]] = select i1 [[FCMP]], double 0x7FF0000000000000, double [[FABS]] 167 ret double %retval 168; CHECK-NEXT: ret double [[SELECT]] 169} 170 171; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+. 172 173define float @test_simplify18(float %x) { 174; CHECK-LABEL: @test_simplify18( 175 %retval = call float @powf(float 10.0, float %x) 176; CHECK-EXP10: [[EXP10F:%[_a-z0-9]+]] = call float @__exp10f(float %x) [[NUW_RO:#[0-9]+]] 177 ret float %retval 178; CHECK-EXP10: ret float [[EXP10F]] 179; CHECK-NO-EXP10: call float @powf 180} 181 182define double @test_simplify19(double %x) { 183; CHECK-LABEL: @test_simplify19( 184 %retval = call double @pow(double 10.0, double %x) 185; CHECK-EXP10: [[EXP10:%[_a-z0-9]+]] = call double @__exp10(double %x) [[NUW_RO]] 186 ret double %retval 187; CHECK-EXP10: ret double [[EXP10]] 188; CHECK-NO-EXP10: call double @pow 189} 190 191; CHECK: attributes [[NUW_RO]] = { nounwind readonly } 192 193