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 ; (X < C1) ? C1 : MIN(X, C2)
      5 define float @clamp_float_fast_ordered_strict_maxmin(float %x) {
      6 ;
      7 ; CHECK-LABEL: @clamp_float_fast_ordered_strict_maxmin(
      8 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
      9 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
     10 ; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
     11 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
     12 ; CHECK-NEXT:    ret float [[R1]]
     13 ;
     14   %cmp2 = fcmp fast olt float %x, 255.0
     15   %min = select i1 %cmp2, float %x, float 255.0
     16   %cmp1 = fcmp fast olt float %x, 1.0
     17   %r = select i1 %cmp1, float 1.0, float %min
     18   ret float %r
     19 }
     20 
     21 ; (X <= C1) ? C1 : MIN(X, C2)
     22 define float @clamp_float_fast_ordered_nonstrict_maxmin(float %x) {
     23 ;
     24 ; CHECK-LABEL: @clamp_float_fast_ordered_nonstrict_maxmin(
     25 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
     26 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
     27 ; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
     28 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
     29 ; CHECK-NEXT:    ret float [[R1]]
     30 ;
     31   %cmp2 = fcmp fast olt float %x, 255.0
     32   %min = select i1 %cmp2, float %x, float 255.0
     33   %cmp1 = fcmp fast ole float %x, 1.0
     34   %r = select i1 %cmp1, float 1.0, float %min
     35   ret float %r
     36 }
     37 
     38 ; (X > C1) ? C1 : MAX(X, C2)
     39 define float @clamp_float_fast_ordered_strict_minmax(float %x) {
     40 ;
     41 ; CHECK-LABEL: @clamp_float_fast_ordered_strict_minmax(
     42 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp fast ogt float [[X:%.*]], 1.000000e+00
     43 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
     44 ; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
     45 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
     46 ; CHECK-NEXT:    ret float [[R1]]
     47 ;
     48   %cmp2 = fcmp fast ogt float %x, 1.0
     49   %max = select i1 %cmp2, float %x, float 1.0
     50   %cmp1 = fcmp fast ogt float %x, 255.0
     51   %r = select i1 %cmp1, float 255.0, float %max
     52   ret float %r
     53 }
     54 
     55 ; (X >= C1) ? C1 : MAX(X, C2)
     56 define float @clamp_float_fast_ordered_nonstrict_minmax(float %x) {
     57 ;
     58 ; CHECK-LABEL: @clamp_float_fast_ordered_nonstrict_minmax(
     59 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp fast ogt float [[X:%.*]], 1.000000e+00
     60 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
     61 ; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
     62 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
     63 ; CHECK-NEXT:    ret float [[R1]]
     64 ;
     65   %cmp2 = fcmp fast ogt float %x, 1.0
     66   %max = select i1 %cmp2, float %x, float 1.0
     67   %cmp1 = fcmp fast oge float %x, 255.0
     68   %r = select i1 %cmp1, float 255.0, float %max
     69   ret float %r
     70 }
     71 
     72 
     73 ; The same for unordered
     74 
     75 ; (X < C1) ? C1 : MIN(X, C2)
     76 define float @clamp_float_fast_unordered_strict_maxmin(float %x) {
     77 ;
     78 ; CHECK-LABEL: @clamp_float_fast_unordered_strict_maxmin(
     79 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp fast oge float [[X:%.*]], 2.550000e+02
     80 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2_INV]], float 2.550000e+02, float [[X]]
     81 ; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
     82 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
     83 ; CHECK-NEXT:    ret float [[R1]]
     84 ;
     85   %cmp2 = fcmp fast ult float %x, 255.0
     86   %min = select i1 %cmp2, float %x, float 255.0
     87   %cmp1 = fcmp fast ult float %x, 1.0
     88   %r = select i1 %cmp1, float 1.0, float %min
     89   ret float %r
     90 }
     91 
     92 ; (X <= C1) ? C1 : MIN(X, C2)
     93 define float @clamp_float_fast_unordered_nonstrict_maxmin(float %x) {
     94 ;
     95 ; CHECK-LABEL: @clamp_float_fast_unordered_nonstrict_maxmin(
     96 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp fast oge float [[X:%.*]], 2.550000e+02
     97 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2_INV]], float 2.550000e+02, float [[X]]
     98 ; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
     99 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
    100 ; CHECK-NEXT:    ret float [[R1]]
    101 ;
    102   %cmp2 = fcmp fast ult float %x, 255.0
    103   %min = select i1 %cmp2, float %x, float 255.0
    104   %cmp1 = fcmp fast ule float %x, 1.0
    105   %r = select i1 %cmp1, float 1.0, float %min
    106   ret float %r
    107 }
    108 
    109 ; (X > C1) ? C1 : MAX(X, C2)
    110 define float @clamp_float_fast_unordered_strict_minmax(float %x) {
    111 ;
    112 ; CHECK-LABEL: @clamp_float_fast_unordered_strict_minmax(
    113 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp fast ole float [[X:%.*]], 1.000000e+00
    114 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2_INV]], float 1.000000e+00, float [[X]]
    115 ; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
    116 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
    117 ; CHECK-NEXT:    ret float [[R1]]
    118 ;
    119   %cmp2 = fcmp fast ugt float %x, 1.0
    120   %max = select i1 %cmp2, float %x, float 1.0
    121   %cmp1 = fcmp fast ugt float %x, 255.0
    122   %r = select i1 %cmp1, float 255.0, float %max
    123   ret float %r
    124 }
    125 
    126 ; (X >= C1) ? C1 : MAX(X, C2)
    127 define float @clamp_float_fast_unordered_nonstrict_minmax(float %x) {
    128 ;
    129 ; CHECK-LABEL: @clamp_float_fast_unordered_nonstrict_minmax(
    130 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp fast ole float [[X:%.*]], 1.000000e+00
    131 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2_INV]], float 1.000000e+00, float [[X]]
    132 ; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
    133 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
    134 ; CHECK-NEXT:    ret float [[R1]]
    135 ;
    136   %cmp2 = fcmp fast ugt float %x, 1.0
    137   %max = select i1 %cmp2, float %x, float 1.0
    138   %cmp1 = fcmp fast uge float %x, 255.0
    139   %r = select i1 %cmp1, float 255.0, float %max
    140   ret float %r
    141 }
    142 
    143 ; Some more checks with fast
    144 
    145 ; (X > 1.0) ? min(x, 255.0) : 1.0
    146 ; That did not match because select was in inverse order.
    147 define float @clamp_test_1(float %x) {
    148 ; CHECK-LABEL: @clamp_test_1(
    149 ; CHECK-NEXT:    [[INNER_CMP_INV:%.*]] = fcmp fast oge float [[X:%.*]], 2.550000e+02
    150 ; CHECK-NEXT:    [[INNER_SEL:%.*]] = select i1 [[INNER_CMP_INV]], float 2.550000e+02, float [[X]]
    151 ; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp fast oge float [[INNER_SEL]], 1.000000e+00
    152 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[DOTINV]], float [[INNER_SEL]], float 1.000000e+00
    153 ; CHECK-NEXT:    ret float [[R1]]
    154 ;
    155   %inner_cmp = fcmp fast ult float %x, 255.0
    156   %inner_sel = select i1 %inner_cmp, float %x, float 255.0
    157   %outer_cmp = fcmp fast ugt float %x, 1.0
    158   %r = select i1 %outer_cmp, float %inner_sel, float 1.0
    159   ret float %r
    160 }
    161 
    162 ; And something negative
    163 
    164 ; Like @clamp_test_1 but HighConst < LowConst
    165 define float @clamp_negative_wrong_const(float %x) {
    166 ; CHECK-LABEL: @clamp_negative_wrong_const(
    167 ; CHECK-NEXT:    [[INNER_CMP_INV:%.*]] = fcmp fast oge float [[X:%.*]], 2.550000e+02
    168 ; CHECK-NEXT:    [[INNER_SEL:%.*]] = select i1 [[INNER_CMP_INV]], float 2.550000e+02, float [[X]]
    169 ; CHECK-NEXT:    [[OUTER_CMP:%.*]] = fcmp fast ugt float [[X]], 5.120000e+02
    170 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[OUTER_CMP]], float [[INNER_SEL]], float 5.120000e+02
    171 ; CHECK-NEXT:    ret float [[R]]
    172 ;
    173   %inner_cmp = fcmp fast ult float %x, 255.0
    174   %inner_sel = select i1 %inner_cmp, float %x, float 255.0
    175   %outer_cmp = fcmp fast ugt float %x, 512.0
    176   %r = select i1 %outer_cmp, float %inner_sel, float 512.0
    177   ret float %r
    178 }
    179 
    180 ; Like @clamp_test_1 but both are min
    181 define float @clamp_negative_same_op(float %x) {
    182 ; CHECK-LABEL: @clamp_negative_same_op(
    183 ; CHECK-NEXT:    [[INNER_CMP_INV:%.*]] = fcmp fast oge float [[X:%.*]], 2.550000e+02
    184 ; CHECK-NEXT:    [[INNER_SEL:%.*]] = select i1 [[INNER_CMP_INV]], float 2.550000e+02, float [[X]]
    185 ; CHECK-NEXT:    [[OUTER_CMP:%.*]] = fcmp fast ult float [[X]], 1.000000e+00
    186 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[OUTER_CMP]], float [[INNER_SEL]], float 1.000000e+00
    187 ; CHECK-NEXT:    ret float [[R]]
    188 ;
    189   %inner_cmp = fcmp fast ult float %x, 255.0
    190   %inner_sel = select i1 %inner_cmp, float %x, float 255.0
    191   %outer_cmp = fcmp fast ult float %x, 1.0
    192   %r = select i1 %outer_cmp, float %inner_sel, float 1.0
    193   ret float %r
    194 }
    195 
    196 
    197 ; And now without fast.
    198 
    199 ; First, check that we don't do bad things in the presence of signed zeros
    200 define float @clamp_float_with_zero1(float %x) {
    201 ; CHECK-LABEL: @clamp_float_with_zero1(
    202 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
    203 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
    204 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ole float [[X]], 0.000000e+00
    205 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 0.000000e+00, float [[MIN]]
    206 ; CHECK-NEXT:    ret float [[R]]
    207 ;
    208   %cmp2 = fcmp fast olt float %x, 255.0
    209   %min = select i1 %cmp2, float %x, float 255.0
    210   %cmp1 = fcmp ole float %x, 0.0
    211   %r = select i1 %cmp1, float 0.0, float %min
    212   ret float %r
    213 }
    214 
    215 define float @clamp_float_with_zero2(float %x) {
    216 ; CHECK-LABEL: @clamp_float_with_zero2(
    217 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
    218 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
    219 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp olt float [[X]], 0.000000e+00
    220 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 0.000000e+00, float [[MIN]]
    221 ; CHECK-NEXT:    ret float [[R]]
    222 ;
    223   %cmp2 = fcmp fast olt float %x, 255.0
    224   %min = select i1 %cmp2, float %x, float 255.0
    225   %cmp1 = fcmp olt float %x, 0.0
    226   %r = select i1 %cmp1, float 0.0, float %min
    227   ret float %r
    228 }
    229 
    230 ; Also, here we care more about the ordering of the inner min/max, so
    231 ; two times more cases.
    232 ; TODO: that is not implemented yet, so these checks are for the
    233 ;       future. This means that checks below can just check that
    234 ;       "fcmp.*%x" happens twice for each label.
    235 
    236 ; (X < C1) ? C1 : MIN(X, C2)
    237 define float @clamp_float_ordered_strict_maxmin1(float %x) {
    238 ;
    239 ; CHECK-LABEL: @clamp_float_ordered_strict_maxmin1(
    240 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
    241 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
    242 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp olt float [[X]], 1.000000e+00
    243 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
    244 ; CHECK-NEXT:    ret float [[R]]
    245 ;
    246   %cmp2 = fcmp olt float %x, 255.0                   ; X is NaN => false
    247   %min = select i1 %cmp2, float %x, float 255.0      ;             255.0
    248   %cmp1 = fcmp olt float %x, 1.0                     ;             false
    249   %r = select i1 %cmp1, float 1.0, float %min        ;             min (255.0)
    250   ret float %r
    251 }
    252 
    253 define float @clamp_float_ordered_strict_maxmin2(float %x) {
    254 ;
    255 ; CHECK-LABEL: @clamp_float_ordered_strict_maxmin2(
    256 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp oge float [[X:%.*]], 2.550000e+02
    257 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2_INV]], float 2.550000e+02, float [[X]]
    258 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp olt float [[X]], 1.000000e+00
    259 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
    260 ; CHECK-NEXT:    ret float [[R]]
    261 ;
    262   %cmp2 = fcmp ult float %x, 255.0                  ; X is NaN => true
    263   %min = select i1 %cmp2, float %x, float 255.0     ;             NaN
    264   %cmp1 = fcmp olt float %x, 1.0                    ;             false
    265   %r = select i1 %cmp1, float 1.0, float %min       ;             min (NaN)
    266   ret float %r
    267 }
    268 
    269 ; (X <= C1) ? C1 : MIN(X, C2)
    270 define float @clamp_float_ordered_nonstrict_maxmin1(float %x) {
    271 ;
    272 ; CHECK-LABEL: @clamp_float_ordered_nonstrict_maxmin1(
    273 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
    274 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
    275 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ole float [[X]], 1.000000e+00
    276 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
    277 ; CHECK-NEXT:    ret float [[R]]
    278 ;
    279   %cmp2 = fcmp olt float %x, 255.0                  ; X is NaN => false
    280   %min = select i1 %cmp2, float %x, float 255.0     ;             255.0
    281   %cmp1 = fcmp ole float %x, 1.0                    ;             false
    282   %r = select i1 %cmp1, float 1.0, float %min       ;             min (255.0)
    283   ret float %r
    284 }
    285 
    286 define float @clamp_float_ordered_nonstrict_maxmin2(float %x) {
    287 ;
    288 ; CHECK-LABEL: @clamp_float_ordered_nonstrict_maxmin2(
    289 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp oge float [[X:%.*]], 2.550000e+02
    290 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2_INV]], float 2.550000e+02, float [[X]]
    291 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ole float [[X]], 1.000000e+00
    292 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
    293 ; CHECK-NEXT:    ret float [[R]]
    294 ;
    295   %cmp2 = fcmp ult float %x, 255.0                  ; x is NaN => true
    296   %min = select i1 %cmp2, float %x, float 255.0     ;             NaN
    297   %cmp1 = fcmp ole float %x, 1.0                    ;             false
    298   %r = select i1 %cmp1, float 1.0, float %min       ;             min (NaN)
    299   ret float %r
    300 }
    301 
    302 ; (X > C1) ? C1 : MAX(X, C2)
    303 define float @clamp_float_ordered_strict_minmax1(float %x) {
    304 ;
    305 ; CHECK-LABEL: @clamp_float_ordered_strict_minmax1(
    306 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
    307 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
    308 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ogt float [[X]], 2.550000e+02
    309 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
    310 ; CHECK-NEXT:    ret float [[R]]
    311 ;
    312   %cmp2 = fcmp ogt float %x, 1.0                    ; x is NaN => false
    313   %max = select i1 %cmp2, float %x, float 1.0       ;             1.0
    314   %cmp1 = fcmp ogt float %x, 255.0                  ;             false
    315   %r = select i1 %cmp1, float 255.0, float %max     ;             max (1.0)
    316   ret float %r
    317 }
    318 
    319 define float @clamp_float_ordered_strict_minmax2(float %x) {
    320 ;
    321 ; CHECK-LABEL: @clamp_float_ordered_strict_minmax2(
    322 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp ole float [[X:%.*]], 1.000000e+00
    323 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2_INV]], float 1.000000e+00, float [[X]]
    324 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ogt float [[X]], 2.550000e+02
    325 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
    326 ; CHECK-NEXT:    ret float [[R]]
    327 ;
    328   %cmp2 = fcmp ugt float %x, 1.0                    ; x is NaN => true
    329   %max = select i1 %cmp2, float %x, float 1.0       ;             NaN
    330   %cmp1 = fcmp ogt float %x, 255.0                  ;             false
    331   %r = select i1 %cmp1, float 255.0, float %max     ;             max (NaN)
    332   ret float %r
    333 }
    334 
    335 ; (X >= C1) ? C1 : MAX(X, C2)
    336 define float @clamp_float_ordered_nonstrict_minmax1(float %x) {
    337 ;
    338 ; CHECK-LABEL: @clamp_float_ordered_nonstrict_minmax1(
    339 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
    340 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
    341 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp oge float [[X]], 2.550000e+02
    342 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
    343 ; CHECK-NEXT:    ret float [[R]]
    344 ;
    345   %cmp2 = fcmp ogt float %x, 1.0                    ; x is NaN => false
    346   %max = select i1 %cmp2, float %x, float 1.0       ;             1.0
    347   %cmp1 = fcmp oge float %x, 255.0                  ;             false
    348   %r = select i1 %cmp1, float 255.0, float %max     ;             max (1.0)
    349   ret float %r
    350 }
    351 
    352 define float @clamp_float_ordered_nonstrict_minmax2(float %x) {
    353 ;
    354 ; CHECK-LABEL: @clamp_float_ordered_nonstrict_minmax2(
    355 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp ole float [[X:%.*]], 1.000000e+00
    356 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2_INV]], float 1.000000e+00, float [[X]]
    357 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp oge float [[X]], 2.550000e+02
    358 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
    359 ; CHECK-NEXT:    ret float [[R]]
    360 ;
    361   %cmp2 = fcmp ugt float %x, 1.0                    ; x is NaN => true
    362   %max = select i1 %cmp2, float %x, float 1.0       ;             NaN
    363   %cmp1 = fcmp oge float %x, 255.0                  ;             false
    364   %r = select i1 %cmp1, float 255.0, float %max     ;             max (NaN)
    365   ret float %r
    366 }
    367 
    368 
    369 ; The same for unordered
    370 
    371 ; (X < C1) ? C1 : MIN(X, C2)
    372 define float @clamp_float_unordered_strict_maxmin1(float %x) {
    373 ;
    374 ; CHECK-LABEL: @clamp_float_unordered_strict_maxmin1(
    375 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
    376 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
    377 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ult float [[X]], 1.000000e+00
    378 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
    379 ; CHECK-NEXT:    ret float [[R]]
    380 ;
    381   %cmp2 = fcmp olt float %x, 255.0                  ; x is NaN => false
    382   %min = select i1 %cmp2, float %x, float 255.0     ;             255.0
    383   %cmp1 = fcmp ult float %x, 1.0                    ;             true
    384   %r = select i1 %cmp1, float 1.0, float %min       ;             1.0
    385   ret float %r
    386 }
    387 
    388 define float @clamp_float_unordered_strict_maxmin2(float %x) {
    389 ;
    390 ; CHECK-LABEL: @clamp_float_unordered_strict_maxmin2(
    391 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp oge float [[X:%.*]], 2.550000e+02
    392 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2_INV]], float 2.550000e+02, float [[X]]
    393 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ult float [[X]], 1.000000e+00
    394 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
    395 ; CHECK-NEXT:    ret float [[R]]
    396 ;
    397   %cmp2 = fcmp ult float %x, 255.0                  ; x is NaN => true
    398   %min = select i1 %cmp2, float %x, float 255.0     ;             NaN
    399   %cmp1 = fcmp ult float %x, 1.0                    ;             true
    400   %r = select i1 %cmp1, float 1.0, float %min       ;             1.0
    401   ret float %r
    402 }
    403 
    404 ; (X <= C1) ? C1 : MIN(X, C2)
    405 define float @clamp_float_unordered_nonstrict_maxmin1(float %x) {
    406 ;
    407 ; CHECK-LABEL: @clamp_float_unordered_nonstrict_maxmin1(
    408 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
    409 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
    410 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ule float [[X]], 1.000000e+00
    411 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
    412 ; CHECK-NEXT:    ret float [[R]]
    413 ;
    414   %cmp2 = fcmp olt float %x, 255.0                  ; x is NaN => false
    415   %min = select i1 %cmp2, float %x, float 255.0     ;             255.0
    416   %cmp1 = fcmp ule float %x, 1.0                    ;             true
    417   %r = select i1 %cmp1, float 1.0, float %min       ;             1.0
    418   ret float %r
    419 }
    420 
    421 define float @clamp_float_unordered_nonstrict_maxmin2(float %x) {
    422 ;
    423 ; CHECK-LABEL: @clamp_float_unordered_nonstrict_maxmin2(
    424 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp oge float [[X:%.*]], 2.550000e+02
    425 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP2_INV]], float 2.550000e+02, float [[X]]
    426 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ule float [[X]], 1.000000e+00
    427 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
    428 ; CHECK-NEXT:    ret float [[R]]
    429 ;
    430   %cmp2 = fcmp ult float %x, 255.0                  ; x is NaN => true
    431   %min = select i1 %cmp2, float %x, float 255.0     ;             NaN
    432   %cmp1 = fcmp ule float %x, 1.0                    ;             true
    433   %r = select i1 %cmp1, float 1.0, float %min       ;             1.0
    434   ret float %r
    435 }
    436 
    437 ; (X > C1) ? C1 : MAX(X, C2)
    438 define float @clamp_float_unordered_strict_minmax1(float %x) {
    439 ;
    440 ; CHECK-LABEL: @clamp_float_unordered_strict_minmax1(
    441 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
    442 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
    443 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ugt float [[X]], 2.550000e+02
    444 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
    445 ; CHECK-NEXT:    ret float [[R]]
    446 ;
    447   %cmp2 = fcmp ogt float %x, 1.0                    ; x is NaN => false
    448   %max = select i1 %cmp2, float %x, float 1.0       ;             1.0
    449   %cmp1 = fcmp ugt float %x, 255.0                  ;             true
    450   %r = select i1 %cmp1, float 255.0, float %max     ;             255.0
    451   ret float %r
    452 }
    453 
    454 define float @clamp_float_unordered_strict_minmax2(float %x) {
    455 ;
    456 ; CHECK-LABEL: @clamp_float_unordered_strict_minmax2(
    457 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp ole float [[X:%.*]], 1.000000e+00
    458 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2_INV]], float 1.000000e+00, float [[X]]
    459 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ugt float [[X]], 2.550000e+02
    460 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
    461 ; CHECK-NEXT:    ret float [[R]]
    462 ;
    463   %cmp2 = fcmp ugt float %x, 1.0                    ; x is NaN => true
    464   %max = select i1 %cmp2, float %x, float 1.0       ;             NaN
    465   %cmp1 = fcmp ugt float %x, 255.0                  ;             true
    466   %r = select i1 %cmp1, float 255.0, float %max     ;             255.0
    467   ret float %r
    468 }
    469 
    470 ; (X >= C1) ? C1 : MAX(X, C2)
    471 define float @clamp_float_unordered_nonstrict_minmax1(float %x) {
    472 ;
    473 ; CHECK-LABEL: @clamp_float_unordered_nonstrict_minmax1(
    474 ; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
    475 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
    476 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uge float [[X]], 2.550000e+02
    477 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
    478 ; CHECK-NEXT:    ret float [[R]]
    479 ;
    480   %cmp2 = fcmp ogt float %x, 1.0                    ; x is NaN => false
    481   %max = select i1 %cmp2, float %x, float 1.0       ;             1.0
    482   %cmp1 = fcmp uge float %x, 255.0                  ;             true
    483   %r = select i1 %cmp1, float 255.0, float %max     ;             255.0
    484   ret float %r
    485 }
    486 
    487 define float @clamp_float_unordered_nonstrict_minmax2(float %x) {
    488 ;
    489 ; CHECK-LABEL: @clamp_float_unordered_nonstrict_minmax2(
    490 ; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp ole float [[X:%.*]], 1.000000e+00
    491 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP2_INV]], float 1.000000e+00, float [[X]]
    492 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uge float [[X]], 2.550000e+02
    493 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
    494 ; CHECK-NEXT:    ret float [[R]]
    495 ;
    496   %cmp2 = fcmp ugt float %x, 1.0                    ; x is NaN => true
    497   %max = select i1 %cmp2, float %x, float 1.0       ;             NaN
    498   %cmp1 = fcmp uge float %x, 255.0                  ;             true
    499   %r = select i1 %cmp1, float 255.0, float %max     ;             255.0
    500   ret float %r
    501 }
    502 
    503 ;; Check casts behavior
    504 define float @ui32_clamp_and_cast_to_float(i32 %x) {
    505 ; CHECK-LABEL: @ui32_clamp_and_cast_to_float(
    506 ; CHECK-NEXT:    [[LO_CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
    507 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X]], 255
    508 ; CHECK-NEXT:    [[MIN1:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 255
    509 ; CHECK-NEXT:    [[TMP2:%.*]] = uitofp i32 [[MIN1]] to float
    510 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[LO_CMP]], float 1.000000e+00, float [[TMP2]]
    511 ; CHECK-NEXT:    ret float [[R]]
    512 ;
    513   %f_x = uitofp i32 %x to float
    514   %up_cmp = icmp ugt i32 %x, 255
    515   %lo_cmp = icmp ult i32 %x, 1
    516   %min = select i1 %up_cmp, float 255.0, float %f_x
    517   %r = select i1 %lo_cmp, float 1.0, float %min
    518   ret float %r
    519 }
    520 
    521 define float @ui64_clamp_and_cast_to_float(i64 %x) {
    522 ; CHECK-LABEL: @ui64_clamp_and_cast_to_float(
    523 ; CHECK-NEXT:    [[LO_CMP:%.*]] = icmp eq i64 [[X:%.*]], 0
    524 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[X]], 255
    525 ; CHECK-NEXT:    [[MIN1:%.*]] = select i1 [[TMP1]], i64 [[X]], i64 255
    526 ; CHECK-NEXT:    [[TMP2:%.*]] = uitofp i64 [[MIN1]] to float
    527 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[LO_CMP]], float 1.000000e+00, float [[TMP2]]
    528 ; CHECK-NEXT:    ret float [[R]]
    529 ;
    530   %f_x = uitofp i64 %x to float
    531   %up_cmp = icmp ugt i64 %x, 255
    532   %lo_cmp = icmp ult i64 %x, 1
    533   %min = select i1 %up_cmp, float 255.0, float %f_x
    534   %r = select i1 %lo_cmp, float 1.0, float %min
    535   ret float %r
    536 }
    537 
    538 define float @mixed_clamp_to_float_1(i32 %x) {
    539 ; CHECK-LABEL: @mixed_clamp_to_float_1(
    540 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 255
    541 ; CHECK-NEXT:    [[SI_MIN:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 255
    542 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[SI_MIN]], 1
    543 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[TMP2]], i32 [[SI_MIN]], i32 1
    544 ; CHECK-NEXT:    [[TMP3:%.*]] = sitofp i32 [[R1]] to float
    545 ; CHECK-NEXT:    ret float [[TMP3]]
    546 ;
    547   %si_min_cmp = icmp sgt i32 %x, 255
    548   %si_min = select i1 %si_min_cmp, i32 255, i32 %x
    549   %f_min = sitofp i32 %si_min to float
    550   %f_x = sitofp i32 %x to float
    551   %lo_cmp = fcmp ult float %f_x, 1.0
    552   %r = select i1 %lo_cmp, float 1.0, float %f_min
    553   ret float %r
    554 }
    555 
    556 define i32 @mixed_clamp_to_i32_1(float %x) {
    557 ; CHECK-LABEL: @mixed_clamp_to_i32_1(
    558 ; CHECK-NEXT:    [[FLOAT_MIN_CMP:%.*]] = fcmp ogt float [[X:%.*]], 2.550000e+02
    559 ; CHECK-NEXT:    [[FLOAT_MIN:%.*]] = select i1 [[FLOAT_MIN_CMP]], float 2.550000e+02, float [[X]]
    560 ; CHECK-NEXT:    [[I32_MIN:%.*]] = fptosi float [[FLOAT_MIN]] to i32
    561 ; CHECK-NEXT:    [[I32_X:%.*]] = fptosi float [[X]] to i32
    562 ; CHECK-NEXT:    [[LO_CMP:%.*]] = icmp eq i32 [[I32_X]], 0
    563 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[LO_CMP]], i32 1, i32 [[I32_MIN]]
    564 ; CHECK-NEXT:    ret i32 [[R]]
    565 ;
    566   %float_min_cmp = fcmp ogt float %x, 255.0
    567   %float_min = select i1 %float_min_cmp, float 255.0, float %x
    568   %i32_min = fptosi float %float_min to i32
    569   %i32_x = fptosi float %x to i32
    570   %lo_cmp = icmp ult i32 %i32_x, 1
    571   %r = select i1 %lo_cmp, i32 1, i32 %i32_min
    572   ret i32 %r
    573 }
    574 
    575 define float @mixed_clamp_to_float_2(i32 %x) {
    576 ; CHECK-LABEL: @mixed_clamp_to_float_2(
    577 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 255
    578 ; CHECK-NEXT:    [[SI_MIN:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 255
    579 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[SI_MIN]], 1
    580 ; CHECK-NEXT:    [[R1:%.*]] = select i1 [[TMP2]], i32 [[SI_MIN]], i32 1
    581 ; CHECK-NEXT:    [[TMP3:%.*]] = sitofp i32 [[R1]] to float
    582 ; CHECK-NEXT:    ret float [[TMP3]]
    583 ;
    584   %si_min_cmp = icmp sgt i32 %x, 255
    585   %si_min = select i1 %si_min_cmp, i32 255, i32 %x
    586   %f_min = sitofp i32 %si_min to float
    587   %lo_cmp = icmp slt i32 %x, 1
    588   %r = select i1 %lo_cmp, float 1.0, float %f_min
    589   ret float %r
    590 }
    591 
    592 define i32 @mixed_clamp_to_i32_2(float %x) {
    593 ; CHECK-LABEL: @mixed_clamp_to_i32_2(
    594 ; CHECK-NEXT:    [[FLOAT_MIN_CMP:%.*]] = fcmp ogt float [[X:%.*]], 2.550000e+02
    595 ; CHECK-NEXT:    [[FLOAT_MIN:%.*]] = select i1 [[FLOAT_MIN_CMP]], float 2.550000e+02, float [[X]]
    596 ; CHECK-NEXT:    [[I32_MIN:%.*]] = fptosi float [[FLOAT_MIN]] to i32
    597 ; CHECK-NEXT:    [[LO_CMP:%.*]] = fcmp olt float [[X]], 1.000000e+00
    598 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[LO_CMP]], i32 1, i32 [[I32_MIN]]
    599 ; CHECK-NEXT:    ret i32 [[R]]
    600 ;
    601   %float_min_cmp = fcmp ogt float %x, 255.0
    602   %float_min = select i1 %float_min_cmp, float 255.0, float %x
    603   %i32_min = fptosi float %float_min to i32
    604   %lo_cmp = fcmp olt float %x, 1.0
    605   %r = select i1 %lo_cmp, i32 1, i32 %i32_min
    606   ret i32 %r
    607 }
    608