Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt < %s -instcombine -S | FileCheck %s
      2 
      3 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
      4 target triple = "x86_64-unknown-linux-gnu"
      5 
      6 ; Check for and against shrinkage when using the
      7 ; unsafe-fp-math function attribute on a math lib
      8 ; function. This optimization may be overridden by
      9 ; the -enable-double-float-shrink option.
     10 ; PR17850: http://llvm.org/bugs/show_bug.cgi?id=17850
     11 
     12 define float @acos_test(float %f)   {
     13    %conv = fpext float %f to double
     14    %call = call double @acos(double %conv)
     15    %conv1 = fptrunc double %call to float
     16    ret float %conv1
     17 ; CHECK-LABEL: acos_test
     18 ; CHECK: call float @acosf(float %f)
     19 }
     20 
     21 define double @acos_test2(float %f)   {
     22    %conv = fpext float %f to double
     23    %call = call double @acos(double %conv)
     24    ret double %call
     25 ; CHECK-LABEL: acos_test2
     26 ; CHECK: call double @acos(double %conv)
     27 }
     28 
     29 define float @acosh_test(float %f)   {
     30    %conv = fpext float %f to double
     31    %call = call double @acosh(double %conv)
     32    %conv1 = fptrunc double %call to float
     33    ret float %conv1
     34 ; CHECK-LABEL: acosh_test
     35 ; CHECK: call float @acoshf(float %f)
     36 }
     37 
     38 define double @acosh_test2(float %f)   {
     39    %conv = fpext float %f to double
     40    %call = call double @acosh(double %conv)
     41    ret double %call
     42 ; CHECK-LABEL: acosh_test2
     43 ; CHECK: call double @acosh(double %conv)
     44 }
     45 
     46 define float @asin_test(float %f)   {
     47    %conv = fpext float %f to double
     48    %call = call double @asin(double %conv)
     49    %conv1 = fptrunc double %call to float
     50    ret float %conv1
     51 ; CHECK-LABEL: asin_test
     52 ; CHECK: call float @asinf(float %f)
     53 }
     54 
     55 define double @asin_test2(float %f)   {
     56    %conv = fpext float %f to double
     57    %call = call double @asin(double %conv)
     58    ret double %call
     59 ; CHECK-LABEL: asin_test2
     60 ; CHECK: call double @asin(double %conv)
     61 }
     62 
     63 define float @asinh_test(float %f)   {
     64    %conv = fpext float %f to double
     65    %call = call double @asinh(double %conv)
     66    %conv1 = fptrunc double %call to float
     67    ret float %conv1
     68 ; CHECK-LABEL: asinh_test
     69 ; CHECK: call float @asinhf(float %f)
     70 }
     71 
     72 define double @asinh_test2(float %f)   {
     73    %conv = fpext float %f to double
     74    %call = call double @asinh(double %conv)
     75    ret double %call
     76 ; CHECK-LABEL: asinh_test2
     77 ; CHECK: call double @asinh(double %conv)
     78 }
     79 
     80 define float @atan_test(float %f)   {
     81    %conv = fpext float %f to double
     82    %call = call double @atan(double %conv)
     83    %conv1 = fptrunc double %call to float
     84    ret float %conv1
     85 ; CHECK-LABEL: atan_test
     86 ; CHECK: call float @atanf(float %f)
     87 }
     88 
     89 define double @atan_test2(float %f)   {
     90    %conv = fpext float %f to double
     91    %call = call double @atan(double %conv)
     92    ret double %call
     93 ; CHECK-LABEL: atan_test2
     94 ; CHECK: call double @atan(double %conv)
     95 }
     96 define float @atanh_test(float %f)   {
     97    %conv = fpext float %f to double
     98    %call = call double @atanh(double %conv)
     99    %conv1 = fptrunc double %call to float
    100    ret float %conv1
    101 ; CHECK-LABEL: atanh_test
    102 ; CHECK: call float @atanhf(float %f)
    103 }
    104 
    105 define double @atanh_test2(float %f)   {
    106     %conv = fpext float %f to double
    107     %call = call double @atanh(double %conv)
    108     ret double %call
    109 ; CHECK-LABEL: atanh_test2
    110 ; CHECK: call double @atanh(double %conv)
    111 }
    112 define float @cbrt_test(float %f)   {
    113    %conv = fpext float %f to double
    114    %call = call double @cbrt(double %conv)
    115    %conv1 = fptrunc double %call to float
    116    ret float %conv1
    117 ; CHECK-LABEL: cbrt_test
    118 ; CHECK: call float @cbrtf(float %f)
    119 }
    120 
    121 define double @cbrt_test2(float %f)   {
    122    %conv = fpext float %f to double
    123    %call = call double @cbrt(double %conv)
    124    ret double %call
    125 ; CHECK-LABEL: cbrt_test2
    126 ; CHECK: call double @cbrt(double %conv)
    127 }
    128 define float @exp_test(float %f)   {
    129    %conv = fpext float %f to double
    130    %call = call double @exp(double %conv)
    131    %conv1 = fptrunc double %call to float
    132    ret float %conv1
    133 ; CHECK-LABEL: exp_test
    134 ; CHECK: call float @expf(float %f)
    135 }
    136 
    137 define double @exp_test2(float %f)   {
    138    %conv = fpext float %f to double
    139    %call = call double @exp(double %conv)
    140    ret double %call
    141 ; CHECK-LABEL: exp_test2
    142 ; CHECK: call double @exp(double %conv)
    143 }
    144 define float @expm1_test(float %f)   {
    145    %conv = fpext float %f to double
    146    %call = call double @expm1(double %conv)
    147    %conv1 = fptrunc double %call to float
    148    ret float %conv1
    149 ; CHECK-LABEL: expm1_test
    150 ; CHECK: call float @expm1f(float %f)
    151 }
    152 
    153 define double @expm1_test2(float %f)   {
    154    %conv = fpext float %f to double
    155    %call = call double @expm1(double %conv)
    156    ret double %call
    157 ; CHECK-LABEL: expm1_test2
    158 ; CHECK: call double @expm1(double %conv)
    159 }
    160 define float @exp10_test(float %f)   {
    161    %conv = fpext float %f to double
    162    %call = call double @exp10(double %conv)
    163    %conv1 = fptrunc double %call to float
    164    ret float %conv1
    165 ; CHECK-LABEL: exp10_test
    166 ; CHECK: call double @exp10(double %conv)
    167 }
    168 
    169 define double @exp10_test2(float %f)   {
    170    %conv = fpext float %f to double
    171    %call = call double @exp10(double %conv)
    172    ret double %call
    173 ; CHECK-LABEL: exp10_test2
    174 ; CHECK: call double @exp10(double %conv)
    175 }
    176 define float @log_test(float %f)   {
    177    %conv = fpext float %f to double
    178    %call = call double @log(double %conv)
    179    %conv1 = fptrunc double %call to float
    180    ret float %conv1
    181 ; CHECK-LABEL: log_test
    182 ; CHECK: call float @logf(float %f)
    183 }
    184 
    185 define double @log_test2(float %f)   {
    186    %conv = fpext float %f to double
    187    %call = call double @log(double %conv)
    188    ret double %call
    189 ; CHECK-LABEL: log_test2
    190 ; CHECK: call double @log(double %conv)
    191 }
    192 define float @log10_test(float %f)   {
    193    %conv = fpext float %f to double
    194    %call = call double @log10(double %conv)
    195    %conv1 = fptrunc double %call to float
    196    ret float %conv1
    197 ; CHECK-LABEL: log10_test
    198 ; CHECK: call float @log10f(float %f)
    199 }
    200 
    201 define double @log10_test2(float %f) {
    202    %conv = fpext float %f to double
    203    %call = call double @log10(double %conv)
    204    ret double %call
    205 ; CHECK-LABEL: log10_test2
    206 ; CHECK: call double @log10(double %conv)
    207 }
    208 define float @log1p_test(float %f)   {
    209    %conv = fpext float %f to double
    210    %call = call double @log1p(double %conv)
    211    %conv1 = fptrunc double %call to float
    212    ret float %conv1
    213 ; CHECK-LABEL: log1p_test
    214 ; CHECK: call float @log1pf(float %f)
    215 }
    216 
    217 define double @log1p_test2(float %f)   {
    218    %conv = fpext float %f to double
    219    %call = call double @log1p(double %conv)
    220    ret double %call
    221 ; CHECK-LABEL: log1p_test2
    222 ; CHECK: call double @log1p(double %conv)
    223 }
    224 define float @log2_test(float %f)   {
    225    %conv = fpext float %f to double
    226    %call = call double @log2(double %conv)
    227    %conv1 = fptrunc double %call to float
    228    ret float %conv1
    229 ; CHECK-LABEL: log2_test
    230 ; CHECK: call float @log2f(float %f)
    231 }
    232 
    233 define double @log2_test2(float %f)   {
    234    %conv = fpext float %f to double
    235    %call = call double @log2(double %conv)
    236    ret double %call
    237 ; CHECK-LABEL: log2_test2
    238 ; CHECK: call double @log2(double %conv)
    239 }
    240 define float @logb_test(float %f)   {
    241    %conv = fpext float %f to double
    242    %call = call double @logb(double %conv)
    243    %conv1 = fptrunc double %call to float
    244    ret float %conv1
    245 ; CHECK-LABEL: logb_test
    246 ; CHECK: call float @logbf(float %f)
    247 }
    248 
    249 define double @logb_test2(float %f)   {
    250    %conv = fpext float %f to double
    251    %call = call double @logb(double %conv)
    252    ret double %call
    253 ; CHECK-LABEL: logb_test2
    254 ; CHECK: call double @logb(double %conv)
    255 }
    256 define float @sin_test(float %f)   {
    257    %conv = fpext float %f to double
    258    %call = call double @sin(double %conv)
    259    %conv1 = fptrunc double %call to float
    260    ret float %conv1
    261 ; CHECK-LABEL: sin_test
    262 ; CHECK: call float @sinf(float %f)
    263 }
    264 
    265 define double @sin_test2(float %f) {
    266    %conv = fpext float %f to double
    267    %call = call double @sin(double %conv)
    268    ret double %call
    269 ; CHECK-LABEL: sin_test2
    270 ; CHECK: call double @sin(double %conv)
    271 }
    272 
    273 define float @sqrt_test(float %f) {
    274    %conv = fpext float %f to double
    275    %call = call double @sqrt(double %conv)
    276    %conv1 = fptrunc double %call to float
    277    ret float %conv1
    278 ; CHECK-LABEL: sqrt_test
    279 ; CHECK: call float @sqrtf(float %f)
    280 }
    281 
    282 define double @sqrt_test2(float %f) {
    283    %conv = fpext float %f to double
    284    %call = call double @sqrt(double %conv)
    285    ret double %call
    286 ; CHECK-LABEL: sqrt_test2
    287 ; CHECK: call double @sqrt(double %conv)
    288 }
    289 
    290 define float @sqrt_int_test(float %f) {
    291    %conv = fpext float %f to double
    292    %call = call double @llvm.sqrt.f64(double %conv)
    293    %conv1 = fptrunc double %call to float
    294    ret float %conv1
    295 ; CHECK-LABEL: sqrt_int_test
    296 ; CHECK: call float @llvm.sqrt.f32(float %f)
    297 }
    298 
    299 define double @sqrt_int_test2(float %f) {
    300    %conv = fpext float %f to double
    301    %call = call double @llvm.sqrt.f64(double %conv)
    302    ret double %call
    303 ; CHECK-LABEL: sqrt_int_test2
    304 ; CHECK: call double @llvm.sqrt.f64(double %conv)
    305 }
    306 
    307 define float @tan_test(float %f) {
    308    %conv = fpext float %f to double
    309    %call = call double @tan(double %conv)
    310    %conv1 = fptrunc double %call to float
    311    ret float %conv1
    312 ; CHECK-LABEL: tan_test
    313 ; CHECK: call float @tanf(float %f)
    314 }
    315 
    316 define double @tan_test2(float %f) {
    317    %conv = fpext float %f to double
    318    %call = call double @tan(double %conv)
    319    ret double %call
    320 ; CHECK-LABEL: tan_test2
    321 ; CHECK: call double @tan(double %conv)
    322 }
    323 define float @tanh_test(float %f) {
    324    %conv = fpext float %f to double
    325    %call = call double @tanh(double %conv)
    326    %conv1 = fptrunc double %call to float
    327    ret float %conv1
    328 ; CHECK-LABEL: tanh_test
    329 ; CHECK: call float @tanhf(float %f)
    330 }
    331 
    332 define double @tanh_test2(float %f) {
    333    %conv = fpext float %f to double
    334    %call = call double @tanh(double %conv)
    335    ret double %call
    336 ; CHECK-LABEL: tanh_test2
    337 ; CHECK: call double @tanh(double %conv)
    338 }
    339 
    340 declare double @tanh(double) #1
    341 declare double @tan(double) #1
    342 
    343 ; sqrt is a special case: the shrinking optimization 
    344 ; is valid even without unsafe-fp-math.
    345 declare double @sqrt(double) 
    346 declare double @llvm.sqrt.f64(double) 
    347 
    348 declare double @sin(double) #1
    349 declare double @log2(double) #1
    350 declare double @log1p(double) #1
    351 declare double @log10(double) #1
    352 declare double @log(double) #1
    353 declare double @logb(double) #1
    354 declare double @exp10(double) #1
    355 declare double @expm1(double) #1
    356 declare double @exp(double) #1
    357 declare double @cbrt(double) #1
    358 declare double @atanh(double) #1
    359 declare double @atan(double) #1
    360 declare double @acos(double) #1
    361 declare double @acosh(double) #1
    362 declare double @asin(double) #1
    363 declare double @asinh(double) #1
    364 
    365 attributes #1 = { "unsafe-fp-math"="true" }
    366 
    367