Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -disable-post-ra -verify-machineinstrs | FileCheck %s
      2 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -fast-isel -fast-isel-abort=1 -disable-post-ra -verify-machineinstrs | FileCheck %s
      3 
      4 ;
      5 ; Get the actual value of the overflow bit.
      6 ;
      7 define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, i32* %res) {
      8 entry:
      9 ; CHECK-LABEL:  saddo1.i32
     10 ; CHECK:        adds {{w[0-9]+}}, w0, w1
     11 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
     12   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
     13   %val = extractvalue {i32, i1} %t, 0
     14   %obit = extractvalue {i32, i1} %t, 1
     15   store i32 %val, i32* %res
     16   ret i1 %obit
     17 }
     18 
     19 ; Test the immediate version.
     20 define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) {
     21 entry:
     22 ; CHECK-LABEL:  saddo2.i32
     23 ; CHECK:        adds {{w[0-9]+}}, w0, #4
     24 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
     25   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4)
     26   %val = extractvalue {i32, i1} %t, 0
     27   %obit = extractvalue {i32, i1} %t, 1
     28   store i32 %val, i32* %res
     29   ret i1 %obit
     30 }
     31 
     32 ; Test negative immediates.
     33 define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) {
     34 entry:
     35 ; CHECK-LABEL:  saddo3.i32
     36 ; CHECK:        subs {{w[0-9]+}}, w0, #4
     37 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
     38   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4)
     39   %val = extractvalue {i32, i1} %t, 0
     40   %obit = extractvalue {i32, i1} %t, 1
     41   store i32 %val, i32* %res
     42   ret i1 %obit
     43 }
     44 
     45 ; Test immediates that are too large to be encoded.
     46 define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) {
     47 entry:
     48 ; CHECK-LABEL:  saddo4.i32
     49 ; CHECK:        adds {{w[0-9]+}}, w0, {{w[0-9]+}}
     50 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
     51   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215)
     52   %val = extractvalue {i32, i1} %t, 0
     53   %obit = extractvalue {i32, i1} %t, 1
     54   store i32 %val, i32* %res
     55   ret i1 %obit
     56 }
     57 
     58 ; Test shift folding.
     59 define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, i32* %res) {
     60 entry:
     61 ; CHECK-LABEL:  saddo5.i32
     62 ; CHECK:        adds {{w[0-9]+}}, w0, w1
     63 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
     64   %lsl = shl i32 %v2, 16
     65   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl)
     66   %val = extractvalue {i32, i1} %t, 0
     67   %obit = extractvalue {i32, i1} %t, 1
     68   store i32 %val, i32* %res
     69   ret i1 %obit
     70 }
     71 
     72 define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) {
     73 entry:
     74 ; CHECK-LABEL:  saddo1.i64
     75 ; CHECK:        adds {{x[0-9]+}}, x0, x1
     76 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
     77   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
     78   %val = extractvalue {i64, i1} %t, 0
     79   %obit = extractvalue {i64, i1} %t, 1
     80   store i64 %val, i64* %res
     81   ret i1 %obit
     82 }
     83 
     84 define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) {
     85 entry:
     86 ; CHECK-LABEL:  saddo2.i64
     87 ; CHECK:        adds {{x[0-9]+}}, x0, #4
     88 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
     89   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)
     90   %val = extractvalue {i64, i1} %t, 0
     91   %obit = extractvalue {i64, i1} %t, 1
     92   store i64 %val, i64* %res
     93   ret i1 %obit
     94 }
     95 
     96 define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) {
     97 entry:
     98 ; CHECK-LABEL:  saddo3.i64
     99 ; CHECK:        subs {{x[0-9]+}}, x0, #4
    100 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
    101   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)
    102   %val = extractvalue {i64, i1} %t, 0
    103   %obit = extractvalue {i64, i1} %t, 1
    104   store i64 %val, i64* %res
    105   ret i1 %obit
    106 }
    107 
    108 define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
    109 entry:
    110 ; CHECK-LABEL:  uaddo.i32
    111 ; CHECK:        adds {{w[0-9]+}}, w0, w1
    112 ; CHECK-NEXT:   cset {{w[0-9]+}}, hs
    113   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
    114   %val = extractvalue {i32, i1} %t, 0
    115   %obit = extractvalue {i32, i1} %t, 1
    116   store i32 %val, i32* %res
    117   ret i1 %obit
    118 }
    119 
    120 define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
    121 entry:
    122 ; CHECK-LABEL:  uaddo.i64
    123 ; CHECK:        adds {{x[0-9]+}}, x0, x1
    124 ; CHECK-NEXT:   cset {{w[0-9]+}}, hs
    125   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
    126   %val = extractvalue {i64, i1} %t, 0
    127   %obit = extractvalue {i64, i1} %t, 1
    128   store i64 %val, i64* %res
    129   ret i1 %obit
    130 }
    131 
    132 define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) {
    133 entry:
    134 ; CHECK-LABEL:  ssubo1.i32
    135 ; CHECK:        subs {{w[0-9]+}}, w0, w1
    136 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
    137   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
    138   %val = extractvalue {i32, i1} %t, 0
    139   %obit = extractvalue {i32, i1} %t, 1
    140   store i32 %val, i32* %res
    141   ret i1 %obit
    142 }
    143 
    144 define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) {
    145 entry:
    146 ; CHECK-LABEL:  ssubo2.i32
    147 ; CHECK:        adds {{w[0-9]+}}, w0, #4
    148 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
    149   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)
    150   %val = extractvalue {i32, i1} %t, 0
    151   %obit = extractvalue {i32, i1} %t, 1
    152   store i32 %val, i32* %res
    153   ret i1 %obit
    154 }
    155 
    156 define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
    157 entry:
    158 ; CHECK-LABEL:  ssubo.i64
    159 ; CHECK:        subs {{x[0-9]+}}, x0, x1
    160 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
    161   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
    162   %val = extractvalue {i64, i1} %t, 0
    163   %obit = extractvalue {i64, i1} %t, 1
    164   store i64 %val, i64* %res
    165   ret i1 %obit
    166 }
    167 
    168 define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
    169 entry:
    170 ; CHECK-LABEL:  usubo.i32
    171 ; CHECK:        subs {{w[0-9]+}}, w0, w1
    172 ; CHECK-NEXT:   cset {{w[0-9]+}}, lo
    173   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
    174   %val = extractvalue {i32, i1} %t, 0
    175   %obit = extractvalue {i32, i1} %t, 1
    176   store i32 %val, i32* %res
    177   ret i1 %obit
    178 }
    179 
    180 define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
    181 entry:
    182 ; CHECK-LABEL:  usubo.i64
    183 ; CHECK:        subs {{x[0-9]+}}, x0, x1
    184 ; CHECK-NEXT:   cset {{w[0-9]+}}, lo
    185   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
    186   %val = extractvalue {i64, i1} %t, 0
    187   %obit = extractvalue {i64, i1} %t, 1
    188   store i64 %val, i64* %res
    189   ret i1 %obit
    190 }
    191 
    192 define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
    193 entry:
    194 ; CHECK-LABEL:  smulo.i32
    195 ; CHECK:        smull x[[MREG:[0-9]+]], w0, w1
    196 ; CHECK-NEXT:   lsr x[[SREG:[0-9]+]], x[[MREG]], #32
    197 ; CHECK-NEXT:   cmp w[[SREG]], w[[MREG]], asr #31
    198 ; CHECK-NEXT:   cset {{w[0-9]+}}, ne
    199   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
    200   %val = extractvalue {i32, i1} %t, 0
    201   %obit = extractvalue {i32, i1} %t, 1
    202   store i32 %val, i32* %res
    203   ret i1 %obit
    204 }
    205 
    206 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
    207 entry:
    208 ; CHECK-LABEL:  smulo.i64
    209 ; CHECK:        mul [[MREG:x[0-9]+]], x0, x1
    210 ; CHECK-NEXT:   smulh [[HREG:x[0-9]+]], x0, x1
    211 ; CHECK-NEXT:   cmp [[HREG]], [[MREG]], asr #63
    212 ; CHECK-NEXT:   cset {{w[0-9]+}}, ne
    213   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
    214   %val = extractvalue {i64, i1} %t, 0
    215   %obit = extractvalue {i64, i1} %t, 1
    216   store i64 %val, i64* %res
    217   ret i1 %obit
    218 }
    219 
    220 define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) {
    221 entry:
    222 ; CHECK-LABEL:  smulo2.i64
    223 ; CHECK:        adds [[MREG:x[0-9]+]], x0, x0
    224 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
    225   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
    226   %val = extractvalue {i64, i1} %t, 0
    227   %obit = extractvalue {i64, i1} %t, 1
    228   store i64 %val, i64* %res
    229   ret i1 %obit
    230 }
    231 
    232 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
    233 entry:
    234 ; CHECK-LABEL:  umulo.i32
    235 ; CHECK:        umull [[MREG:x[0-9]+]], w0, w1
    236 ; CHECK-NEXT:   cmp xzr, [[MREG]], lsr #32
    237 ; CHECK-NEXT:   cset {{w[0-9]+}}, ne
    238   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
    239   %val = extractvalue {i32, i1} %t, 0
    240   %obit = extractvalue {i32, i1} %t, 1
    241   store i32 %val, i32* %res
    242   ret i1 %obit
    243 }
    244 
    245 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
    246 entry:
    247 ; CHECK-LABEL:  umulo.i64
    248 ; CHECK:        umulh [[MREG:x[0-9]+]], x0, x1
    249 ; CHECK-NEXT:   cmp xzr, [[MREG]]
    250 ; CHECK-NEXT:   cset {{w[0-9]+}}, ne
    251   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
    252   %val = extractvalue {i64, i1} %t, 0
    253   %obit = extractvalue {i64, i1} %t, 1
    254   store i64 %val, i64* %res
    255   ret i1 %obit
    256 }
    257 
    258 define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) {
    259 entry:
    260 ; CHECK-LABEL:  umulo2.i64
    261 ; CHECK:        adds [[MREG:x[0-9]+]], x0, x0
    262 ; CHECK-NEXT:   cset {{w[0-9]+}}, hs
    263   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
    264   %val = extractvalue {i64, i1} %t, 0
    265   %obit = extractvalue {i64, i1} %t, 1
    266   store i64 %val, i64* %res
    267   ret i1 %obit
    268 }
    269 
    270 
    271 ;
    272 ; Check the use of the overflow bit in combination with a select instruction.
    273 ;
    274 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
    275 entry:
    276 ; CHECK-LABEL:  saddo.select.i32
    277 ; CHECK:        cmn w0, w1
    278 ; CHECK-NEXT:   csel w0, w0, w1, vs
    279   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
    280   %obit = extractvalue {i32, i1} %t, 1
    281   %ret = select i1 %obit, i32 %v1, i32 %v2
    282   ret i32 %ret
    283 }
    284 
    285 define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
    286 entry:
    287 ; CHECK-LABEL:  saddo.not.i32
    288 ; CHECK:        cmn w0, w1
    289 ; CHECK-NEXT:   cset w0, vc
    290   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
    291   %obit = extractvalue {i32, i1} %t, 1
    292   %ret = xor i1 %obit, true
    293   ret i1 %ret
    294 }
    295 
    296 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
    297 entry:
    298 ; CHECK-LABEL:  saddo.select.i64
    299 ; CHECK:        cmn x0, x1
    300 ; CHECK-NEXT:   csel x0, x0, x1, vs
    301   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
    302   %obit = extractvalue {i64, i1} %t, 1
    303   %ret = select i1 %obit, i64 %v1, i64 %v2
    304   ret i64 %ret
    305 }
    306 
    307 define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
    308 entry:
    309 ; CHECK-LABEL:  saddo.not.i64
    310 ; CHECK:        cmn x0, x1
    311 ; CHECK-NEXT:   cset w0, vc
    312   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
    313   %obit = extractvalue {i64, i1} %t, 1
    314   %ret = xor i1 %obit, true
    315   ret i1 %ret
    316 }
    317 
    318 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
    319 entry:
    320 ; CHECK-LABEL:  uaddo.select.i32
    321 ; CHECK:        cmn w0, w1
    322 ; CHECK-NEXT:   csel w0, w0, w1, hs
    323   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
    324   %obit = extractvalue {i32, i1} %t, 1
    325   %ret = select i1 %obit, i32 %v1, i32 %v2
    326   ret i32 %ret
    327 }
    328 
    329 define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
    330 entry:
    331 ; CHECK-LABEL:  uaddo.not.i32
    332 ; CHECK:        cmn w0, w1
    333 ; CHECK-NEXT:   cset w0, lo
    334   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
    335   %obit = extractvalue {i32, i1} %t, 1
    336   %ret = xor i1 %obit, true
    337   ret i1 %ret
    338 }
    339 
    340 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
    341 entry:
    342 ; CHECK-LABEL:  uaddo.select.i64
    343 ; CHECK:        cmn x0, x1
    344 ; CHECK-NEXT:   csel x0, x0, x1, hs
    345   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
    346   %obit = extractvalue {i64, i1} %t, 1
    347   %ret = select i1 %obit, i64 %v1, i64 %v2
    348   ret i64 %ret
    349 }
    350 
    351 define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
    352 entry:
    353 ; CHECK-LABEL:  uaddo.not.i64
    354 ; CHECK:        cmn x0, x1
    355 ; CHECK-NEXT:   cset w0, lo
    356   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
    357   %obit = extractvalue {i64, i1} %t, 1
    358   %ret = xor i1 %obit, true
    359   ret i1 %ret
    360 }
    361 
    362 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
    363 entry:
    364 ; CHECK-LABEL:  ssubo.select.i32
    365 ; CHECK:        cmp w0, w1
    366 ; CHECK-NEXT:   csel w0, w0, w1, vs
    367   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
    368   %obit = extractvalue {i32, i1} %t, 1
    369   %ret = select i1 %obit, i32 %v1, i32 %v2
    370   ret i32 %ret
    371 }
    372 
    373 define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
    374 entry:
    375 ; CHECK-LABEL:  ssubo.not.i32
    376 ; CHECK:        cmp w0, w1
    377 ; CHECK-NEXT:   cset w0, vc
    378   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
    379   %obit = extractvalue {i32, i1} %t, 1
    380   %ret = xor i1 %obit, true
    381   ret i1 %ret
    382 }
    383 
    384 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
    385 entry:
    386 ; CHECK-LABEL:  ssubo.select.i64
    387 ; CHECK:        cmp x0, x1
    388 ; CHECK-NEXT:   csel x0, x0, x1, vs
    389   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
    390   %obit = extractvalue {i64, i1} %t, 1
    391   %ret = select i1 %obit, i64 %v1, i64 %v2
    392   ret i64 %ret
    393 }
    394 
    395 define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
    396 entry:
    397 ; CHECK-LABEL:  ssub.not.i64
    398 ; CHECK:        cmp x0, x1
    399 ; CHECK-NEXT:   cset w0, vc
    400   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
    401   %obit = extractvalue {i64, i1} %t, 1
    402   %ret = xor i1 %obit, true
    403   ret i1 %ret
    404 }
    405 
    406 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
    407 entry:
    408 ; CHECK-LABEL:  usubo.select.i32
    409 ; CHECK:        cmp w0, w1
    410 ; CHECK-NEXT:   csel w0, w0, w1, lo
    411   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
    412   %obit = extractvalue {i32, i1} %t, 1
    413   %ret = select i1 %obit, i32 %v1, i32 %v2
    414   ret i32 %ret
    415 }
    416 
    417 define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
    418 entry:
    419 ; CHECK-LABEL:  usubo.not.i32
    420 ; CHECK:        cmp w0, w1
    421 ; CHECK-NEXT:   cset w0, hs
    422   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
    423   %obit = extractvalue {i32, i1} %t, 1
    424   %ret = xor i1 %obit, true
    425   ret i1 %ret
    426 }
    427 
    428 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
    429 entry:
    430 ; CHECK-LABEL:  usubo.select.i64
    431 ; CHECK:        cmp x0, x1
    432 ; CHECK-NEXT:   csel x0, x0, x1, lo
    433   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
    434   %obit = extractvalue {i64, i1} %t, 1
    435   %ret = select i1 %obit, i64 %v1, i64 %v2
    436   ret i64 %ret
    437 }
    438 
    439 define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
    440 entry:
    441 ; CHECK-LABEL:  usubo.not.i64
    442 ; CHECK:        cmp x0, x1
    443 ; CHECK-NEXT:   cset w0, hs
    444   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
    445   %obit = extractvalue {i64, i1} %t, 1
    446   %ret = xor i1 %obit, true
    447   ret i1 %ret
    448 }
    449 
    450 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
    451 entry:
    452 ; CHECK-LABEL:  smulo.select.i32
    453 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
    454 ; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x[[MREG]], #32
    455 ; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
    456 ; CHECK-NEXT:   csel    w0, w0, w1, ne
    457   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
    458   %obit = extractvalue {i32, i1} %t, 1
    459   %ret = select i1 %obit, i32 %v1, i32 %v2
    460   ret i32 %ret
    461 }
    462 
    463 define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
    464 entry:
    465 ; CHECK-LABEL:  smulo.not.i32
    466 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
    467 ; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x[[MREG]], #32
    468 ; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
    469 ; CHECK-NEXT:   cset    w0, eq
    470   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
    471   %obit = extractvalue {i32, i1} %t, 1
    472   %ret = xor i1 %obit, true
    473   ret i1 %ret
    474 }
    475 
    476 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
    477 entry:
    478 ; CHECK-LABEL:  smulo.select.i64
    479 ; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
    480 ; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
    481 ; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
    482 ; CHECK-NEXT:   csel    x0, x0, x1, ne
    483   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
    484   %obit = extractvalue {i64, i1} %t, 1
    485   %ret = select i1 %obit, i64 %v1, i64 %v2
    486   ret i64 %ret
    487 }
    488 
    489 define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
    490 entry:
    491 ; CHECK-LABEL:  smulo.not.i64
    492 ; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
    493 ; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
    494 ; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
    495 ; CHECK-NEXT:   cset    w0, eq
    496   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
    497   %obit = extractvalue {i64, i1} %t, 1
    498   %ret = xor i1 %obit, true
    499   ret i1 %ret
    500 }
    501 
    502 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
    503 entry:
    504 ; CHECK-LABEL:  umulo.select.i32
    505 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
    506 ; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
    507 ; CHECK-NEXT:   csel    w0, w0, w1, ne
    508   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
    509   %obit = extractvalue {i32, i1} %t, 1
    510   %ret = select i1 %obit, i32 %v1, i32 %v2
    511   ret i32 %ret
    512 }
    513 
    514 define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
    515 entry:
    516 ; CHECK-LABEL:  umulo.not.i32
    517 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
    518 ; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
    519 ; CHECK-NEXT:   cset    w0, eq
    520   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
    521   %obit = extractvalue {i32, i1} %t, 1
    522   %ret = xor i1 %obit, true
    523   ret i1 %ret
    524 }
    525 
    526 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
    527 entry:
    528 ; CHECK-LABEL:  umulo.select.i64
    529 ; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
    530 ; CHECK-NEXT:   cmp     xzr, [[MREG]]
    531 ; CHECK-NEXT:   csel    x0, x0, x1, ne
    532   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
    533   %obit = extractvalue {i64, i1} %t, 1
    534   %ret = select i1 %obit, i64 %v1, i64 %v2
    535   ret i64 %ret
    536 }
    537 
    538 define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
    539 entry:
    540 ; CHECK-LABEL:  umulo.not.i64
    541 ; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
    542 ; CHECK-NEXT:   cmp     xzr, [[MREG]]
    543 ; CHECK-NEXT:   cset    w0, eq
    544   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
    545   %obit = extractvalue {i64, i1} %t, 1
    546   %ret = xor i1 %obit, true
    547   ret i1 %ret
    548 }
    549 
    550 
    551 ;
    552 ; Check the use of the overflow bit in combination with a branch instruction.
    553 ;
    554 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
    555 entry:
    556 ; CHECK-LABEL:  saddo.br.i32
    557 ; CHECK:        cmn w0, w1
    558 ; CHECK-NEXT:   b.vc
    559   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
    560   %val = extractvalue {i32, i1} %t, 0
    561   %obit = extractvalue {i32, i1} %t, 1
    562   br i1 %obit, label %overflow, label %continue
    563 
    564 overflow:
    565   ret i1 false
    566 
    567 continue:
    568   ret i1 true
    569 }
    570 
    571 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
    572 entry:
    573 ; CHECK-LABEL:  saddo.br.i64
    574 ; CHECK:        cmn x0, x1
    575 ; CHECK-NEXT:   b.vc
    576   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
    577   %val = extractvalue {i64, i1} %t, 0
    578   %obit = extractvalue {i64, i1} %t, 1
    579   br i1 %obit, label %overflow, label %continue
    580 
    581 overflow:
    582   ret i1 false
    583 
    584 continue:
    585   ret i1 true
    586 }
    587 
    588 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
    589 entry:
    590 ; CHECK-LABEL:  uaddo.br.i32
    591 ; CHECK:        cmn w0, w1
    592 ; CHECK-NEXT:   b.lo
    593   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
    594   %val = extractvalue {i32, i1} %t, 0
    595   %obit = extractvalue {i32, i1} %t, 1
    596   br i1 %obit, label %overflow, label %continue
    597 
    598 overflow:
    599   ret i1 false
    600 
    601 continue:
    602   ret i1 true
    603 }
    604 
    605 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
    606 entry:
    607 ; CHECK-LABEL:  uaddo.br.i64
    608 ; CHECK:        cmn x0, x1
    609 ; CHECK-NEXT:   b.lo
    610   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
    611   %val = extractvalue {i64, i1} %t, 0
    612   %obit = extractvalue {i64, i1} %t, 1
    613   br i1 %obit, label %overflow, label %continue
    614 
    615 overflow:
    616   ret i1 false
    617 
    618 continue:
    619   ret i1 true
    620 }
    621 
    622 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
    623 entry:
    624 ; CHECK-LABEL:  ssubo.br.i32
    625 ; CHECK:        cmp w0, w1
    626 ; CHECK-NEXT:   b.vc
    627   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
    628   %val = extractvalue {i32, i1} %t, 0
    629   %obit = extractvalue {i32, i1} %t, 1
    630   br i1 %obit, label %overflow, label %continue
    631 
    632 overflow:
    633   ret i1 false
    634 
    635 continue:
    636   ret i1 true
    637 }
    638 
    639 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
    640 entry:
    641 ; CHECK-LABEL:  ssubo.br.i64
    642 ; CHECK:        cmp x0, x1
    643 ; CHECK-NEXT:   b.vc
    644   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
    645   %val = extractvalue {i64, i1} %t, 0
    646   %obit = extractvalue {i64, i1} %t, 1
    647   br i1 %obit, label %overflow, label %continue
    648 
    649 overflow:
    650   ret i1 false
    651 
    652 continue:
    653   ret i1 true
    654 }
    655 
    656 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
    657 entry:
    658 ; CHECK-LABEL:  usubo.br.i32
    659 ; CHECK:        cmp w0, w1
    660 ; CHECK-NEXT:   b.hs
    661   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
    662   %val = extractvalue {i32, i1} %t, 0
    663   %obit = extractvalue {i32, i1} %t, 1
    664   br i1 %obit, label %overflow, label %continue
    665 
    666 overflow:
    667   ret i1 false
    668 
    669 continue:
    670   ret i1 true
    671 }
    672 
    673 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
    674 entry:
    675 ; CHECK-LABEL:  usubo.br.i64
    676 ; CHECK:        cmp x0, x1
    677 ; CHECK-NEXT:   b.hs
    678   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
    679   %val = extractvalue {i64, i1} %t, 0
    680   %obit = extractvalue {i64, i1} %t, 1
    681   br i1 %obit, label %overflow, label %continue
    682 
    683 overflow:
    684   ret i1 false
    685 
    686 continue:
    687   ret i1 true
    688 }
    689 
    690 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
    691 entry:
    692 ; CHECK-LABEL:  smulo.br.i32
    693 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
    694 ; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x8, #32
    695 ; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
    696 ; CHECK-NEXT:   b.eq
    697   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
    698   %val = extractvalue {i32, i1} %t, 0
    699   %obit = extractvalue {i32, i1} %t, 1
    700   br i1 %obit, label %overflow, label %continue
    701 
    702 overflow:
    703   ret i1 false
    704 
    705 continue:
    706   ret i1 true
    707 }
    708 
    709 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
    710 entry:
    711 ; CHECK-LABEL:  smulo.br.i64
    712 ; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
    713 ; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
    714 ; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
    715 ; CHECK-NEXT:   b.eq
    716   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
    717   %val = extractvalue {i64, i1} %t, 0
    718   %obit = extractvalue {i64, i1} %t, 1
    719   br i1 %obit, label %overflow, label %continue
    720 
    721 overflow:
    722   ret i1 false
    723 
    724 continue:
    725   ret i1 true
    726 }
    727 
    728 define zeroext i1 @smulo2.br.i64(i64 %v1) {
    729 entry:
    730 ; CHECK-LABEL:  smulo2.br.i64
    731 ; CHECK:        cmn  x0, x0
    732 ; CHECK-NEXT:   b.vc
    733   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
    734   %val = extractvalue {i64, i1} %t, 0
    735   %obit = extractvalue {i64, i1} %t, 1
    736   br i1 %obit, label %overflow, label %continue
    737 
    738 overflow:
    739   ret i1 false
    740 
    741 continue:
    742   ret i1 true
    743 }
    744 
    745 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
    746 entry:
    747 ; CHECK-LABEL:  umulo.br.i32
    748 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
    749 ; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
    750 ; CHECK-NEXT:   b.eq
    751   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
    752   %val = extractvalue {i32, i1} %t, 0
    753   %obit = extractvalue {i32, i1} %t, 1
    754   br i1 %obit, label %overflow, label %continue
    755 
    756 overflow:
    757   ret i1 false
    758 
    759 continue:
    760   ret i1 true
    761 }
    762 
    763 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
    764 entry:
    765 ; CHECK-LABEL:  umulo.br.i64
    766 ; CHECK:        umulh   [[REG:x[0-9]+]], x0, x1
    767 ; CHECK-NEXT:   {{cbz|cmp}}
    768   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
    769   %val = extractvalue {i64, i1} %t, 0
    770   %obit = extractvalue {i64, i1} %t, 1
    771   br i1 %obit, label %overflow, label %continue
    772 
    773 overflow:
    774   ret i1 false
    775 
    776 continue:
    777   ret i1 true
    778 }
    779 
    780 define zeroext i1 @umulo2.br.i64(i64 %v1) {
    781 entry:
    782 ; CHECK-LABEL:  umulo2.br.i64
    783 ; CHECK:        cmn  x0, x0
    784 ; CHECK-NEXT:   b.lo
    785   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
    786   %val = extractvalue {i64, i1} %t, 0
    787   %obit = extractvalue {i64, i1} %t, 1
    788   br i1 %obit, label %overflow, label %continue
    789 
    790 overflow:
    791   ret i1 false
    792 
    793 continue:
    794   ret i1 true
    795 }
    796 
    797 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
    798 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
    799 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
    800 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
    801 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
    802 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
    803 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
    804 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
    805 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
    806 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
    807 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
    808 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
    809 
    810