Home | History | Annotate | Download | only in InstCombine
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt -S -instcombine < %s | FileCheck %s
      3 
      4 declare double @llvm.fabs.f64(double) readnone
      5 
      6 define i1 @test1(float %x, float %y) {
      7 ; CHECK-LABEL: @test1(
      8 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
      9 ; CHECK-NEXT:    ret i1 [[CMP]]
     10 ;
     11   %ext1 = fpext float %x to double
     12   %ext2 = fpext float %y to double
     13   %cmp = fcmp ogt double %ext1, %ext2
     14   ret i1 %cmp
     15 }
     16 
     17 define i1 @test2(float %a) {
     18 ; CHECK-LABEL: @test2(
     19 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 1.000000e+00
     20 ; CHECK-NEXT:    ret i1 [[CMP]]
     21 ;
     22   %ext = fpext float %a to double
     23   %cmp = fcmp ogt double %ext, 1.000000e+00
     24   ret i1 %cmp
     25 }
     26 
     27 define i1 @test3(float %a) {
     28 ; CHECK-LABEL: @test3(
     29 ; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[A:%.*]] to double
     30 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x3FF0000000000001
     31 ; CHECK-NEXT:    ret i1 [[CMP]]
     32 ;
     33   %ext = fpext float %a to double
     34   %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
     35   ret i1 %cmp
     36 }
     37 
     38 define i1 @test4(float %a) {
     39 ; CHECK-LABEL: @test4(
     40 ; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[A:%.*]] to double
     41 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x36A0000000000000
     42 ; CHECK-NEXT:    ret i1 [[CMP]]
     43 ;
     44   %ext = fpext float %a to double
     45   %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
     46   ret i1 %cmp
     47 }
     48 
     49 define i1 @fneg_constant_swap_pred(float %x) {
     50 ; CHECK-LABEL: @fneg_constant_swap_pred(
     51 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00
     52 ; CHECK-NEXT:    ret i1 [[CMP]]
     53 ;
     54   %neg = fsub float -0.0, %x
     55   %cmp = fcmp ogt float %neg, 1.0
     56   ret i1 %cmp
     57 }
     58 
     59 define <2 x i1> @fneg_constant_swap_pred_vec(<2 x float> %x) {
     60 ; CHECK-LABEL: @fneg_constant_swap_pred_vec(
     61 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
     62 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
     63 ;
     64   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
     65   %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
     66   ret <2 x i1> %cmp
     67 }
     68 
     69 define <2 x i1> @fneg_constant_swap_pred_vec_undef(<2 x float> %x) {
     70 ; CHECK-LABEL: @fneg_constant_swap_pred_vec_undef(
     71 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
     72 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
     73 ;
     74   %neg = fsub <2 x float> <float undef, float -0.0>, %x
     75   %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
     76   ret <2 x i1> %cmp
     77 }
     78 
     79 define i1 @fneg_fneg_swap_pred(float %x, float %y) {
     80 ; CHECK-LABEL: @fneg_fneg_swap_pred(
     81 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
     82 ; CHECK-NEXT:    ret i1 [[CMP]]
     83 ;
     84   %neg1 = fsub float -0.0, %x
     85   %neg2 = fsub float -0.0, %y
     86   %cmp = fcmp olt float %neg1, %neg2
     87   ret i1 %cmp
     88 }
     89 
     90 define <2 x i1> @fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
     91 ; CHECK-LABEL: @fneg_fneg_swap_pred_vec(
     92 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
     93 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
     94 ;
     95   %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x
     96   %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y
     97   %cmp = fcmp olt <2 x float> %neg1, %neg2
     98   ret <2 x i1> %cmp
     99 }
    100 
    101 define <2 x i1> @fneg_fneg_swap_pred_vec_undef(<2 x float> %x, <2 x float> %y) {
    102 ; CHECK-LABEL: @fneg_fneg_swap_pred_vec_undef(
    103 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
    104 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
    105 ;
    106   %neg1 = fsub <2 x float> <float -0.0, float undef>, %x
    107   %neg2 = fsub <2 x float> <float undef, float -0.0>, %y
    108   %cmp = fcmp olt <2 x float> %neg1, %neg2
    109   ret <2 x i1> %cmp
    110 }
    111 
    112 define i1 @test7(float %x) {
    113 ; CHECK-LABEL: @test7(
    114 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00
    115 ; CHECK-NEXT:    ret i1 [[CMP]]
    116 ;
    117   %ext = fpext float %x to ppc_fp128
    118   %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000
    119   ret i1 %cmp
    120 }
    121 
    122 define float @test8(float %x) {
    123 ; CHECK-LABEL: @test8(
    124 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
    125 ; CHECK-NEXT:    [[CONV2:%.*]] = uitofp i1 [[CMP]] to float
    126 ; CHECK-NEXT:    ret float [[CONV2]]
    127 ;
    128   %conv = fpext float %x to double
    129   %cmp = fcmp olt double %conv, 0.000000e+00
    130   %conv1 = zext i1 %cmp to i32
    131   %conv2 = sitofp i32 %conv1 to float
    132   ret float %conv2
    133 ; Float comparison to zero shouldn't cast to double.
    134 }
    135 
    136 declare double @fabs(double) readnone
    137 
    138 define i32 @test9(double %a) {
    139 ; CHECK-LABEL: @test9(
    140 ; CHECK-NEXT:    ret i32 0
    141 ;
    142   %call = tail call double @fabs(double %a)
    143   %cmp = fcmp olt double %call, 0.000000e+00
    144   %conv = zext i1 %cmp to i32
    145   ret i32 %conv
    146 }
    147 
    148 define i32 @test9_intrinsic(double %a) {
    149 ; CHECK-LABEL: @test9_intrinsic(
    150 ; CHECK-NEXT:    ret i32 0
    151 ;
    152   %call = tail call double @llvm.fabs.f64(double %a)
    153   %cmp = fcmp olt double %call, 0.000000e+00
    154   %conv = zext i1 %cmp to i32
    155   ret i32 %conv
    156 }
    157 
    158 define i32 @test10(double %a) {
    159 ; CHECK-LABEL: @test10(
    160 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
    161 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    162 ; CHECK-NEXT:    ret i32 [[CONV]]
    163 ;
    164   %call = tail call double @fabs(double %a)
    165   %cmp = fcmp ole double %call, 0.000000e+00
    166   %conv = zext i1 %cmp to i32
    167   ret i32 %conv
    168 }
    169 
    170 define i32 @test10_intrinsic(double %a) {
    171 ; CHECK-LABEL: @test10_intrinsic(
    172 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
    173 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    174 ; CHECK-NEXT:    ret i32 [[CONV]]
    175 ;
    176   %call = tail call double @llvm.fabs.f64(double %a)
    177   %cmp = fcmp ole double %call, 0.000000e+00
    178   %conv = zext i1 %cmp to i32
    179   ret i32 %conv
    180 }
    181 
    182 define i32 @test11(double %a) {
    183 ; CHECK-LABEL: @test11(
    184 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
    185 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    186 ; CHECK-NEXT:    ret i32 [[CONV]]
    187 ;
    188   %call = tail call double @fabs(double %a)
    189   %cmp = fcmp ogt double %call, 0.000000e+00
    190   %conv = zext i1 %cmp to i32
    191   ret i32 %conv
    192 }
    193 
    194 define i32 @test11_intrinsic(double %a) {
    195 ; CHECK-LABEL: @test11_intrinsic(
    196 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
    197 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    198 ; CHECK-NEXT:    ret i32 [[CONV]]
    199 ;
    200   %call = tail call double @llvm.fabs.f64(double %a)
    201   %cmp = fcmp ogt double %call, 0.000000e+00
    202   %conv = zext i1 %cmp to i32
    203   ret i32 %conv
    204 }
    205 
    206 define i32 @test12(double %a) {
    207 ; CHECK-LABEL: @test12(
    208 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord double [[A:%.*]], 0.000000e+00
    209 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    210 ; CHECK-NEXT:    ret i32 [[CONV]]
    211 ;
    212   %call = tail call double @fabs(double %a)
    213   %cmp = fcmp oge double %call, 0.000000e+00
    214   %conv = zext i1 %cmp to i32
    215   ret i32 %conv
    216 }
    217 
    218 define i32 @test12_intrinsic(double %a) {
    219 ; CHECK-LABEL: @test12_intrinsic(
    220 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord double [[A:%.*]], 0.000000e+00
    221 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    222 ; CHECK-NEXT:    ret i32 [[CONV]]
    223 ;
    224   %call = tail call double @llvm.fabs.f64(double %a)
    225   %cmp = fcmp oge double %call, 0.000000e+00
    226   %conv = zext i1 %cmp to i32
    227   ret i32 %conv
    228 }
    229 
    230 define i32 @test13(double %a) {
    231 ; CHECK-LABEL: @test13(
    232 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[A:%.*]], 0.000000e+00
    233 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    234 ; CHECK-NEXT:    ret i32 [[CONV]]
    235 ;
    236   %call = tail call double @fabs(double %a)
    237   %cmp = fcmp une double %call, 0.000000e+00
    238   %conv = zext i1 %cmp to i32
    239   ret i32 %conv
    240 }
    241 
    242 define i32 @test13_intrinsic(double %a) {
    243 ; CHECK-LABEL: @test13_intrinsic(
    244 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[A:%.*]], 0.000000e+00
    245 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    246 ; CHECK-NEXT:    ret i32 [[CONV]]
    247 ;
    248   %call = tail call double @llvm.fabs.f64(double %a)
    249   %cmp = fcmp une double %call, 0.000000e+00
    250   %conv = zext i1 %cmp to i32
    251   ret i32 %conv
    252 }
    253 
    254 define i32 @test14(double %a) {
    255 ; CHECK-LABEL: @test14(
    256 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
    257 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    258 ; CHECK-NEXT:    ret i32 [[CONV]]
    259 ;
    260   %call = tail call double @fabs(double %a)
    261   %cmp = fcmp oeq double %call, 0.000000e+00
    262   %conv = zext i1 %cmp to i32
    263   ret i32 %conv
    264 }
    265 
    266 define i32 @test14_intrinsic(double %a) {
    267 ; CHECK-LABEL: @test14_intrinsic(
    268 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
    269 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    270 ; CHECK-NEXT:    ret i32 [[CONV]]
    271 ;
    272   %call = tail call double @llvm.fabs.f64(double %a)
    273   %cmp = fcmp oeq double %call, 0.000000e+00
    274   %conv = zext i1 %cmp to i32
    275   ret i32 %conv
    276 }
    277 
    278 define i32 @test15(double %a) {
    279 ; CHECK-LABEL: @test15(
    280 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
    281 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    282 ; CHECK-NEXT:    ret i32 [[CONV]]
    283 ;
    284   %call = tail call double @fabs(double %a)
    285   %cmp = fcmp one double %call, 0.000000e+00
    286   %conv = zext i1 %cmp to i32
    287   ret i32 %conv
    288 }
    289 
    290 define i32 @test15_intrinsic(double %a) {
    291 ; CHECK-LABEL: @test15_intrinsic(
    292 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
    293 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    294 ; CHECK-NEXT:    ret i32 [[CONV]]
    295 ;
    296   %call = tail call double @llvm.fabs.f64(double %a)
    297   %cmp = fcmp one double %call, 0.000000e+00
    298   %conv = zext i1 %cmp to i32
    299   ret i32 %conv
    300 }
    301 
    302 define i32 @test16(double %a) {
    303 ; CHECK-LABEL: @test16(
    304 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[A:%.*]], 0.000000e+00
    305 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    306 ; CHECK-NEXT:    ret i32 [[CONV]]
    307 ;
    308   %call = tail call double @fabs(double %a)
    309   %cmp = fcmp ueq double %call, 0.000000e+00
    310   %conv = zext i1 %cmp to i32
    311   ret i32 %conv
    312 }
    313 
    314 define i32 @test16_intrinsic(double %a) {
    315 ; CHECK-LABEL: @test16_intrinsic(
    316 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[A:%.*]], 0.000000e+00
    317 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    318 ; CHECK-NEXT:    ret i32 [[CONV]]
    319 ;
    320   %call = tail call double @llvm.fabs.f64(double %a)
    321   %cmp = fcmp ueq double %call, 0.000000e+00
    322   %conv = zext i1 %cmp to i32
    323   ret i32 %conv
    324 }
    325 
    326 ; Don't crash.
    327 define i32 @test17(double %a, double (double)* %p) {
    328 ; CHECK-LABEL: @test17(
    329 ; CHECK-NEXT:    [[CALL:%.*]] = tail call double [[P:%.*]](double [[A:%.*]])
    330 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[CALL]], 0.000000e+00
    331 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
    332 ; CHECK-NEXT:    ret i32 [[CONV]]
    333 ;
    334   %call = tail call double %p(double %a)
    335   %cmp = fcmp ueq double %call, 0.000000e+00
    336   %conv = zext i1 %cmp to i32
    337   ret i32 %conv
    338 }
    339 
    340 ; Can fold fcmp with undef on one side by choosing NaN for the undef
    341 define i32 @test18_undef_unordered(float %a) {
    342 ; CHECK-LABEL: @test18_undef_unordered(
    343 ; CHECK-NEXT:    ret i32 1
    344 ;
    345   %cmp = fcmp ueq float %a, undef
    346   %conv = zext i1 %cmp to i32
    347   ret i32 %conv
    348 }
    349 ; Can fold fcmp with undef on one side by choosing NaN for the undef
    350 define i32 @test18_undef_ordered(float %a) {
    351 ; CHECK-LABEL: @test18_undef_ordered(
    352 ; CHECK-NEXT:    ret i32 0
    353 ;
    354   %cmp = fcmp oeq float %a, undef
    355   %conv = zext i1 %cmp to i32
    356   ret i32 %conv
    357 }
    358 
    359 ; Can fold fcmp with undef on both side
    360 ;   fcmp u_pred undef, undef -> true
    361 ;   fcmp o_pred undef, undef -> false
    362 ; because whatever you choose for the first undef
    363 ; you can choose NaN for the other undef
    364 define i1 @test19_undef_unordered() {
    365 ; CHECK-LABEL: @test19_undef_unordered(
    366 ; CHECK-NEXT:    ret i1 true
    367 ;
    368   %cmp = fcmp ueq float undef, undef
    369   ret i1 %cmp
    370 }
    371 
    372 define i1 @test19_undef_ordered() {
    373 ; CHECK-LABEL: @test19_undef_ordered(
    374 ; CHECK-NEXT:    ret i1 false
    375 ;
    376   %cmp = fcmp oeq float undef, undef
    377   ret i1 %cmp
    378 }
    379 
    380