Home | History | Annotate | Download | only in InstCombine
      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