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 define <2 x float> @fsub_negzero_vec_undef_elts(<2 x float> %x) {
      5 ; CHECK-LABEL: @fsub_negzero_vec_undef_elts(
      6 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
      7 ;
      8   %r = fsub nsz <2 x float> %x, <float undef, float -0.0>
      9   ret <2 x float> %r
     10 }
     11 
     12 ; fsub -0.0, (fsub -0.0, X) ==> X
     13 define float @fsub_-0_-0_x(float %a) {
     14 ; CHECK-LABEL: @fsub_-0_-0_x(
     15 ; CHECK-NEXT:    ret float [[A:%.*]]
     16 ;
     17   %t1 = fsub float -0.0, %a
     18   %ret = fsub float -0.0, %t1
     19   ret float %ret
     20 }
     21 
     22 define <2 x float> @fsub_-0_-0_x_vec(<2 x float> %a) {
     23 ; CHECK-LABEL: @fsub_-0_-0_x_vec(
     24 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
     25 ;
     26   %t1 = fsub <2 x float> <float -0.0, float -0.0>, %a
     27   %ret = fsub <2 x float> <float -0.0, float -0.0>, %t1
     28   ret <2 x float> %ret
     29 }
     30 
     31 define <2 x float> @fsub_-0_-0_x_vec_undef_elts(<2 x float> %a) {
     32 ; CHECK-LABEL: @fsub_-0_-0_x_vec_undef_elts(
     33 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
     34 ;
     35   %t1 = fsub <2 x float> <float undef, float -0.0>, %a
     36   %ret = fsub <2 x float> <float -0.0, float undef>, %t1
     37   ret <2 x float> %ret
     38 }
     39 
     40 ; fsub 0.0, (fsub -0.0, X) != X
     41 define float @fsub_0_-0_x(float %a) {
     42 ; CHECK-LABEL: @fsub_0_-0_x(
     43 ; CHECK-NEXT:    [[T1:%.*]] = fsub float 0.000000e+00, [[A:%.*]]
     44 ; CHECK-NEXT:    [[RET:%.*]] = fsub float -0.000000e+00, [[T1]]
     45 ; CHECK-NEXT:    ret float [[RET]]
     46 ;
     47   %t1 = fsub float 0.0, %a
     48   %ret = fsub float -0.0, %t1
     49   ret float %ret
     50 }
     51 
     52 ; fsub -0.0, (fsub 0.0, X) != X
     53 define float @fsub_-0_0_x(float %a) {
     54 ; CHECK-LABEL: @fsub_-0_0_x(
     55 ; CHECK-NEXT:    [[T1:%.*]] = fsub float -0.000000e+00, [[A:%.*]]
     56 ; CHECK-NEXT:    [[RET:%.*]] = fsub float 0.000000e+00, [[T1]]
     57 ; CHECK-NEXT:    ret float [[RET]]
     58 ;
     59   %t1 = fsub float -0.0, %a
     60   %ret = fsub float 0.0, %t1
     61   ret float %ret
     62 }
     63 
     64 ; fsub X, 0 ==> X
     65 define float @fsub_x_0(float %x) {
     66 ; CHECK-LABEL: @fsub_x_0(
     67 ; CHECK-NEXT:    ret float [[X:%.*]]
     68 ;
     69   %r = fsub float %x, 0.0
     70   ret float %r
     71 }
     72 
     73 define <2 x float> @fsub_x_0_vec_undef(<2 x float> %x) {
     74 ; CHECK-LABEL: @fsub_x_0_vec_undef(
     75 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
     76 ;
     77   %r = fsub <2 x float> %x, <float undef, float 0.0>
     78   ret <2 x float> %r
     79 }
     80 
     81 ; fadd X, -0 ==> X
     82 define float @fadd_x_n0(float %a) {
     83 ; CHECK-LABEL: @fadd_x_n0(
     84 ; CHECK-NEXT:    ret float [[A:%.*]]
     85 ;
     86   %ret = fadd float %a, -0.0
     87   ret float %ret
     88 }
     89 
     90 define <2 x float> @fadd_x_n0_vec_undef_elt(<2 x float> %a) {
     91 ; CHECK-LABEL: @fadd_x_n0_vec_undef_elt(
     92 ; CHECK-NEXT:    ret <2 x float> [[A:%.*]]
     93 ;
     94   %ret = fadd <2 x float> %a, <float -0.0, float undef>
     95   ret <2 x float> %ret
     96 }
     97 
     98 ; fmul X, 1.0 ==> X
     99 define double @fmul_X_1(double %a) {
    100 ; CHECK-LABEL: @fmul_X_1(
    101 ; CHECK-NEXT:    ret double [[A:%.*]]
    102 ;
    103   %b = fmul double 1.0, %a
    104   ret double %b
    105 }
    106 
    107 ; PR2642
    108 define <4 x float> @fmul_X_1_vec(<4 x float> %x) {
    109 ; CHECK-LABEL: @fmul_X_1_vec(
    110 ; CHECK-NEXT:    ret <4 x float> [[X:%.*]]
    111 ;
    112   %m = fmul <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0>
    113   ret <4 x float> %m
    114 }
    115 
    116 ; fdiv X, 1.0 ==> X
    117 define float @fdiv_x_1(float %a) {
    118 ; CHECK-LABEL: @fdiv_x_1(
    119 ; CHECK-NEXT:    ret float [[A:%.*]]
    120 ;
    121   %ret = fdiv float %a, 1.0
    122   ret float %ret
    123 }
    124 
    125 ; We can't optimize away the fadd in this test because the input
    126 ; value to the function and subsequently to the fadd may be -0.0.
    127 ; In that one special case, the result of the fadd should be +0.0
    128 ; rather than the first parameter of the fadd.
    129 
    130 ; Fragile test warning: We need 6 sqrt calls to trigger the bug
    131 ; because the internal logic has a magic recursion limit of 6.
    132 ; This is presented without any explanation or ability to customize.
    133 
    134 declare float @sqrtf(float)
    135 
    136 define float @PR22688(float %x) {
    137 ; CHECK-LABEL: @PR22688(
    138 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @sqrtf(float [[X:%.*]])
    139 ; CHECK-NEXT:    [[TMP2:%.*]] = call float @sqrtf(float [[TMP1]])
    140 ; CHECK-NEXT:    [[TMP3:%.*]] = call float @sqrtf(float [[TMP2]])
    141 ; CHECK-NEXT:    [[TMP4:%.*]] = call float @sqrtf(float [[TMP3]])
    142 ; CHECK-NEXT:    [[TMP5:%.*]] = call float @sqrtf(float [[TMP4]])
    143 ; CHECK-NEXT:    [[TMP6:%.*]] = call float @sqrtf(float [[TMP5]])
    144 ; CHECK-NEXT:    [[TMP7:%.*]] = fadd float [[TMP6]], 0.000000e+00
    145 ; CHECK-NEXT:    ret float [[TMP7]]
    146 ;
    147   %1 = call float @sqrtf(float %x)
    148   %2 = call float @sqrtf(float %1)
    149   %3 = call float @sqrtf(float %2)
    150   %4 = call float @sqrtf(float %3)
    151   %5 = call float @sqrtf(float %4)
    152   %6 = call float @sqrtf(float %5)
    153   %7 = fadd float %6, 0.0
    154   ret float %7
    155 }
    156 
    157 declare float @llvm.fabs.f32(float)
    158 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
    159 declare float @llvm.sqrt.f32(float)
    160 
    161 define float @fabs_select_positive_constants(i32 %c) {
    162 ; CHECK-LABEL: @fabs_select_positive_constants(
    163 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    164 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
    165 ; CHECK-NEXT:    ret float [[SELECT]]
    166 ;
    167   %cmp = icmp eq i32 %c, 0
    168   %select = select i1 %cmp, float 1.0, float 2.0
    169   %fabs = call float @llvm.fabs.f32(float %select)
    170   ret float %fabs
    171 }
    172 
    173 define <2 x float> @fabs_select_positive_constants_vector(i32 %c) {
    174 ; CHECK-LABEL: @fabs_select_positive_constants_vector(
    175 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    176 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> <float 2.000000e+00, float 2.000000e+00>
    177 ; CHECK-NEXT:    ret <2 x float> [[SELECT]]
    178 ;
    179   %cmp = icmp eq i32 %c, 0
    180   %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
    181   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
    182   ret <2 x float> %fabs
    183 }
    184 
    185 define float @fabs_select_constant_variable(i32 %c, float %x) {
    186 ; CHECK-LABEL: @fabs_select_constant_variable(
    187 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    188 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float [[X:%.*]]
    189 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
    190 ; CHECK-NEXT:    ret float [[FABS]]
    191 ;
    192   %cmp = icmp eq i32 %c, 0
    193   %select = select i1 %cmp, float 1.0, float %x
    194   %fabs = call float @llvm.fabs.f32(float %select)
    195   ret float %fabs
    196 }
    197 
    198 define <2 x float> @fabs_select_constant_variable_vector(i32 %c, <2 x float> %x) {
    199 ; CHECK-LABEL: @fabs_select_constant_variable_vector(
    200 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    201 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]]
    202 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
    203 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
    204 ;
    205   %cmp = icmp eq i32 %c, 0
    206   %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> %x
    207   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
    208   ret <2 x float> %fabs
    209 }
    210 
    211 define float @fabs_select_neg0_pos0(i32 %c) {
    212 ; CHECK-LABEL: @fabs_select_neg0_pos0(
    213 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    214 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float 0.000000e+00
    215 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
    216 ; CHECK-NEXT:    ret float [[FABS]]
    217 ;
    218   %cmp = icmp eq i32 %c, 0
    219   %select = select i1 %cmp, float -0.0, float 0.0
    220   %fabs = call float @llvm.fabs.f32(float %select)
    221   ret float %fabs
    222 }
    223 
    224 define <2 x float> @fabs_select_neg0_pos0_vector(i32 %c) {
    225 ; CHECK-LABEL: @fabs_select_neg0_pos0_vector(
    226 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    227 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float -0.000000e+00, float -0.000000e+00>, <2 x float> zeroinitializer
    228 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
    229 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
    230 ;
    231   %cmp = icmp eq i32 %c, 0
    232   %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float 0.0, float 0.0>
    233   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
    234   ret <2 x float> %fabs
    235 }
    236 
    237 define float @fabs_select_neg0_neg1(i32 %c) {
    238 ; CHECK-LABEL: @fabs_select_neg0_neg1(
    239 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    240 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float -1.000000e+00
    241 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
    242 ; CHECK-NEXT:    ret float [[FABS]]
    243 ;
    244   %cmp = icmp eq i32 %c, 0
    245   %select = select i1 %cmp, float -0.0, float -1.0
    246   %fabs = call float @llvm.fabs.f32(float %select)
    247   ret float %fabs
    248 }
    249 
    250 define <2 x float> @fabs_select_neg0_neg1_vector(i32 %c) {
    251 ; CHECK-LABEL: @fabs_select_neg0_neg1_vector(
    252 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    253 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float -0.000000e+00, float -0.000000e+00>, <2 x float> <float -1.000000e+00, float -1.000000e+00>
    254 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
    255 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
    256 ;
    257   %cmp = icmp eq i32 %c, 0
    258   %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float -1.0, float -1.0>
    259   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
    260   ret <2 x float> %fabs
    261 }
    262 
    263 define float @fabs_select_nan_nan(i32 %c) {
    264 ; CHECK-LABEL: @fabs_select_nan_nan(
    265 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    266 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0x7FF8000000000000, float 0x7FF8000100000000
    267 ; CHECK-NEXT:    ret float [[SELECT]]
    268 ;
    269   %cmp = icmp eq i32 %c, 0
    270   %select = select i1 %cmp, float 0x7FF8000000000000, float 0x7FF8000100000000
    271   %fabs = call float @llvm.fabs.f32(float %select)
    272   ret float %fabs
    273 }
    274 
    275 define <2 x float> @fabs_select_nan_nan_vector(i32 %c) {
    276 ; CHECK-LABEL: @fabs_select_nan_nan_vector(
    277 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    278 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
    279 ; CHECK-NEXT:    ret <2 x float> [[SELECT]]
    280 ;
    281   %cmp = icmp eq i32 %c, 0
    282   %select = select i1 %cmp, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
    283   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
    284   ret <2 x float> %fabs
    285 }
    286 
    287 define float @fabs_select_negnan_nan(i32 %c) {
    288 ; CHECK-LABEL: @fabs_select_negnan_nan(
    289 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    290 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000000000000
    291 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
    292 ; CHECK-NEXT:    ret float [[FABS]]
    293 ;
    294   %cmp = icmp eq i32 %c, 0
    295   %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000000000000
    296   %fabs = call float @llvm.fabs.f32(float %select)
    297   ret float %fabs
    298 }
    299 
    300 define <2 x float> @fabs_select_negnan_nan_vector(i32 %c) {
    301 ; CHECK-LABEL: @fabs_select_negnan_nan_vector(
    302 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    303 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
    304 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
    305 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
    306 ;
    307   %cmp = icmp eq i32 %c, 0
    308   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
    309   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
    310   ret <2 x float> %fabs
    311 }
    312 
    313 define float @fabs_select_negnan_negnan(i32 %c) {
    314 ; CHECK-LABEL: @fabs_select_negnan_negnan(
    315 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    316 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000100000000
    317 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
    318 ; CHECK-NEXT:    ret float [[FABS]]
    319 ;
    320   %cmp = icmp eq i32 %c, 0
    321   %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000100000000
    322   %fabs = call float @llvm.fabs.f32(float %select)
    323   ret float %fabs
    324 }
    325 
    326 define <2 x float> @fabs_select_negnan_negnan_vector(i32 %c) {
    327 ; CHECK-LABEL: @fabs_select_negnan_negnan_vector(
    328 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    329 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
    330 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
    331 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
    332 ;
    333   %cmp = icmp eq i32 %c, 0
    334   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
    335   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
    336   ret <2 x float> %fabs
    337 }
    338 
    339 define float @fabs_select_negnan_negzero(i32 %c) {
    340 ; CHECK-LABEL: @fabs_select_negnan_negzero(
    341 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    342 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float -0.000000e+00
    343 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
    344 ; CHECK-NEXT:    ret float [[FABS]]
    345 ;
    346   %cmp = icmp eq i32 %c, 0
    347   %select = select i1 %cmp, float 0xFFF8000000000000, float -0.0
    348   %fabs = call float @llvm.fabs.f32(float %select)
    349   ret float %fabs
    350 }
    351 
    352 define <2 x float> @fabs_select_negnan_negzero_vector(i32 %c) {
    353 ; CHECK-LABEL: @fabs_select_negnan_negzero_vector(
    354 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    355 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.000000e+00, float -0.000000e+00>
    356 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
    357 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
    358 ;
    359   %cmp = icmp eq i32 %c, 0
    360   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.0, float -0.0>
    361   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
    362   ret <2 x float> %fabs
    363 }
    364 
    365 define float @fabs_select_negnan_zero(i32 %c) {
    366 ; CHECK-LABEL: @fabs_select_negnan_zero(
    367 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    368 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0.000000e+00
    369 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
    370 ; CHECK-NEXT:    ret float [[FABS]]
    371 ;
    372   %cmp = icmp eq i32 %c, 0
    373   %select = select i1 %cmp, float 0xFFF8000000000000, float 0.0
    374   %fabs = call float @llvm.fabs.f32(float %select)
    375   ret float %fabs
    376 }
    377 
    378 define <2 x float> @fabs_select_negnan_zero_vector(i32 %c) {
    379 ; CHECK-LABEL: @fabs_select_negnan_zero_vector(
    380 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    381 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> zeroinitializer
    382 ; CHECK-NEXT:    [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
    383 ; CHECK-NEXT:    ret <2 x float> [[FABS]]
    384 ;
    385   %cmp = icmp eq i32 %c, 0
    386   %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0.0, float 0.0>
    387   %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
    388   ret <2 x float> %fabs
    389 }
    390 
    391 ; The fabs can't be eliminated because llvm.sqrt.f32 may return -0 or NaN with
    392 ; an arbitrary sign bit.
    393 define float @fabs_sqrt(float %a) {
    394 ; CHECK-LABEL: @fabs_sqrt(
    395 ; CHECK-NEXT:    [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
    396 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
    397 ; CHECK-NEXT:    ret float [[FABS]]
    398 ;
    399   %sqrt = call float @llvm.sqrt.f32(float %a)
    400   %fabs = call float @llvm.fabs.f32(float %sqrt)
    401   ret float %fabs
    402 }
    403 
    404 ; The fabs can't be eliminated because the nnan sqrt may still return -0.
    405 define float @fabs_sqrt_nnan(float %a) {
    406 ; CHECK-LABEL: @fabs_sqrt_nnan(
    407 ; CHECK-NEXT:    [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
    408 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
    409 ; CHECK-NEXT:    ret float [[FABS]]
    410 ;
    411   %sqrt = call nnan float @llvm.sqrt.f32(float %a)
    412   %fabs = call float @llvm.fabs.f32(float %sqrt)
    413   ret float %fabs
    414 }
    415 
    416 ; The fabs can't be eliminated because the nsz sqrt may still return NaN.
    417 define float @fabs_sqrt_nsz(float %a) {
    418 ; CHECK-LABEL: @fabs_sqrt_nsz(
    419 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz float @llvm.sqrt.f32(float [[A:%.*]])
    420 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
    421 ; CHECK-NEXT:    ret float [[FABS]]
    422 ;
    423   %sqrt = call nsz float @llvm.sqrt.f32(float %a)
    424   %fabs = call float @llvm.fabs.f32(float %sqrt)
    425   ret float %fabs
    426 }
    427 
    428 ; The fabs can be eliminated because we're nsz and nnan.
    429 define float @fabs_sqrt_nnan_nsz(float %a) {
    430 ; CHECK-LABEL: @fabs_sqrt_nnan_nsz(
    431 ; CHECK-NEXT:    [[SQRT:%.*]] = call nnan nsz float @llvm.sqrt.f32(float [[A:%.*]])
    432 ; CHECK-NEXT:    ret float [[SQRT]]
    433 ;
    434   %sqrt = call nnan nsz float @llvm.sqrt.f32(float %a)
    435   %fabs = call float @llvm.fabs.f32(float %sqrt)
    436   ret float %fabs
    437 }
    438 
    439 ; The second fabs can be eliminated because the operand to sqrt cannot be -0.
    440 define float @fabs_sqrt_nnan_fabs(float %a) {
    441 ; CHECK-LABEL: @fabs_sqrt_nnan_fabs(
    442 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
    443 ; CHECK-NEXT:    [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[B]])
    444 ; CHECK-NEXT:    ret float [[SQRT]]
    445 ;
    446   %b = call float @llvm.fabs.f32(float %a)
    447   %sqrt = call nnan float @llvm.sqrt.f32(float %b)
    448   %fabs = call float @llvm.fabs.f32(float %sqrt)
    449   ret float %fabs
    450 }
    451 
    452 define float @fabs_select_positive_constants_vector_extract(i32 %c) {
    453 ; CHECK-LABEL: @fabs_select_positive_constants_vector_extract(
    454 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
    455 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> <float 2.000000e+00, float 2.000000e+00>
    456 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <2 x float> [[SELECT]], i32 0
    457 ; CHECK-NEXT:    ret float [[EXTRACT]]
    458 ;
    459   %cmp = icmp eq i32 %c, 0
    460   %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
    461   %extract = extractelement <2 x float> %select, i32 0
    462   %fabs = call float @llvm.fabs.f32(float %extract)
    463   ret float %fabs
    464 }
    465 
    466 declare double @llvm.minnum.f64(double, double)
    467 declare double @llvm.maxnum.f64(double, double)
    468 declare <2 x double> @llvm.minnum.v2f64(<2 x double>, <2 x double>)
    469 declare <2 x double> @llvm.maxnum.v2f64(<2 x double>, <2 x double>)
    470 
    471 ; From the LangRef for minnum/maxnum:
    472 ; "follows the IEEE-754 semantics for maxNum, which also match for libms fmax.
    473 ; If either operand is a NaN, returns the other non-NaN operand."
    474 
    475 define double @maxnum_nan_op0(double %x) {
    476 ; CHECK-LABEL: @maxnum_nan_op0(
    477 ; CHECK-NEXT:    ret double [[X:%.*]]
    478 ;
    479   %r = call double @llvm.maxnum.f64(double 0x7ff8000000000000, double %x)
    480   ret double %r
    481 }
    482 
    483 define double @maxnum_nan_op1(double %x) {
    484 ; CHECK-LABEL: @maxnum_nan_op1(
    485 ; CHECK-NEXT:    ret double [[X:%.*]]
    486 ;
    487   %r = call double @llvm.maxnum.f64(double %x, double 0x7ff800000000dead)
    488   ret double %r
    489 }
    490 
    491 define double @minnum_nan_op0(double %x) {
    492 ; CHECK-LABEL: @minnum_nan_op0(
    493 ; CHECK-NEXT:    ret double [[X:%.*]]
    494 ;
    495   %r = call double @llvm.minnum.f64(double 0x7ff8000dead00000, double %x)
    496   ret double %r
    497 }
    498 
    499 define double @minnum_nan_op1(double %x) {
    500 ; CHECK-LABEL: @minnum_nan_op1(
    501 ; CHECK-NEXT:    ret double [[X:%.*]]
    502 ;
    503   %r = call double @llvm.minnum.f64(double %x, double 0x7ff800dead00dead)
    504   ret double %r
    505 }
    506 
    507 define <2 x double> @maxnum_nan_op0_vec(<2 x double> %x) {
    508 ; CHECK-LABEL: @maxnum_nan_op0_vec(
    509 ; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
    510 ;
    511   %r = call <2 x double> @llvm.maxnum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> %x)
    512   ret <2 x double> %r
    513 }
    514 
    515 define <2 x double> @maxnum_nan_op1_vec(<2 x double> %x) {
    516 ; CHECK-LABEL: @maxnum_nan_op1_vec(
    517 ; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
    518 ;
    519   %r = call <2 x double> @llvm.maxnum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800000000dead, double 0x7ff8ffffffffffff>)
    520   ret <2 x double> %r
    521 }
    522 
    523 define <2 x double> @minnum_nan_op0_vec(<2 x double> %x) {
    524 ; CHECK-LABEL: @minnum_nan_op0_vec(
    525 ; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
    526 ;
    527   %r = call <2 x double> @llvm.minnum.v2f64(<2 x double> <double undef, double 0x7ff8000dead00000>, <2 x double> %x)
    528   ret <2 x double> %r
    529 }
    530 
    531 define <2 x double> @minnum_nan_op1_vec(<2 x double> %x) {
    532 ; CHECK-LABEL: @minnum_nan_op1_vec(
    533 ; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
    534 ;
    535   %r = call <2 x double> @llvm.minnum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800dead00dead, double 0x7ff800dead00dead>)
    536   ret <2 x double> %r
    537 }
    538 
    539