Home | History | Annotate | Download | only in InstSimplify
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt < %s -instsimplify -S | FileCheck %s
      3 
      4 ; Infinity
      5 
      6 define i1 @inf0(double %arg) {
      7 ; CHECK-LABEL: @inf0(
      8 ; CHECK-NEXT:    ret i1 false
      9 ;
     10   %tmp = fcmp ogt double %arg, 0x7FF0000000000000
     11   ret i1 %tmp
     12 }
     13 
     14 define i1 @inf1(double %arg) {
     15 ; CHECK-LABEL: @inf1(
     16 ; CHECK-NEXT:    ret i1 true
     17 ;
     18   %tmp = fcmp ule double %arg, 0x7FF0000000000000
     19   ret i1 %tmp
     20 }
     21 
     22 ; Negative infinity
     23 
     24 define i1 @ninf0(double %arg) {
     25 ; CHECK-LABEL: @ninf0(
     26 ; CHECK-NEXT:    ret i1 false
     27 ;
     28   %tmp = fcmp olt double %arg, 0xFFF0000000000000
     29   ret i1 %tmp
     30 }
     31 
     32 define i1 @ninf1(double %arg) {
     33 ; CHECK-LABEL: @ninf1(
     34 ; CHECK-NEXT:    ret i1 true
     35 ;
     36   %tmp = fcmp uge double %arg, 0xFFF0000000000000
     37   ret i1 %tmp
     38 }
     39 
     40 ; NaNs
     41 
     42 define i1 @nan0(double %arg) {
     43 ; CHECK-LABEL: @nan0(
     44 ; CHECK-NEXT:    ret i1 false
     45 ;
     46   %tmp = fcmp ord double %arg, 0x7FF00000FFFFFFFF
     47   ret i1 %tmp
     48 }
     49 
     50 define i1 @nan1(double %arg) {
     51 ; CHECK-LABEL: @nan1(
     52 ; CHECK-NEXT:    ret i1 false
     53 ;
     54   %tmp = fcmp oeq double %arg, 0x7FF00000FFFFFFFF
     55   ret i1 %tmp
     56 }
     57 
     58 define i1 @nan2(double %arg) {
     59 ; CHECK-LABEL: @nan2(
     60 ; CHECK-NEXT:    ret i1 false
     61 ;
     62   %tmp = fcmp olt double %arg, 0x7FF00000FFFFFFFF
     63   ret i1 %tmp
     64 }
     65 
     66 define i1 @nan3(double %arg) {
     67 ; CHECK-LABEL: @nan3(
     68 ; CHECK-NEXT:    ret i1 true
     69 ;
     70   %tmp = fcmp uno double %arg, 0x7FF00000FFFFFFFF
     71   ret i1 %tmp
     72 }
     73 
     74 define i1 @nan4(double %arg) {
     75 ; CHECK-LABEL: @nan4(
     76 ; CHECK-NEXT:    ret i1 true
     77 ;
     78   %tmp = fcmp une double %arg, 0x7FF00000FFFFFFFF
     79   ret i1 %tmp
     80 }
     81 
     82 define i1 @nan5(double %arg) {
     83 ; CHECK-LABEL: @nan5(
     84 ; CHECK-NEXT:    ret i1 true
     85 ;
     86   %tmp = fcmp ult double %arg, 0x7FF00000FFFFFFFF
     87   ret i1 %tmp
     88 }
     89 
     90 ; Negative NaN.
     91 
     92 define i1 @nnan0(double %arg) {
     93 ; CHECK-LABEL: @nnan0(
     94 ; CHECK-NEXT:    ret i1 false
     95 ;
     96   %tmp = fcmp ord double %arg, 0xFFF00000FFFFFFFF
     97   ret i1 %tmp
     98 }
     99 
    100 define i1 @nnan1(double %arg) {
    101 ; CHECK-LABEL: @nnan1(
    102 ; CHECK-NEXT:    ret i1 false
    103 ;
    104   %tmp = fcmp oeq double %arg, 0xFFF00000FFFFFFFF
    105   ret i1 %tmp
    106 }
    107 
    108 define i1 @nnan2(double %arg) {
    109 ; CHECK-LABEL: @nnan2(
    110 ; CHECK-NEXT:    ret i1 false
    111 ;
    112   %tmp = fcmp olt double %arg, 0xFFF00000FFFFFFFF
    113   ret i1 %tmp
    114 }
    115 
    116 define i1 @nnan3(double %arg) {
    117 ; CHECK-LABEL: @nnan3(
    118 ; CHECK-NEXT:    ret i1 true
    119 ;
    120   %tmp = fcmp uno double %arg, 0xFFF00000FFFFFFFF
    121   ret i1 %tmp
    122 }
    123 
    124 define i1 @nnan4(double %arg) {
    125 ; CHECK-LABEL: @nnan4(
    126 ; CHECK-NEXT:    ret i1 true
    127 ;
    128   %tmp = fcmp une double %arg, 0xFFF00000FFFFFFFF
    129   ret i1 %tmp
    130 }
    131 
    132 define i1 @nnan5(double %arg) {
    133 ; CHECK-LABEL: @nnan5(
    134 ; CHECK-NEXT:    ret i1 true
    135 ;
    136   %tmp = fcmp ult double %arg, 0xFFF00000FFFFFFFF
    137   ret i1 %tmp
    138 }
    139 
    140 ; Negative zero.
    141 
    142 define i1 @nzero0() {
    143 ; CHECK-LABEL: @nzero0(
    144 ; CHECK-NEXT:    ret i1 true
    145 ;
    146   %tmp = fcmp oeq double 0.0, -0.0
    147   ret i1 %tmp
    148 }
    149 
    150 define i1 @nzero1() {
    151 ; CHECK-LABEL: @nzero1(
    152 ; CHECK-NEXT:    ret i1 false
    153 ;
    154   %tmp = fcmp ogt double 0.0, -0.0
    155   ret i1 %tmp
    156 }
    157 
    158 ; No enlightenment here.
    159 
    160 define i1 @one_with_self(double %arg) {
    161 ; CHECK-LABEL: @one_with_self(
    162 ; CHECK-NEXT:    ret i1 false
    163 ;
    164   %tmp = fcmp one double %arg, %arg
    165   ret i1 %tmp
    166 }
    167 
    168 ; These tests choose arbitrarily between float and double,
    169 ; and between uge and olt, to give reasonble coverage
    170 ; without combinatorial explosion.
    171 
    172 declare half @llvm.fabs.f16(half)
    173 declare float @llvm.fabs.f32(float)
    174 declare double @llvm.fabs.f64(double)
    175 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
    176 declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
    177 declare float @llvm.sqrt.f32(float)
    178 declare double @llvm.powi.f64(double,i32)
    179 declare float @llvm.exp.f32(float)
    180 declare float @llvm.minnum.f32(float, float)
    181 declare float @llvm.maxnum.f32(float, float)
    182 declare double @llvm.exp2.f64(double)
    183 declare float @llvm.fma.f32(float,float,float)
    184 
    185 declare void @expect_equal(i1,i1)
    186 
    187 define i1 @orderedLessZeroTree(float,float,float,float) {
    188 ; CHECK-LABEL: @orderedLessZeroTree(
    189 ; CHECK-NEXT:    ret i1 true
    190 ;
    191   %square = fmul float %0, %0
    192   %abs = call float @llvm.fabs.f32(float %1)
    193   %sqrt = call float @llvm.sqrt.f32(float %2)
    194   %fma = call float @llvm.fma.f32(float %3, float %3, float %sqrt)
    195   %div = fdiv float %square, %abs
    196   %rem = frem float %sqrt, %fma
    197   %add = fadd float %div, %rem
    198   %uge = fcmp uge float %add, 0.000000e+00
    199   ret i1 %uge
    200 }
    201 
    202 define i1 @orderedLessZeroExpExt(float) {
    203 ; CHECK-LABEL: @orderedLessZeroExpExt(
    204 ; CHECK-NEXT:    ret i1 true
    205 ;
    206   %a = call float @llvm.exp.f32(float %0)
    207   %b = fpext float %a to double
    208   %uge = fcmp uge double %b, 0.000000e+00
    209   ret i1 %uge
    210 }
    211 
    212 define i1 @orderedLessZeroExp2Trunc(double) {
    213 ; CHECK-LABEL: @orderedLessZeroExp2Trunc(
    214 ; CHECK-NEXT:    ret i1 false
    215 ;
    216   %a = call double @llvm.exp2.f64(double %0)
    217   %b = fptrunc double %a to float
    218   %olt = fcmp olt float %b, 0.000000e+00
    219   ret i1 %olt
    220 }
    221 
    222 define i1 @orderedLessZeroPowi(double,double) {
    223 ; CHECK-LABEL: @orderedLessZeroPowi(
    224 ; CHECK-NEXT:    ret i1 false
    225 ;
    226   ; Even constant exponent
    227   %a = call double @llvm.powi.f64(double %0, i32 2)
    228   %square = fmul double %1, %1
    229   ; Odd constant exponent with provably non-negative base
    230   %b = call double @llvm.powi.f64(double %square, i32 3)
    231   %c = fadd double %a, %b
    232   %olt = fcmp olt double %b, 0.000000e+00
    233   ret i1 %olt
    234 }
    235 
    236 define i1 @orderedLessZeroUIToFP(i32) {
    237 ; CHECK-LABEL: @orderedLessZeroUIToFP(
    238 ; CHECK-NEXT:    ret i1 true
    239 ;
    240   %a = uitofp i32 %0 to float
    241   %uge = fcmp uge float %a, 0.000000e+00
    242   ret i1 %uge
    243 }
    244 
    245 define i1 @orderedLessZeroSelect(float, float) {
    246 ; CHECK-LABEL: @orderedLessZeroSelect(
    247 ; CHECK-NEXT:    ret i1 true
    248 ;
    249   %a = call float @llvm.exp.f32(float %0)
    250   %b = call float @llvm.fabs.f32(float %1)
    251   %c = fcmp olt float %0, %1
    252   %d = select i1 %c, float %a, float %b
    253   %e = fadd float %d, 1.0
    254   %uge = fcmp uge float %e, 0.000000e+00
    255   ret i1 %uge
    256 }
    257 
    258 define i1 @orderedLessZeroMinNum(float, float) {
    259 ; CHECK-LABEL: @orderedLessZeroMinNum(
    260 ; CHECK-NEXT:    ret i1 true
    261 ;
    262   %a = call float @llvm.exp.f32(float %0)
    263   %b = call float @llvm.fabs.f32(float %1)
    264   %c = call float @llvm.minnum.f32(float %a, float %b)
    265   %uge = fcmp uge float %c, 0.000000e+00
    266   ret i1 %uge
    267 }
    268 
    269 ; PR37776: https://bugs.llvm.org/show_bug.cgi?id=37776
    270 ; exp() may return nan, leaving %1 as the unknown result, so we can't simplify.
    271 
    272 define i1 @orderedLessZeroMaxNum(float, float) {
    273 ; CHECK-LABEL: @orderedLessZeroMaxNum(
    274 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.exp.f32(float [[TMP0:%.*]])
    275 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[TMP1:%.*]])
    276 ; CHECK-NEXT:    [[UGE:%.*]] = fcmp uge float [[B]], 0.000000e+00
    277 ; CHECK-NEXT:    ret i1 [[UGE]]
    278 ;
    279   %a = call float @llvm.exp.f32(float %0)
    280   %b = call float @llvm.maxnum.f32(float %a, float %1)
    281   %uge = fcmp uge float %b, 0.000000e+00
    282   ret i1 %uge
    283 }
    284 
    285 define i1 @known_positive_olt_with_negative_constant(double %a) {
    286 ; CHECK-LABEL: @known_positive_olt_with_negative_constant(
    287 ; CHECK-NEXT:    ret i1 false
    288 ;
    289   %call = call double @llvm.fabs.f64(double %a)
    290   %cmp = fcmp olt double %call, -1.0
    291   ret i1 %cmp
    292 }
    293 
    294 define <2 x i1> @known_positive_ole_with_negative_constant_splat_vec(<2 x i32> %a) {
    295 ; CHECK-LABEL: @known_positive_ole_with_negative_constant_splat_vec(
    296 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
    297 ;
    298   %call = uitofp <2 x i32> %a to <2 x double>
    299   %cmp = fcmp ole <2 x double> %call, <double -2.0, double -2.0>
    300   ret <2 x i1> %cmp
    301 }
    302 
    303 define i1 @known_positive_ugt_with_negative_constant(i32 %a) {
    304 ; CHECK-LABEL: @known_positive_ugt_with_negative_constant(
    305 ; CHECK-NEXT:    ret i1 true
    306 ;
    307   %call = uitofp i32 %a to float
    308   %cmp = fcmp ugt float %call, -3.0
    309   ret i1 %cmp
    310 }
    311 
    312 define <2 x i1> @known_positive_uge_with_negative_constant_splat_vec(<2 x float> %a) {
    313 ; CHECK-LABEL: @known_positive_uge_with_negative_constant_splat_vec(
    314 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
    315 ;
    316   %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
    317   %cmp = fcmp uge <2 x float> %call, <float -4.0, float -4.0>
    318   ret <2 x i1> %cmp
    319 }
    320 
    321 define i1 @known_positive_oeq_with_negative_constant(half %a) {
    322 ; CHECK-LABEL: @known_positive_oeq_with_negative_constant(
    323 ; CHECK-NEXT:    ret i1 false
    324 ;
    325   %call = call half @llvm.fabs.f16(half %a)
    326   %cmp = fcmp oeq half %call, -5.0
    327   ret i1 %cmp
    328 }
    329 
    330 define <2 x i1> @known_positive_une_with_negative_constant_splat_vec(<2 x i32> %a) {
    331 ; CHECK-LABEL: @known_positive_une_with_negative_constant_splat_vec(
    332 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
    333 ;
    334   %call = uitofp <2 x i32> %a to <2 x half>
    335   %cmp = fcmp une <2 x half> %call, <half -6.0, half -6.0>
    336   ret <2 x i1> %cmp
    337 }
    338 
    339 define i1 @nonans1(double %in1, double %in2) {
    340 ; CHECK-LABEL: @nonans1(
    341 ; CHECK-NEXT:    ret i1 false
    342 ;
    343   %cmp = fcmp nnan uno double %in1, %in2
    344   ret i1 %cmp
    345 }
    346 
    347 define i1 @nonans2(double %in1, double %in2) {
    348 ; CHECK-LABEL: @nonans2(
    349 ; CHECK-NEXT:    ret i1 true
    350 ;
    351   %cmp = fcmp nnan ord double %in1, %in2
    352   ret i1 %cmp
    353 }
    354 
    355 define <2 x i1> @orderedCompareWithNaNVector(<2 x double> %A) {
    356 ; CHECK-LABEL: @orderedCompareWithNaNVector(
    357 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
    358 ;
    359   %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
    360   ret <2 x i1> %cmp
    361 }
    362 
    363 define <2 x i1> @orderedCompareWithNaNVector_undef_elt(<2 x double> %A) {
    364 ; CHECK-LABEL: @orderedCompareWithNaNVector_undef_elt(
    365 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
    366 ;
    367   %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double undef>
    368   ret <2 x i1> %cmp
    369 }
    370 
    371 define <2 x i1> @unorderedCompareWithNaNVector_undef_elt(<2 x double> %A) {
    372 ; CHECK-LABEL: @unorderedCompareWithNaNVector_undef_elt(
    373 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
    374 ;
    375   %cmp = fcmp ult <2 x double> %A, <double undef, double 0xFFFFFFFFFFFFFFFF>
    376   ret <2 x i1> %cmp
    377 }
    378 
    379