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_test1(float %f)   {
     13    %conv = fpext float %f to double
     14    %call = call fast double @acos(double %conv)
     15    %conv1 = fptrunc double %call to float
     16    ret float %conv1
     17 ; CHECK-LABEL: acos_test1
     18 ; CHECK: call fast float @acosf(float %f)
     19 }
     20 
     21 define double @acos_test2(float %f)   {
     22    %conv = fpext float %f to double
     23    %call = call fast double @acos(double %conv)
     24    ret double %call
     25 ; CHECK-LABEL: acos_test2
     26 ; CHECK: call fast double @acos(double %conv)
     27 }
     28 
     29 define float @acosh_test1(float %f)   {
     30    %conv = fpext float %f to double
     31    %call = call fast double @acosh(double %conv)
     32    %conv1 = fptrunc double %call to float
     33    ret float %conv1
     34 ; CHECK-LABEL: acosh_test1
     35 ; CHECK: call fast float @acoshf(float %f)
     36 }
     37 
     38 define double @acosh_test2(float %f)   {
     39    %conv = fpext float %f to double
     40    %call = call fast double @acosh(double %conv)
     41    ret double %call
     42 ; CHECK-LABEL: acosh_test2
     43 ; CHECK: call fast double @acosh(double %conv)
     44 }
     45 
     46 define float @asin_test1(float %f)   {
     47    %conv = fpext float %f to double
     48    %call = call fast double @asin(double %conv)
     49    %conv1 = fptrunc double %call to float
     50    ret float %conv1
     51 ; CHECK-LABEL: asin_test1
     52 ; CHECK: call fast float @asinf(float %f)
     53 }
     54 
     55 define double @asin_test2(float %f)   {
     56    %conv = fpext float %f to double
     57    %call = call fast double @asin(double %conv)
     58    ret double %call
     59 ; CHECK-LABEL: asin_test2
     60 ; CHECK: call fast double @asin(double %conv)
     61 }
     62 
     63 define float @asinh_test1(float %f)   {
     64    %conv = fpext float %f to double
     65    %call = call fast double @asinh(double %conv)
     66    %conv1 = fptrunc double %call to float
     67    ret float %conv1
     68 ; CHECK-LABEL: asinh_test1
     69 ; CHECK: call fast float @asinhf(float %f)
     70 }
     71 
     72 define double @asinh_test2(float %f)   {
     73    %conv = fpext float %f to double
     74    %call = call fast double @asinh(double %conv)
     75    ret double %call
     76 ; CHECK-LABEL: asinh_test2
     77 ; CHECK: call fast double @asinh(double %conv)
     78 }
     79 
     80 define float @atan_test1(float %f)   {
     81    %conv = fpext float %f to double
     82    %call = call fast double @atan(double %conv)
     83    %conv1 = fptrunc double %call to float
     84    ret float %conv1
     85 ; CHECK-LABEL: atan_test1
     86 ; CHECK: call fast float @atanf(float %f)
     87 }
     88 
     89 define double @atan_test2(float %f)   {
     90    %conv = fpext float %f to double
     91    %call = call fast double @atan(double %conv)
     92    ret double %call
     93 ; CHECK-LABEL: atan_test2
     94 ; CHECK: call fast double @atan(double %conv)
     95 }
     96 
     97 define float @atanh_test1(float %f)   {
     98    %conv = fpext float %f to double
     99    %call = call fast double @atanh(double %conv)
    100    %conv1 = fptrunc double %call to float
    101    ret float %conv1
    102 ; CHECK-LABEL: atanh_test1
    103 ; CHECK: call fast float @atanhf(float %f)
    104 }
    105 
    106 define double @atanh_test2(float %f)   {
    107     %conv = fpext float %f to double
    108     %call = call fast double @atanh(double %conv)
    109     ret double %call
    110 ; CHECK-LABEL: atanh_test2
    111 ; CHECK: call fast double @atanh(double %conv)
    112 }
    113 
    114 define float @cbrt_test1(float %f)   {
    115    %conv = fpext float %f to double
    116    %call = call fast double @cbrt(double %conv)
    117    %conv1 = fptrunc double %call to float
    118    ret float %conv1
    119 ; CHECK-LABEL: cbrt_test1
    120 ; CHECK: call fast float @cbrtf(float %f)
    121 }
    122 
    123 define double @cbrt_test2(float %f)   {
    124    %conv = fpext float %f to double
    125    %call = call fast  double @cbrt(double %conv)
    126    ret double %call
    127 ; CHECK-LABEL: cbrt_test2
    128 ; CHECK: call fast double @cbrt(double %conv)
    129 }
    130 
    131 define float @exp_test1(float %f)   {
    132    %conv = fpext float %f to double
    133    %call = call fast double @exp(double %conv)
    134    %conv1 = fptrunc double %call to float
    135    ret float %conv1
    136 ; CHECK-LABEL: exp_test1
    137 ; CHECK: call fast float @expf(float %f)
    138 }
    139 
    140 define double @exp_test2(float %f)   {
    141    %conv = fpext float %f to double
    142    %call = call fast double @exp(double %conv)
    143    ret double %call
    144 ; CHECK-LABEL: exp_test2
    145 ; CHECK: call fast double @exp(double %conv)
    146 }
    147 
    148 define float @expm1_test1(float %f)   {
    149    %conv = fpext float %f to double
    150    %call = call fast double @expm1(double %conv)
    151    %conv1 = fptrunc double %call to float
    152    ret float %conv1
    153 ; CHECK-LABEL: expm1_test1
    154 ; CHECK: call fast float @expm1f(float %f)
    155 }
    156 
    157 define double @expm1_test2(float %f)   {
    158    %conv = fpext float %f to double
    159    %call = call fast double @expm1(double %conv)
    160    ret double %call
    161 ; CHECK-LABEL: expm1_test2
    162 ; CHECK: call fast double @expm1(double %conv)
    163 }
    164 
    165 ; exp10f() doesn't exist for this triple, so it doesn't shrink.
    166 
    167 define float @exp10_test1(float %f)   {
    168    %conv = fpext float %f to double
    169    %call = call fast double @exp10(double %conv)
    170    %conv1 = fptrunc double %call to float
    171    ret float %conv1
    172 ; CHECK-LABEL: exp10_test1
    173 ; CHECK: call fast double @exp10(double %conv)
    174 }
    175 
    176 define double @exp10_test2(float %f)   {
    177    %conv = fpext float %f to double
    178    %call = call fast double @exp10(double %conv)
    179    ret double %call
    180 ; CHECK-LABEL: exp10_test2
    181 ; CHECK: call fast double @exp10(double %conv)
    182 }
    183 
    184 define float @log_test1(float %f)   {
    185    %conv = fpext float %f to double
    186    %call = call fast double @log(double %conv)
    187    %conv1 = fptrunc double %call to float
    188    ret float %conv1
    189 ; CHECK-LABEL: log_test1
    190 ; CHECK: call fast float @logf(float %f)
    191 }
    192 
    193 define double @log_test2(float %f)   {
    194    %conv = fpext float %f to double
    195    %call = call fast double @log(double %conv)
    196    ret double %call
    197 ; CHECK-LABEL: log_test2
    198 ; CHECK: call fast double @log(double %conv)
    199 }
    200 
    201 define float @log10_test1(float %f)   {
    202    %conv = fpext float %f to double
    203    %call = call fast double @log10(double %conv)
    204    %conv1 = fptrunc double %call to float
    205    ret float %conv1
    206 ; CHECK-LABEL: log10_test1
    207 ; CHECK: call fast float @log10f(float %f)
    208 }
    209 
    210 define double @log10_test2(float %f) {
    211    %conv = fpext float %f to double
    212    %call = call fast double @log10(double %conv)
    213    ret double %call
    214 ; CHECK-LABEL: log10_test2
    215 ; CHECK: call fast double @log10(double %conv)
    216 }
    217 
    218 define float @log1p_test1(float %f)   {
    219    %conv = fpext float %f to double
    220    %call = call fast double @log1p(double %conv)
    221    %conv1 = fptrunc double %call to float
    222    ret float %conv1
    223 ; CHECK-LABEL: log1p_test1
    224 ; CHECK: call fast float @log1pf(float %f)
    225 }
    226 
    227 define double @log1p_test2(float %f)   {
    228    %conv = fpext float %f to double
    229    %call = call fast double @log1p(double %conv)
    230    ret double %call
    231 ; CHECK-LABEL: log1p_test2
    232 ; CHECK: call fast double @log1p(double %conv)
    233 }
    234 
    235 define float @log2_test1(float %f)   {
    236    %conv = fpext float %f to double
    237    %call = call fast double @log2(double %conv)
    238    %conv1 = fptrunc double %call to float
    239    ret float %conv1
    240 ; CHECK-LABEL: log2_test1
    241 ; CHECK: call fast float @log2f(float %f)
    242 }
    243 
    244 define double @log2_test2(float %f)   {
    245    %conv = fpext float %f to double
    246    %call = call fast double @log2(double %conv)
    247    ret double %call
    248 ; CHECK-LABEL: log2_test2
    249 ; CHECK: call fast double @log2(double %conv)
    250 }
    251 
    252 define float @logb_test1(float %f)   {
    253    %conv = fpext float %f to double
    254    %call = call fast double @logb(double %conv)
    255    %conv1 = fptrunc double %call to float
    256    ret float %conv1
    257 ; CHECK-LABEL: logb_test1
    258 ; CHECK: call fast float @logbf(float %f)
    259 }
    260 
    261 define double @logb_test2(float %f)   {
    262    %conv = fpext float %f to double
    263    %call = call fast double @logb(double %conv)
    264    ret double %call
    265 ; CHECK-LABEL: logb_test2
    266 ; CHECK: call fast double @logb(double %conv)
    267 }
    268 
    269 define float @sin_test1(float %f)   {
    270    %conv = fpext float %f to double
    271    %call = call fast double @sin(double %conv)
    272    %conv1 = fptrunc double %call to float
    273    ret float %conv1
    274 ; CHECK-LABEL: sin_test1
    275 ; CHECK: call fast float @sinf(float %f)
    276 }
    277 
    278 define double @sin_test2(float %f) {
    279    %conv = fpext float %f to double
    280    %call = call fast double @sin(double %conv)
    281    ret double %call
    282 ; CHECK-LABEL: sin_test2
    283 ; CHECK: call fast double @sin(double %conv)
    284 }
    285 
    286 define float @sqrt_test1(float %f) {
    287    %conv = fpext float %f to double
    288    %call = call double @sqrt(double %conv)
    289    %conv1 = fptrunc double %call to float
    290    ret float %conv1
    291 ; CHECK-LABEL: sqrt_test1
    292 ; CHECK: call float @sqrtf(float %f)
    293 }
    294 
    295 define double @sqrt_test2(float %f) {
    296    %conv = fpext float %f to double
    297    %call = call double @sqrt(double %conv)
    298    ret double %call
    299 ; CHECK-LABEL: sqrt_test2
    300 ; CHECK: call double @sqrt(double %conv)
    301 }
    302 
    303 define float @sqrt_int_test1(float %f) {
    304    %conv = fpext float %f to double
    305    %call = call double @llvm.sqrt.f64(double %conv)
    306    %conv1 = fptrunc double %call to float
    307    ret float %conv1
    308 ; CHECK-LABEL: sqrt_int_test1
    309 ; CHECK: call float @llvm.sqrt.f32(float %f)
    310 }
    311 
    312 define double @sqrt_int_test2(float %f) {
    313    %conv = fpext float %f to double
    314    %call = call double @llvm.sqrt.f64(double %conv)
    315    ret double %call
    316 ; CHECK-LABEL: sqrt_int_test2
    317 ; CHECK: call double @llvm.sqrt.f64(double %conv)
    318 }
    319 
    320 define float @tan_test1(float %f) {
    321    %conv = fpext float %f to double
    322    %call = call fast double @tan(double %conv)
    323    %conv1 = fptrunc double %call to float
    324    ret float %conv1
    325 ; CHECK-LABEL: tan_test1
    326 ; CHECK: call fast float @tanf(float %f)
    327 }
    328 
    329 define double @tan_test2(float %f) {
    330    %conv = fpext float %f to double
    331    %call = call fast double @tan(double %conv)
    332    ret double %call
    333 ; CHECK-LABEL: tan_test2
    334 ; CHECK: call fast double @tan(double %conv)
    335 }
    336 define float @tanh_test1(float %f) {
    337    %conv = fpext float %f to double
    338    %call = call fast double @tanh(double %conv)
    339    %conv1 = fptrunc double %call to float
    340    ret float %conv1
    341 ; CHECK-LABEL: tanh_test1
    342 ; CHECK: call fast float @tanhf(float %f)
    343 }
    344 
    345 define double @tanh_test2(float %f) {
    346    %conv = fpext float %f to double
    347    %call = call fast double @tanh(double %conv)
    348    ret double %call
    349 ; CHECK-LABEL: tanh_test2
    350 ; CHECK: call fast double @tanh(double %conv)
    351 }
    352 
    353 ; 'arcp' on an fmax() is meaningless. This test just proves that
    354 ; flags are propagated for shrunken *binary* double FP calls.
    355 define float @max1(float %a, float %b) {
    356   %c = fpext float %a to double
    357   %d = fpext float %b to double
    358   %e = call arcp double @fmax(double %c, double %d)
    359   %f = fptrunc double %e to float
    360   ret float %f
    361 
    362 ; CHECK-LABEL: max1(
    363 ; CHECK-NEXT:  call arcp float @fmaxf(float %a, float %b)
    364 ; CHECK-NEXT:  ret
    365 }
    366 
    367 ; A function can have a name that matches a common libcall,
    368 ; but with the wrong type(s). Let it be.
    369 
    370 define float @fake_fmin(float %a, float %b) {
    371   %c = fpext float %a to fp128
    372   %d = fpext float %b to fp128
    373   %e = call fp128 @fmin(fp128 %c, fp128 %d)
    374   %f = fptrunc fp128 %e to float
    375   ret float %f
    376 
    377 ; CHECK-LABEL: fake_fmin(
    378 ; CHECK-NEXT:  %c = fpext float %a to fp128
    379 ; CHECK-NEXT:  %d = fpext float %b to fp128
    380 ; CHECK-NEXT:  %e = call fp128 @fmin(fp128 %c, fp128 %d)
    381 ; CHECK-NEXT:  %f = fptrunc fp128 %e to float
    382 ; CHECK-NEXT:  ret float %f
    383 }
    384 
    385 declare fp128 @fmin(fp128, fp128) ; This is not the 'fmin' you're looking for.
    386 
    387 declare double @fmax(double, double)
    388 
    389 declare double @tanh(double)
    390 declare double @tan(double)
    391 
    392 ; sqrt is a special case: the shrinking optimization 
    393 ; is valid even without unsafe-fp-math.
    394 declare double @sqrt(double) 
    395 declare double @llvm.sqrt.f64(double) 
    396 
    397 declare double @sin(double)
    398 declare double @log2(double)
    399 declare double @log1p(double)
    400 declare double @log10(double)
    401 declare double @log(double)
    402 declare double @logb(double)
    403 declare double @exp10(double)
    404 declare double @expm1(double)
    405 declare double @exp(double)
    406 declare double @cbrt(double)
    407 declare double @atanh(double)
    408 declare double @atan(double)
    409 declare double @acos(double)
    410 declare double @acosh(double)
    411 declare double @asin(double)
    412 declare double @asinh(double)
    413 
    414