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 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
      5 
      6 declare i32 @abs(i32)
      7 declare i64 @labs(i64)
      8 declare i64 @llabs(i64)
      9 
     10 ; Test that the abs library call simplifier works correctly.
     11 ; abs(x) -> x <s 0 ? -x : x.
     12 
     13 define i32 @test_abs(i32 %x) {
     14 ; CHECK-LABEL: @test_abs(
     15 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
     16 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[X]]
     17 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[NEG]], i32 [[X]]
     18 ; CHECK-NEXT:    ret i32 [[TMP2]]
     19 ;
     20   %ret = call i32 @abs(i32 %x)
     21   ret i32 %ret
     22 }
     23 
     24 define i64 @test_labs(i64 %x) {
     25 ; CHECK-LABEL: @test_labs(
     26 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[X:%.*]], 0
     27 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i64 0, [[X]]
     28 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i64 [[NEG]], i64 [[X]]
     29 ; CHECK-NEXT:    ret i64 [[TMP2]]
     30 ;
     31   %ret = call i64 @labs(i64 %x)
     32   ret i64 %ret
     33 }
     34 
     35 define i64 @test_llabs(i64 %x) {
     36 ; CHECK-LABEL: @test_llabs(
     37 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[X:%.*]], 0
     38 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i64 0, [[X]]
     39 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i64 [[NEG]], i64 [[X]]
     40 ; CHECK-NEXT:    ret i64 [[TMP2]]
     41 ;
     42   %ret = call i64 @llabs(i64 %x)
     43   ret i64 %ret
     44 }
     45 
     46 ; We have a canonical form of abs to make CSE easier.
     47 
     48 define i8 @abs_canonical_1(i8 %x) {
     49 ; CHECK-LABEL: @abs_canonical_1(
     50 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
     51 ; CHECK-NEXT:    [[NEG:%.*]] = sub i8 0, [[X]]
     52 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEG]], i8 [[X]]
     53 ; CHECK-NEXT:    ret i8 [[ABS]]
     54 ;
     55   %cmp = icmp sgt i8 %x, 0
     56   %neg = sub i8 0, %x
     57   %abs = select i1 %cmp, i8 %x, i8 %neg
     58   ret i8 %abs
     59 }
     60 
     61 ; Vectors should work too.
     62 
     63 define <2 x i8> @abs_canonical_2(<2 x i8> %x) {
     64 ; CHECK-LABEL: @abs_canonical_2(
     65 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
     66 ; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
     67 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[NEG]], <2 x i8> [[X]]
     68 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
     69 ;
     70   %cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>
     71   %neg = sub <2 x i8> zeroinitializer, %x
     72   %abs = select <2 x i1> %cmp, <2 x i8> %x, <2 x i8> %neg
     73   ret <2 x i8> %abs
     74 }
     75 
     76 ; Even if a constant has undef elements.
     77 
     78 define <2 x i8> @abs_canonical_2_vec_undef_elts(<2 x i8> %x) {
     79 ; CHECK-LABEL: @abs_canonical_2_vec_undef_elts(
     80 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
     81 ; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
     82 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[NEG]], <2 x i8> [[X]]
     83 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
     84 ;
     85   %cmp = icmp sgt <2 x i8> %x, <i8 undef, i8 -1>
     86   %neg = sub <2 x i8> zeroinitializer, %x
     87   %abs = select <2 x i1> %cmp, <2 x i8> %x, <2 x i8> %neg
     88   ret <2 x i8> %abs
     89 }
     90 
     91 ; NSW should not change.
     92 
     93 define i8 @abs_canonical_3(i8 %x) {
     94 ; CHECK-LABEL: @abs_canonical_3(
     95 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
     96 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i8 0, [[X]]
     97 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEG]], i8 [[X]]
     98 ; CHECK-NEXT:    ret i8 [[ABS]]
     99 ;
    100   %cmp = icmp slt i8 %x, 0
    101   %neg = sub nsw i8 0, %x
    102   %abs = select i1 %cmp, i8 %neg, i8 %x
    103   ret i8 %abs
    104 }
    105 
    106 define i8 @abs_canonical_4(i8 %x) {
    107 ; CHECK-LABEL: @abs_canonical_4(
    108 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
    109 ; CHECK-NEXT:    [[NEG:%.*]] = sub i8 0, [[X]]
    110 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEG]], i8 [[X]]
    111 ; CHECK-NEXT:    ret i8 [[ABS]]
    112 ;
    113   %cmp = icmp slt i8 %x, 1
    114   %neg = sub i8 0, %x
    115   %abs = select i1 %cmp, i8 %neg, i8 %x
    116   ret i8 %abs
    117 }
    118 
    119 define i32 @abs_canonical_5(i8 %x) {
    120 ; CHECK-LABEL: @abs_canonical_5(
    121 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
    122 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X]] to i32
    123 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[CONV]]
    124 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[CONV]]
    125 ; CHECK-NEXT:    ret i32 [[ABS]]
    126 ;
    127   %cmp = icmp sgt i8 %x, 0
    128   %conv = sext i8 %x to i32
    129   %neg = sub i32 0, %conv
    130   %abs = select i1 %cmp, i32 %conv, i32 %neg
    131   ret i32 %abs
    132 }
    133 
    134 define i32 @abs_canonical_6(i32 %a, i32 %b) {
    135 ; CHECK-LABEL: @abs_canonical_6(
    136 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
    137 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], 0
    138 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 0, [[TMP1]]
    139 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP2]], i32 [[TMP1]]
    140 ; CHECK-NEXT:    ret i32 [[ABS]]
    141 ;
    142   %tmp1 = sub i32 %a, %b
    143   %cmp = icmp sgt i32 %tmp1, -1
    144   %tmp2 = sub i32 %b, %a
    145   %abs = select i1 %cmp, i32 %tmp1, i32 %tmp2
    146   ret i32 %abs
    147 }
    148 
    149 define <2 x i8> @abs_canonical_7(<2 x i8> %a, <2 x i8 > %b) {
    150 ; CHECK-LABEL: @abs_canonical_7(
    151 ; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> [[A:%.*]], [[B:%.*]]
    152 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], zeroinitializer
    153 ; CHECK-NEXT:    [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
    154 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[TMP2]], <2 x i8> [[TMP1]]
    155 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
    156 ;
    157 
    158   %tmp1 = sub <2 x i8> %a, %b
    159   %cmp = icmp sgt <2 x i8> %tmp1, <i8 -1, i8 -1>
    160   %tmp2 = sub <2 x i8> %b, %a
    161   %abs = select <2 x i1> %cmp, <2 x i8> %tmp1, <2 x i8> %tmp2
    162   ret <2 x i8> %abs
    163 }
    164 
    165 define i32 @abs_canonical_8(i32 %a) {
    166 ; CHECK-LABEL: @abs_canonical_8(
    167 ; CHECK-NEXT:    [[TMP:%.*]] = sub i32 0, [[A:%.*]]
    168 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
    169 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP]], i32 [[A]]
    170 ; CHECK-NEXT:    ret i32 [[ABS]]
    171 ;
    172   %tmp = sub i32 0, %a
    173   %cmp = icmp slt i32 %tmp, 0
    174   %abs = select i1 %cmp, i32 %a, i32 %tmp
    175   ret i32 %abs
    176 }
    177 
    178 define i32 @abs_canonical_9(i32 %a, i32 %b) {
    179 ; CHECK-LABEL: @abs_canonical_9(
    180 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
    181 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], -1
    182 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 [[B]], [[A]]
    183 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP1]], i32 [[TMP2]]
    184 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[ABS]], [[TMP2]]
    185 ; CHECK-NEXT:    ret i32 [[ADD]]
    186 ;
    187   %tmp1 = sub i32 %a, %b
    188   %cmp = icmp sgt i32 %tmp1, -1
    189   %tmp2 = sub i32 %b, %a
    190   %abs = select i1 %cmp, i32 %tmp1, i32 %tmp2
    191   %add = add i32 %abs, %tmp2 ; increase use count for %tmp2.
    192   ret i32 %add
    193 }
    194 
    195 define i32 @abs_canonical_10(i32 %a, i32 %b) {
    196 ; CHECK-LABEL: @abs_canonical_10(
    197 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
    198 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], 0
    199 ; CHECK-NEXT:    [[NEGTMP:%.*]] = sub i32 0, [[TMP1]]
    200 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGTMP]], i32 [[TMP1]]
    201 ; CHECK-NEXT:    ret i32 [[ABS]]
    202 ;
    203   %tmp2 = sub i32 %b, %a
    204   %tmp1 = sub i32 %a, %b
    205   %cmp = icmp sgt i32 %tmp1, -1
    206   %abs = select i1 %cmp, i32 %tmp1, i32 %tmp2
    207   ret i32 %abs
    208 }
    209 
    210 ; We have a canonical form of nabs to make CSE easier.
    211 
    212 define i8 @nabs_canonical_1(i8 %x) {
    213 ; CHECK-LABEL: @nabs_canonical_1(
    214 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
    215 ; CHECK-NEXT:    [[NEG:%.*]] = sub i8 0, [[X]]
    216 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEG]]
    217 ; CHECK-NEXT:    ret i8 [[ABS]]
    218 ;
    219   %cmp = icmp sgt i8 %x, 0
    220   %neg = sub i8 0, %x
    221   %abs = select i1 %cmp, i8 %neg, i8 %x
    222   ret i8 %abs
    223 }
    224 
    225 ; Vectors should work too.
    226 
    227 define <2 x i8> @nabs_canonical_2(<2 x i8> %x) {
    228 ; CHECK-LABEL: @nabs_canonical_2(
    229 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
    230 ; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
    231 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[X]], <2 x i8> [[NEG]]
    232 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
    233 ;
    234   %cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>
    235   %neg = sub <2 x i8> zeroinitializer, %x
    236   %abs = select <2 x i1> %cmp, <2 x i8> %neg, <2 x i8> %x
    237   ret <2 x i8> %abs
    238 }
    239 
    240 ; Even if a constant has undef elements.
    241 
    242 define <2 x i8> @nabs_canonical_2_vec_undef_elts(<2 x i8> %x) {
    243 ; CHECK-LABEL: @nabs_canonical_2_vec_undef_elts(
    244 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
    245 ; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
    246 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[X]], <2 x i8> [[NEG]]
    247 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
    248 ;
    249   %cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 undef>
    250   %neg = sub <2 x i8> zeroinitializer, %x
    251   %abs = select <2 x i1> %cmp, <2 x i8> %neg, <2 x i8> %x
    252   ret <2 x i8> %abs
    253 }
    254 
    255 ; NSW should not change.
    256 
    257 define i8 @nabs_canonical_3(i8 %x) {
    258 ; CHECK-LABEL: @nabs_canonical_3(
    259 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
    260 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i8 0, [[X]]
    261 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEG]]
    262 ; CHECK-NEXT:    ret i8 [[ABS]]
    263 ;
    264   %cmp = icmp slt i8 %x, 0
    265   %neg = sub nsw i8 0, %x
    266   %abs = select i1 %cmp, i8 %x, i8 %neg
    267   ret i8 %abs
    268 }
    269 
    270 define i8 @nabs_canonical_4(i8 %x) {
    271 ; CHECK-LABEL: @nabs_canonical_4(
    272 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
    273 ; CHECK-NEXT:    [[NEG:%.*]] = sub i8 0, [[X]]
    274 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEG]]
    275 ; CHECK-NEXT:    ret i8 [[ABS]]
    276 ;
    277   %cmp = icmp slt i8 %x, 1
    278   %neg = sub i8 0, %x
    279   %abs = select i1 %cmp, i8 %x, i8 %neg
    280   ret i8 %abs
    281 }
    282 
    283 define i32 @nabs_canonical_5(i8 %x) {
    284 ; CHECK-LABEL: @nabs_canonical_5(
    285 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
    286 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X]] to i32
    287 ; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[CONV]]
    288 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[CONV]], i32 [[NEG]]
    289 ; CHECK-NEXT:    ret i32 [[ABS]]
    290 ;
    291   %cmp = icmp sgt i8 %x, 0
    292   %conv = sext i8 %x to i32
    293   %neg = sub i32 0, %conv
    294   %abs = select i1 %cmp, i32 %neg, i32 %conv
    295   ret i32 %abs
    296 }
    297 
    298 define i32 @nabs_canonical_6(i32 %a, i32 %b) {
    299 ; CHECK-LABEL: @nabs_canonical_6(
    300 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
    301 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], 0
    302 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 0, [[TMP1]]
    303 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP1]], i32 [[TMP2]]
    304 ; CHECK-NEXT:    ret i32 [[ABS]]
    305 ;
    306   %tmp1 = sub i32 %a, %b
    307   %cmp = icmp sgt i32 %tmp1, -1
    308   %tmp2 = sub i32 %b, %a
    309   %abs = select i1 %cmp, i32 %tmp2, i32 %tmp1
    310   ret i32 %abs
    311 }
    312 
    313 define <2 x i8> @nabs_canonical_7(<2 x i8> %a, <2 x i8 > %b) {
    314 ; CHECK-LABEL: @nabs_canonical_7(
    315 ; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> [[A:%.*]], [[B:%.*]]
    316 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], zeroinitializer
    317 ; CHECK-NEXT:    [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
    318 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[TMP1]], <2 x i8> [[TMP2]]
    319 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
    320 ;
    321   %tmp1 = sub <2 x i8> %a, %b
    322   %cmp = icmp sgt <2 x i8> %tmp1, <i8 -1, i8 -1>
    323   %tmp2 = sub <2 x i8> %b, %a
    324   %abs = select <2 x i1> %cmp, <2 x i8> %tmp2, <2 x i8> %tmp1
    325   ret <2 x i8> %abs
    326 }
    327 
    328 define i32 @nabs_canonical_8(i32 %a) {
    329 ; CHECK-LABEL: @nabs_canonical_8(
    330 ; CHECK-NEXT:    [[TMP:%.*]] = sub i32 0, [[A:%.*]]
    331 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
    332 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[TMP]]
    333 ; CHECK-NEXT:    ret i32 [[ABS]]
    334 ;
    335   %tmp = sub i32 0, %a
    336   %cmp = icmp slt i32 %tmp, 0
    337   %abs = select i1 %cmp, i32 %tmp, i32 %a
    338   ret i32 %abs
    339 }
    340 
    341 define i32 @nabs_canonical_9(i32 %a, i32 %b) {
    342 ; CHECK-LABEL: @nabs_canonical_9(
    343 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
    344 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], -1
    345 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 [[B]], [[A]]
    346 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP2]], i32 [[TMP1]]
    347 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP2]], [[ABS]]
    348 ; CHECK-NEXT:    ret i32 [[ADD]]
    349 ;
    350   %tmp1 = sub i32 %a, %b
    351   %cmp = icmp sgt i32 %tmp1, -1
    352   %tmp2 = sub i32 %b, %a
    353   %abs = select i1 %cmp, i32 %tmp2, i32 %tmp1
    354   %add = add i32 %tmp2, %abs ; increase use count for %tmp2
    355   ret i32 %add
    356 }
    357 
    358 define i32 @nabs_canonical_10(i32 %a, i32 %b) {
    359 ; CHECK-LABEL: @nabs_canonical_10(
    360 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
    361 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP1]], 0
    362 ; CHECK-NEXT:    [[NEGTMP:%.*]] = sub i32 0, [[TMP1]]
    363 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP1]], i32 [[NEGTMP]]
    364 ; CHECK-NEXT:    ret i32 [[ABS]]
    365 ;
    366   %tmp2 = sub i32 %b, %a
    367   %tmp1 = sub i32 %a, %b
    368   %cmp = icmp slt i32 %tmp1, 1
    369   %abs = select i1 %cmp, i32 %tmp1, i32 %tmp2
    370   ret i32 %abs
    371 }
    372 
    373 ; The following 5 tests use a shift+add+xor to implement abs():
    374 ; B = ashr i8 A, 7  -- smear the sign bit.
    375 ; xor (add A, B), B -- add -1 and flip bits if negative
    376 
    377 define i8 @shifty_abs_commute0(i8 %x) {
    378 ; CHECK-LABEL: @shifty_abs_commute0(
    379 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 0
    380 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 0, [[X]]
    381 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
    382 ; CHECK-NEXT:    ret i8 [[ABS]]
    383 ;
    384   %signbit = ashr i8 %x, 7
    385   %add = add i8 %signbit, %x
    386   %abs = xor i8 %add, %signbit
    387   ret i8 %abs
    388 }
    389 
    390 define i8 @shifty_abs_commute0_nsw(i8 %x) {
    391 ; CHECK-LABEL: @shifty_abs_commute0_nsw(
    392 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 0
    393 ; CHECK-NEXT:    [[TMP2:%.*]] = sub nsw i8 0, [[X]]
    394 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
    395 ; CHECK-NEXT:    ret i8 [[ABS]]
    396 ;
    397   %signbit = ashr i8 %x, 7
    398   %add = add nsw i8 %signbit, %x
    399   %abs = xor i8 %add, %signbit
    400   ret i8 %abs
    401 }
    402 
    403 ; The nuw flag creates a contradiction. If the shift produces all 1s, the only
    404 ; way for the add to not wrap is for %x to be 0, but then the shift couldn't
    405 ; have produced all 1s. We partially optimize this.
    406 define i8 @shifty_abs_commute0_nuw(i8 %x) {
    407 ; CHECK-LABEL: @shifty_abs_commute0_nuw(
    408 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[X:%.*]], 0
    409 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 0
    410 ; CHECK-NEXT:    ret i8 [[ABS]]
    411 ;
    412   %signbit = ashr i8 %x, 7
    413   %add = add nuw i8 %signbit, %x
    414   %abs = xor i8 %add, %signbit
    415   ret i8 %abs
    416 }
    417 
    418 define <2 x i8> @shifty_abs_commute1(<2 x i8> %x) {
    419 ; CHECK-LABEL: @shifty_abs_commute1(
    420 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
    421 ; CHECK-NEXT:    [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
    422 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> [[TMP2]], <2 x i8> [[X]]
    423 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
    424 ;
    425   %signbit = ashr <2 x i8> %x, <i8 7, i8 7>
    426   %add = add <2 x i8> %signbit, %x
    427   %abs = xor <2 x i8> %signbit, %add
    428   ret <2 x i8> %abs
    429 }
    430 
    431 define <2 x i8> @shifty_abs_commute2(<2 x i8> %x) {
    432 ; CHECK-LABEL: @shifty_abs_commute2(
    433 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[X:%.*]], <i8 3, i8 3>
    434 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i8> [[Y]], zeroinitializer
    435 ; CHECK-NEXT:    [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[Y]]
    436 ; CHECK-NEXT:    [[ABS:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> [[TMP2]], <2 x i8> [[Y]]
    437 ; CHECK-NEXT:    ret <2 x i8> [[ABS]]
    438 ;
    439   %y = mul <2 x i8> %x, <i8 3, i8 3>   ; extra op to thwart complexity-based canonicalization
    440   %signbit = ashr <2 x i8> %y, <i8 7, i8 7>
    441   %add = add <2 x i8> %y, %signbit
    442   %abs = xor <2 x i8> %signbit, %add
    443   ret <2 x i8> %abs
    444 }
    445 
    446 define i8 @shifty_abs_commute3(i8 %x) {
    447 ; CHECK-LABEL: @shifty_abs_commute3(
    448 ; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[X:%.*]], 3
    449 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y]], 0
    450 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 0, [[Y]]
    451 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[Y]]
    452 ; CHECK-NEXT:    ret i8 [[ABS]]
    453 ;
    454   %y = mul i8 %x, 3                    ; extra op to thwart complexity-based canonicalization
    455   %signbit = ashr i8 %y, 7
    456   %add = add i8 %y, %signbit
    457   %abs = xor i8 %add, %signbit
    458   ret i8 %abs
    459 }
    460 
    461 ; Negative test - don't transform if it would increase instruction count.
    462 
    463 declare void @extra_use(i8)
    464 
    465 define i8 @shifty_abs_too_many_uses(i8 %x) {
    466 ; CHECK-LABEL: @shifty_abs_too_many_uses(
    467 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7
    468 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SIGNBIT]], [[X]]
    469 ; CHECK-NEXT:    [[ABS:%.*]] = xor i8 [[ADD]], [[SIGNBIT]]
    470 ; CHECK-NEXT:    call void @extra_use(i8 [[SIGNBIT]])
    471 ; CHECK-NEXT:    ret i8 [[ABS]]
    472 ;
    473   %signbit = ashr i8 %x, 7
    474   %add = add i8 %x, %signbit
    475   %abs = xor i8 %add, %signbit
    476   call void @extra_use(i8 %signbit)
    477   ret i8 %abs
    478 }
    479 
    480 ; There's another way to make abs() using shift, xor, and subtract.
    481 ; PR36036 - https://bugs.llvm.org/show_bug.cgi?id=36036
    482 
    483 define i8 @shifty_sub(i8 %x) {
    484 ; CHECK-LABEL: @shifty_sub(
    485 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 0
    486 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 0, [[X]]
    487 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
    488 ; CHECK-NEXT:    ret i8 [[R]]
    489 ;
    490   %sh = ashr i8 %x, 7
    491   %xor = xor i8 %x, %sh
    492   %r = sub i8 %xor, %sh
    493   ret i8 %r
    494 }
    495 
    496 define i8 @shifty_sub_nsw_commute(i8 %x) {
    497 ; CHECK-LABEL: @shifty_sub_nsw_commute(
    498 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 0
    499 ; CHECK-NEXT:    [[TMP2:%.*]] = sub nsw i8 0, [[X]]
    500 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
    501 ; CHECK-NEXT:    ret i8 [[R]]
    502 ;
    503   %sh = ashr i8 %x, 7
    504   %xor = xor i8 %sh, %x
    505   %r = sub nsw i8 %xor, %sh
    506   ret i8 %r
    507 }
    508 
    509 define <4 x i32> @shifty_sub_nuw_vec_commute(<4 x i32> %x) {
    510 ; CHECK-LABEL: @shifty_sub_nuw_vec_commute(
    511 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], zeroinitializer
    512 ; CHECK-NEXT:    [[R:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[X]], <4 x i32> zeroinitializer
    513 ; CHECK-NEXT:    ret <4 x i32> [[R]]
    514 ;
    515   %sh = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>
    516   %xor = xor <4 x i32> %sh, %x
    517   %r = sub nuw <4 x i32> %xor, %sh
    518   ret <4 x i32> %r
    519 }
    520 
    521 define i12 @shifty_sub_nsw_nuw(i12 %x) {
    522 ; CHECK-LABEL: @shifty_sub_nsw_nuw(
    523 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i12 [[X:%.*]], 0
    524 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i12 [[X]], i12 0
    525 ; CHECK-NEXT:    ret i12 [[R]]
    526 ;
    527   %sh = ashr i12 %x, 11
    528   %xor = xor i12 %x, %sh
    529   %r = sub nsw nuw i12 %xor, %sh
    530   ret i12 %r
    531 }
    532 
    533 define i8 @negate_abs(i8 %x) {
    534 ; CHECK-LABEL: @negate_abs(
    535 ; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[X:%.*]]
    536 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[X]], 0
    537 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i8 [[X]], i8 [[N]]
    538 ; CHECK-NEXT:    ret i8 [[S]]
    539 ;
    540   %n = sub i8 0, %x
    541   %c = icmp slt i8 %x, 0
    542   %s = select i1 %c, i8 %n, i8 %x
    543   %r = sub i8 0, %s
    544   ret i8 %r
    545 }
    546 
    547 define <2 x i8> @negate_nabs(<2 x i8> %x) {
    548 ; CHECK-LABEL: @negate_nabs(
    549 ; CHECK-NEXT:    [[N:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]
    550 ; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i8> [[X]], zeroinitializer
    551 ; CHECK-NEXT:    [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[N]], <2 x i8> [[X]]
    552 ; CHECK-NEXT:    ret <2 x i8> [[S]]
    553 ;
    554   %n = sub <2 x i8> zeroinitializer, %x
    555   %c = icmp slt <2 x i8> %x, zeroinitializer
    556   %s = select <2 x i1> %c, <2 x i8> %x, <2 x i8> %n
    557   %r = sub <2 x i8> zeroinitializer, %s
    558   ret <2 x i8> %r
    559 }
    560 
    561 define i1 @abs_must_be_positive(i32 %x) {
    562 ; CHECK-LABEL: @abs_must_be_positive(
    563 ; CHECK-NEXT:    ret i1 true
    564 ;
    565   %negx = sub nsw i32 0, %x
    566   %c = icmp sge i32 %x, 0
    567   %sel = select i1 %c, i32 %x, i32 %negx
    568   %c2 = icmp sge i32 %sel, 0
    569   ret i1 %c2
    570 }
    571 
    572