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