Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -march=arm64 -aarch64-atomic-cfg-tidy=0 -disable-post-ra -verify-machineinstrs < %s | FileCheck %s
      2 ; RUN: llc -march=arm64 -aarch64-atomic-cfg-tidy=0 -fast-isel -fast-isel-abort=1 -disable-post-ra -verify-machineinstrs < %s | 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 i64 @saddo.select.i64(i64 %v1, i64 %v2) {
    286 entry:
    287 ; CHECK-LABEL:  saddo.select.i64
    288 ; CHECK:        cmn x0, x1
    289 ; CHECK-NEXT:   csel x0, x0, x1, vs
    290   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
    291   %obit = extractvalue {i64, i1} %t, 1
    292   %ret = select i1 %obit, i64 %v1, i64 %v2
    293   ret i64 %ret
    294 }
    295 
    296 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
    297 entry:
    298 ; CHECK-LABEL:  uaddo.select.i32
    299 ; CHECK:        cmn w0, w1
    300 ; CHECK-NEXT:   csel w0, w0, w1, hs
    301   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
    302   %obit = extractvalue {i32, i1} %t, 1
    303   %ret = select i1 %obit, i32 %v1, i32 %v2
    304   ret i32 %ret
    305 }
    306 
    307 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
    308 entry:
    309 ; CHECK-LABEL:  uaddo.select.i64
    310 ; CHECK:        cmn x0, x1
    311 ; CHECK-NEXT:   csel x0, x0, x1, hs
    312   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
    313   %obit = extractvalue {i64, i1} %t, 1
    314   %ret = select i1 %obit, i64 %v1, i64 %v2
    315   ret i64 %ret
    316 }
    317 
    318 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
    319 entry:
    320 ; CHECK-LABEL:  ssubo.select.i32
    321 ; CHECK:        cmp w0, w1
    322 ; CHECK-NEXT:   csel w0, w0, w1, vs
    323   %t = call {i32, i1} @llvm.ssub.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 i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
    330 entry:
    331 ; CHECK-LABEL:  ssubo.select.i64
    332 ; CHECK:        cmp x0, x1
    333 ; CHECK-NEXT:   csel x0, x0, x1, vs
    334   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
    335   %obit = extractvalue {i64, i1} %t, 1
    336   %ret = select i1 %obit, i64 %v1, i64 %v2
    337   ret i64 %ret
    338 }
    339 
    340 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
    341 entry:
    342 ; CHECK-LABEL:  usubo.select.i32
    343 ; CHECK:        cmp w0, w1
    344 ; CHECK-NEXT:   csel w0, w0, w1, lo
    345   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
    346   %obit = extractvalue {i32, i1} %t, 1
    347   %ret = select i1 %obit, i32 %v1, i32 %v2
    348   ret i32 %ret
    349 }
    350 
    351 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
    352 entry:
    353 ; CHECK-LABEL:  usubo.select.i64
    354 ; CHECK:        cmp x0, x1
    355 ; CHECK-NEXT:   csel x0, x0, x1, lo
    356   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
    357   %obit = extractvalue {i64, i1} %t, 1
    358   %ret = select i1 %obit, i64 %v1, i64 %v2
    359   ret i64 %ret
    360 }
    361 
    362 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
    363 entry:
    364 ; CHECK-LABEL:  smulo.select.i32
    365 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
    366 ; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x[[MREG]], #32
    367 ; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
    368 ; CHECK-NEXT:   csel    w0, w0, w1, ne
    369   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
    370   %obit = extractvalue {i32, i1} %t, 1
    371   %ret = select i1 %obit, i32 %v1, i32 %v2
    372   ret i32 %ret
    373 }
    374 
    375 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
    376 entry:
    377 ; CHECK-LABEL:  smulo.select.i64
    378 ; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
    379 ; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
    380 ; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
    381 ; CHECK-NEXT:   csel    x0, x0, x1, ne
    382   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
    383   %obit = extractvalue {i64, i1} %t, 1
    384   %ret = select i1 %obit, i64 %v1, i64 %v2
    385   ret i64 %ret
    386 }
    387 
    388 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
    389 entry:
    390 ; CHECK-LABEL:  umulo.select.i32
    391 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
    392 ; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
    393 ; CHECK-NEXT:   csel    w0, w0, w1, ne
    394   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
    395   %obit = extractvalue {i32, i1} %t, 1
    396   %ret = select i1 %obit, i32 %v1, i32 %v2
    397   ret i32 %ret
    398 }
    399 
    400 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
    401 entry:
    402 ; CHECK-LABEL:  umulo.select.i64
    403 ; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
    404 ; CHECK-NEXT:   cmp     xzr, [[MREG]]
    405 ; CHECK-NEXT:   csel    x0, x0, x1, ne
    406   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
    407   %obit = extractvalue {i64, i1} %t, 1
    408   %ret = select i1 %obit, i64 %v1, i64 %v2
    409   ret i64 %ret
    410 }
    411 
    412 
    413 ;
    414 ; Check the use of the overflow bit in combination with a branch instruction.
    415 ;
    416 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
    417 entry:
    418 ; CHECK-LABEL:  saddo.br.i32
    419 ; CHECK:        cmn w0, w1
    420 ; CHECK-NEXT:   b.vc
    421   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
    422   %val = extractvalue {i32, i1} %t, 0
    423   %obit = extractvalue {i32, i1} %t, 1
    424   br i1 %obit, label %overflow, label %continue
    425 
    426 overflow:
    427   ret i1 false
    428 
    429 continue:
    430   ret i1 true
    431 }
    432 
    433 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
    434 entry:
    435 ; CHECK-LABEL:  saddo.br.i64
    436 ; CHECK:        cmn x0, x1
    437 ; CHECK-NEXT:   b.vc
    438   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
    439   %val = extractvalue {i64, i1} %t, 0
    440   %obit = extractvalue {i64, i1} %t, 1
    441   br i1 %obit, label %overflow, label %continue
    442 
    443 overflow:
    444   ret i1 false
    445 
    446 continue:
    447   ret i1 true
    448 }
    449 
    450 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
    451 entry:
    452 ; CHECK-LABEL:  uaddo.br.i32
    453 ; CHECK:        cmn w0, w1
    454 ; CHECK-NEXT:   b.lo
    455   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
    456   %val = extractvalue {i32, i1} %t, 0
    457   %obit = extractvalue {i32, i1} %t, 1
    458   br i1 %obit, label %overflow, label %continue
    459 
    460 overflow:
    461   ret i1 false
    462 
    463 continue:
    464   ret i1 true
    465 }
    466 
    467 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
    468 entry:
    469 ; CHECK-LABEL:  uaddo.br.i64
    470 ; CHECK:        cmn x0, x1
    471 ; CHECK-NEXT:   b.lo
    472   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
    473   %val = extractvalue {i64, i1} %t, 0
    474   %obit = extractvalue {i64, i1} %t, 1
    475   br i1 %obit, label %overflow, label %continue
    476 
    477 overflow:
    478   ret i1 false
    479 
    480 continue:
    481   ret i1 true
    482 }
    483 
    484 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
    485 entry:
    486 ; CHECK-LABEL:  ssubo.br.i32
    487 ; CHECK:        cmp w0, w1
    488 ; CHECK-NEXT:   b.vc
    489   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
    490   %val = extractvalue {i32, i1} %t, 0
    491   %obit = extractvalue {i32, i1} %t, 1
    492   br i1 %obit, label %overflow, label %continue
    493 
    494 overflow:
    495   ret i1 false
    496 
    497 continue:
    498   ret i1 true
    499 }
    500 
    501 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
    502 entry:
    503 ; CHECK-LABEL:  ssubo.br.i64
    504 ; CHECK:        cmp x0, x1
    505 ; CHECK-NEXT:   b.vc
    506   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
    507   %val = extractvalue {i64, i1} %t, 0
    508   %obit = extractvalue {i64, i1} %t, 1
    509   br i1 %obit, label %overflow, label %continue
    510 
    511 overflow:
    512   ret i1 false
    513 
    514 continue:
    515   ret i1 true
    516 }
    517 
    518 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
    519 entry:
    520 ; CHECK-LABEL:  usubo.br.i32
    521 ; CHECK:        cmp w0, w1
    522 ; CHECK-NEXT:   b.hs
    523   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
    524   %val = extractvalue {i32, i1} %t, 0
    525   %obit = extractvalue {i32, i1} %t, 1
    526   br i1 %obit, label %overflow, label %continue
    527 
    528 overflow:
    529   ret i1 false
    530 
    531 continue:
    532   ret i1 true
    533 }
    534 
    535 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
    536 entry:
    537 ; CHECK-LABEL:  usubo.br.i64
    538 ; CHECK:        cmp x0, x1
    539 ; CHECK-NEXT:   b.hs
    540   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
    541   %val = extractvalue {i64, i1} %t, 0
    542   %obit = extractvalue {i64, i1} %t, 1
    543   br i1 %obit, label %overflow, label %continue
    544 
    545 overflow:
    546   ret i1 false
    547 
    548 continue:
    549   ret i1 true
    550 }
    551 
    552 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
    553 entry:
    554 ; CHECK-LABEL:  smulo.br.i32
    555 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
    556 ; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x8, #32
    557 ; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
    558 ; CHECK-NEXT:   b.eq
    559   %t = call {i32, i1} @llvm.smul.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 @smulo.br.i64(i64 %v1, i64 %v2) {
    572 entry:
    573 ; CHECK-LABEL:  smulo.br.i64
    574 ; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
    575 ; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
    576 ; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
    577 ; CHECK-NEXT:   b.eq
    578   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
    579   %val = extractvalue {i64, i1} %t, 0
    580   %obit = extractvalue {i64, i1} %t, 1
    581   br i1 %obit, label %overflow, label %continue
    582 
    583 overflow:
    584   ret i1 false
    585 
    586 continue:
    587   ret i1 true
    588 }
    589 
    590 define zeroext i1 @smulo2.br.i64(i64 %v1) {
    591 entry:
    592 ; CHECK-LABEL:  smulo2.br.i64
    593 ; CHECK:        cmn  x0, x0
    594 ; CHECK-NEXT:   b.vc
    595   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
    596   %val = extractvalue {i64, i1} %t, 0
    597   %obit = extractvalue {i64, i1} %t, 1
    598   br i1 %obit, label %overflow, label %continue
    599 
    600 overflow:
    601   ret i1 false
    602 
    603 continue:
    604   ret i1 true
    605 }
    606 
    607 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
    608 entry:
    609 ; CHECK-LABEL:  umulo.br.i32
    610 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
    611 ; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
    612 ; CHECK-NEXT:   b.eq
    613   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
    614   %val = extractvalue {i32, i1} %t, 0
    615   %obit = extractvalue {i32, i1} %t, 1
    616   br i1 %obit, label %overflow, label %continue
    617 
    618 overflow:
    619   ret i1 false
    620 
    621 continue:
    622   ret i1 true
    623 }
    624 
    625 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
    626 entry:
    627 ; CHECK-LABEL:  umulo.br.i64
    628 ; CHECK:        umulh   [[REG:x[0-9]+]], x0, x1
    629 ; CHECK-NEXT:   {{cbz|cmp}}
    630   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
    631   %val = extractvalue {i64, i1} %t, 0
    632   %obit = extractvalue {i64, i1} %t, 1
    633   br i1 %obit, label %overflow, label %continue
    634 
    635 overflow:
    636   ret i1 false
    637 
    638 continue:
    639   ret i1 true
    640 }
    641 
    642 define zeroext i1 @umulo2.br.i64(i64 %v1) {
    643 entry:
    644 ; CHECK-LABEL:  umulo2.br.i64
    645 ; CHECK:        cmn  x0, x0
    646 ; CHECK-NEXT:   b.lo
    647   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
    648   %val = extractvalue {i64, i1} %t, 0
    649   %obit = extractvalue {i64, i1} %t, 1
    650   br i1 %obit, label %overflow, label %continue
    651 
    652 overflow:
    653   ret i1 false
    654 
    655 continue:
    656   ret i1 true
    657 }
    658 
    659 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
    660 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
    661 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
    662 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
    663 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
    664 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
    665 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
    666 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
    667 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
    668 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
    669 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
    670 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
    671 
    672