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 14 declare float @powf(float, float) nounwind readonly 15 declare double @pow(double, double) nounwind readonly 16 17 ; Check pow(1.0, x) -> 1.0. 18 19 define 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 26 define 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 35 define 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 43 define 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 53 define 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 60 define 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 69 define 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 80 define 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 93 define 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 100 define 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 109 define 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 116 define 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 125 define 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 133 define 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 143 define 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 151 define 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 159 declare double @llvm.pow.f64(double %Val, double %Power) 160 define 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 173 define 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 182 define 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