[llvm] ba927f6 - [AArch64] Regenerate arith overflow test, and add a few more select tests. NFC

David Green via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 6 03:02:19 PST 2022


Author: David Green
Date: 2022-01-06T11:02:14Z
New Revision: ba927f66c0214f1353fc76b8f2aa8374c48bb13d

URL: https://github.com/llvm/llvm-project/commit/ba927f66c0214f1353fc76b8f2aa8374c48bb13d
DIFF: https://github.com/llvm/llvm-project/commit/ba927f66c0214f1353fc76b8f2aa8374c48bb13d.diff

LOG: [AArch64] Regenerate arith overflow test, and add a few more select tests. NFC

Added: 
    

Modified: 
    llvm/test/CodeGen/AArch64/arm64-xaluo.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/CodeGen/AArch64/arm64-xaluo.ll b/llvm/test/CodeGen/AArch64/arm64-xaluo.ll
index d8f5db89954f6..0ce5b8ab8e400 100644
--- a/llvm/test/CodeGen/AArch64/arm64-xaluo.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-xaluo.ll
@@ -1,15 +1,35 @@
-; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -disable-post-ra -verify-machineinstrs | FileCheck %s
-; 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
-; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -disable-post-ra -verify-machineinstrs | FileCheck %s --check-prefixes=GISEL,FALLBACK
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=arm64-eabi -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,SDAG
+; RUN: llc < %s -mtriple=arm64-eabi -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,FAST
+; RUN: llc < %s -mtriple=arm64-eabi -global-isel -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,GISEL
 
 ;
 ; Get the actual value of the overflow bit.
 ;
 define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, i32* %res) {
+; SDAG-LABEL: saddo1.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds w8, w0, w1
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str w8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo1.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds w8, w0, w1
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo1.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds w8, w0, w1
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str w8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo1.i32
-; CHECK:        adds {{w[0-9]+}}, w0, w1
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -19,10 +39,29 @@ entry:
 
 ; Test the immediate version.
 define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) {
+; SDAG-LABEL: saddo2.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds w8, w0, #4
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str w8, [x1]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo2.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds w8, w0, #4
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x1]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo2.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds w8, w0, #4
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str w8, [x1]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo2.i32
-; CHECK:        adds {{w[0-9]+}}, w0, #4
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -32,10 +71,29 @@ entry:
 
 ; Test negative immediates.
 define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) {
+; SDAG-LABEL: saddo3.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs w8, w0, #4
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str w8, [x1]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo3.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs w8, w0, #4
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x1]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo3.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs w8, w0, #4
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str w8, [x1]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo3.i32
-; CHECK:        subs {{w[0-9]+}}, w0, #4
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -45,10 +103,32 @@ entry:
 
 ; Test immediates that are too large to be encoded.
 define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) {
+; SDAG-LABEL: saddo4.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    mov w8, #16777215
+; SDAG-NEXT:    adds w8, w0, w8
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str w8, [x1]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo4.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    mov w8, #16777215
+; FAST-NEXT:    adds w8, w0, w8
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x1]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo4.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    mov w8, #16777215
+; GISEL-NEXT:    adds w8, w0, w8
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str w8, [x1]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo4.i32
-; CHECK:        adds {{w[0-9]+}}, w0, {{w[0-9]+}}
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -58,10 +138,29 @@ entry:
 
 ; Test shift folding.
 define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, i32* %res) {
+; SDAG-LABEL: saddo5.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds w8, w0, w1, lsl #16
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str w8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo5.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds w8, w0, w1, lsl #16
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo5.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds w8, w0, w1, lsl #16
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str w8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo5.i32
-; CHECK:        adds {{w[0-9]+}}, w0, w1
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %lsl = shl i32 %v2, 16
   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl)
   %val = extractvalue {i32, i1} %t, 0
@@ -71,10 +170,29 @@ entry:
 }
 
 define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) {
+; SDAG-LABEL: saddo1.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds x8, x0, x1
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str x8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo1.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds x8, x0, x1
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str x8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo1.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds x8, x0, x1
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str x8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo1.i64
-; CHECK:        adds {{x[0-9]+}}, x0, x1
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -83,10 +201,29 @@ entry:
 }
 
 define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) {
+; SDAG-LABEL: saddo2.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds x8, x0, #4
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str x8, [x1]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo2.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds x8, x0, #4
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str x8, [x1]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo2.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds x8, x0, #4
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str x8, [x1]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo2.i64
-; CHECK:        adds {{x[0-9]+}}, x0, #4
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -95,10 +232,29 @@ entry:
 }
 
 define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) {
+; SDAG-LABEL: saddo3.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs x8, x0, #4
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str x8, [x1]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo3.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs x8, x0, #4
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str x8, [x1]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo3.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs x8, x0, #4
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str x8, [x1]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo3.i64
-; CHECK:        subs {{x[0-9]+}}, x0, #4
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -106,15 +262,30 @@ entry:
   ret i1 %obit
 }
 
-; FALLBACK-NOT: remark{{.*}}uaddo.i32
 define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
+; SDAG-LABEL: uaddo.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds w8, w0, w1
+; SDAG-NEXT:    cset w0, hs
+; SDAG-NEXT:    str w8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds w8, w0, w1
+; FAST-NEXT:    cset w9, hs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds w8, w0, w1
+; GISEL-NEXT:    cset w9, hs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str w8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  uaddo.i32
-; CHECK:        adds {{w[0-9]+}}, w0, w1
-; CHECK-NEXT:   cset {{w[0-9]+}}, hs
-; GISEL-LABEL:  uaddo.i32
-; GISEL:        adds {{w[0-9]+}}, w0, w1
-; GISEL-NEXT:   cset {{w[0-9]+}}, hs
   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -122,15 +293,30 @@ entry:
   ret i1 %obit
 }
 
-; FALLBACK-NOT: remark{{.*}}uaddo.i64
 define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
+; SDAG-LABEL: uaddo.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds x8, x0, x1
+; SDAG-NEXT:    cset w0, hs
+; SDAG-NEXT:    str x8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds x8, x0, x1
+; FAST-NEXT:    cset w9, hs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str x8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds x8, x0, x1
+; GISEL-NEXT:    cset w9, hs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str x8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  uaddo.i64
-; CHECK:        adds {{x[0-9]+}}, x0, x1
-; CHECK-NEXT:   cset {{w[0-9]+}}, hs
-; GISEL-LABEL:  uaddo.i64
-; GISEL:        adds {{x[0-9]+}}, x0, x1
-; GISEL-NEXT:   cset {{w[0-9]+}}, hs
   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -139,10 +325,29 @@ entry:
 }
 
 define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) {
+; SDAG-LABEL: ssubo1.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs w8, w0, w1
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str w8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo1.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs w8, w0, w1
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo1.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs w8, w0, w1
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str w8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  ssubo1.i32
-; CHECK:        subs {{w[0-9]+}}, w0, w1
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -151,10 +356,29 @@ entry:
 }
 
 define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) {
+; SDAG-LABEL: ssubo2.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds w8, w0, #4
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str w8, [x1]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo2.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds w8, w0, #4
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x1]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo2.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds w8, w0, #4
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str w8, [x1]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  ssubo2.i32
-; CHECK:        adds {{w[0-9]+}}, w0, #4
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -163,10 +387,29 @@ entry:
 }
 
 define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
+; SDAG-LABEL: ssubo.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs x8, x0, x1
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str x8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs x8, x0, x1
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str x8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs x8, x0, x1
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str x8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  ssubo.i64
-; CHECK:        subs {{x[0-9]+}}, x0, x1
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -175,10 +418,29 @@ entry:
 }
 
 define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
+; SDAG-LABEL: usubo.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs w8, w0, w1
+; SDAG-NEXT:    cset w0, lo
+; SDAG-NEXT:    str w8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs w8, w0, w1
+; FAST-NEXT:    cset w9, lo
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs w8, w0, w1
+; GISEL-NEXT:    cset w9, lo
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str w8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  usubo.i32
-; CHECK:        subs {{w[0-9]+}}, w0, w1
-; CHECK-NEXT:   cset {{w[0-9]+}}, lo
   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -187,10 +449,29 @@ entry:
 }
 
 define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
+; SDAG-LABEL: usubo.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs x8, x0, x1
+; SDAG-NEXT:    cset w0, lo
+; SDAG-NEXT:    str x8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs x8, x0, x1
+; FAST-NEXT:    cset w9, lo
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str x8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs x8, x0, x1
+; GISEL-NEXT:    cset w9, lo
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str x8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  usubo.i64
-; CHECK:        subs {{x[0-9]+}}, x0, x1
-; CHECK-NEXT:   cset {{w[0-9]+}}, lo
   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -199,11 +480,33 @@ entry:
 }
 
 define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
+; SDAG-LABEL: smulo.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    smull x8, w0, w1
+; SDAG-NEXT:    cmp x8, w8, sxtw
+; SDAG-NEXT:    cset w0, ne
+; SDAG-NEXT:    str w8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    smull x8, w0, w1
+; FAST-NEXT:    cmp x8, w8, sxtw
+; FAST-NEXT:    cset w9, ne
+; FAST-NEXT:    str w8, [x2]
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    smull x8, w0, w1
+; GISEL-NEXT:    mul w9, w0, w1
+; GISEL-NEXT:    asr x8, x8, #32
+; GISEL-NEXT:    cmp w8, w9, asr #31
+; GISEL-NEXT:    cset w0, ne
+; GISEL-NEXT:    str w9, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo.i32
-; CHECK:        smull x[[MREG:[0-9]+]], w0, w1
-; CHECK-NEXT:   cmp x[[MREG]], w[[MREG]], sxtw
-; CHECK-NEXT:   cset {{w[0-9]+}}, ne
   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -212,12 +515,34 @@ entry:
 }
 
 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
+; SDAG-LABEL: smulo.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    mul x8, x0, x1
+; SDAG-NEXT:    smulh x9, x0, x1
+; SDAG-NEXT:    cmp x9, x8, asr #63
+; SDAG-NEXT:    cset w0, ne
+; SDAG-NEXT:    str x8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    mul x8, x0, x1
+; FAST-NEXT:    smulh x9, x0, x1
+; FAST-NEXT:    cmp x9, x8, asr #63
+; FAST-NEXT:    cset w9, ne
+; FAST-NEXT:    str x8, [x2]
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    mul x8, x0, x1
+; GISEL-NEXT:    smulh x9, x0, x1
+; GISEL-NEXT:    cmp x9, x8, asr #63
+; GISEL-NEXT:    cset w0, ne
+; GISEL-NEXT:    str x8, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo.i64
-; CHECK:        mul [[MREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   smulh [[HREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   cmp [[HREG]], [[MREG]], asr #63
-; CHECK-NEXT:   cset {{w[0-9]+}}, ne
   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -226,10 +551,29 @@ entry:
 }
 
 define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) {
+; SDAG-LABEL: smulo2.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds x8, x0, x0
+; SDAG-NEXT:    cset w0, vs
+; SDAG-NEXT:    str x8, [x1]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo2.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds x8, x0, x0
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str x8, [x1]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo2.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds x8, x0, x0
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str x8, [x1]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo2.i64
-; CHECK:        adds [[MREG:x[0-9]+]], x0, x0
-; CHECK-NEXT:   cset {{w[0-9]+}}, vs
   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -238,11 +582,34 @@ entry:
 }
 
 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
+; SDAG-LABEL: umulo.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umull x8, w0, w1
+; SDAG-NEXT:    tst x8, #0xffffffff00000000
+; SDAG-NEXT:    cset w0, ne
+; SDAG-NEXT:    str w8, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umull x8, w0, w1
+; FAST-NEXT:    tst x8, #0xffffffff00000000
+; FAST-NEXT:    cset w9, ne
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str w8, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umull x8, w0, w1
+; GISEL-NEXT:    mul w9, w0, w1
+; GISEL-NEXT:    lsr x8, x8, #32
+; GISEL-NEXT:    cmp w8, #0
+; GISEL-NEXT:    cset w8, ne
+; GISEL-NEXT:    mov w0, w8
+; GISEL-NEXT:    str w9, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo.i32
-; CHECK:        umull [[MREG:x[0-9]+]], w0, w1
-; CHECK-NEXT:   tst [[MREG]], #0xffffffff00000000
-; CHECK-NEXT:   cset {{w[0-9]+}}, ne
   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -251,11 +618,37 @@ entry:
 }
 
 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
+; SDAG-LABEL: umulo.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umulh x8, x0, x1
+; SDAG-NEXT:    mul x9, x0, x1
+; SDAG-NEXT:    cmp xzr, x8
+; SDAG-NEXT:    cset w8, ne
+; SDAG-NEXT:    mov w0, w8
+; SDAG-NEXT:    str x9, [x2]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umulh x8, x0, x1
+; FAST-NEXT:    mul x9, x0, x1
+; FAST-NEXT:    cmp xzr, x8
+; FAST-NEXT:    cset w8, ne
+; FAST-NEXT:    and w8, w8, #0x1
+; FAST-NEXT:    mov w0, w8
+; FAST-NEXT:    str x9, [x2]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umulh x8, x0, x1
+; GISEL-NEXT:    mul x9, x0, x1
+; GISEL-NEXT:    cmp x8, #0
+; GISEL-NEXT:    cset w8, ne
+; GISEL-NEXT:    mov w0, w8
+; GISEL-NEXT:    str x9, [x2]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo.i64
-; CHECK:        umulh [[MREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   cmp xzr, [[MREG]]
-; CHECK-NEXT:   cset {{w[0-9]+}}, ne
   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -264,10 +657,29 @@ entry:
 }
 
 define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) {
+; SDAG-LABEL: umulo2.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds x8, x0, x0
+; SDAG-NEXT:    cset w0, hs
+; SDAG-NEXT:    str x8, [x1]
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo2.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds x8, x0, x0
+; FAST-NEXT:    cset w9, hs
+; FAST-NEXT:    and w0, w9, #0x1
+; FAST-NEXT:    str x8, [x1]
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo2.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds x8, x0, x0
+; GISEL-NEXT:    cset w9, hs
+; GISEL-NEXT:    ubfx w0, w9, #0, #1
+; GISEL-NEXT:    str x8, [x1]
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo2.i64
-; CHECK:        adds [[MREG:x[0-9]+]], x0, x0
-; CHECK-NEXT:   cset {{w[0-9]+}}, hs
   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -280,10 +692,26 @@ entry:
 ; Check the use of the overflow bit in combination with a select instruction.
 ;
 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: saddo.select.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn w0, w1
+; SDAG-NEXT:    csel w0, w0, w1, vs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.select.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn w0, w1
+; FAST-NEXT:    csel w0, w0, w1, vs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.select.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn w0, w1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    csel w0, w0, w1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo.select.i32
-; CHECK:        cmn w0, w1
-; CHECK-NEXT:   csel w0, w0, w1, vs
   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = select i1 %obit, i32 %v1, i32 %v2
@@ -291,10 +719,26 @@ entry:
 }
 
 define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: saddo.not.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn w0, w1
+; SDAG-NEXT:    cset w0, vc
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.not.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn w0, w1
+; FAST-NEXT:    cset w0, vc
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.not.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn w0, w1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    eor w8, w8, #0x1
+; GISEL-NEXT:    and w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo.not.i32
-; CHECK:        cmn w0, w1
-; CHECK-NEXT:   cset w0, vc
   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -302,10 +746,26 @@ entry:
 }
 
 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: saddo.select.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn x0, x1
+; SDAG-NEXT:    csel x0, x0, x1, vs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.select.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn x0, x1
+; FAST-NEXT:    csel x0, x0, x1, vs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.select.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn x0, x1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    csel x0, x0, x1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo.select.i64
-; CHECK:        cmn x0, x1
-; CHECK-NEXT:   csel x0, x0, x1, vs
   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = select i1 %obit, i64 %v1, i64 %v2
@@ -313,10 +773,26 @@ entry:
 }
 
 define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: saddo.not.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn x0, x1
+; SDAG-NEXT:    cset w0, vc
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.not.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn x0, x1
+; FAST-NEXT:    cset w0, vc
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.not.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn x0, x1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    eor w8, w8, #0x1
+; GISEL-NEXT:    and w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo.not.i64
-; CHECK:        cmn x0, x1
-; CHECK-NEXT:   cset w0, vc
   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -324,10 +800,26 @@ entry:
 }
 
 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: uaddo.select.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn w0, w1
+; SDAG-NEXT:    csel w0, w0, w1, hs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.select.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn w0, w1
+; FAST-NEXT:    csel w0, w0, w1, hs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.select.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn w0, w1
+; GISEL-NEXT:    cset w8, hs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    csel w0, w0, w1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  uaddo.select.i32
-; CHECK:        cmn w0, w1
-; CHECK-NEXT:   csel w0, w0, w1, hs
   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = select i1 %obit, i32 %v1, i32 %v2
@@ -335,10 +827,26 @@ entry:
 }
 
 define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: uaddo.not.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn w0, w1
+; SDAG-NEXT:    cset w0, lo
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.not.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn w0, w1
+; FAST-NEXT:    cset w0, lo
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.not.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn w0, w1
+; GISEL-NEXT:    cset w8, hs
+; GISEL-NEXT:    eor w8, w8, #0x1
+; GISEL-NEXT:    and w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  uaddo.not.i32
-; CHECK:        cmn w0, w1
-; CHECK-NEXT:   cset w0, lo
   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -346,10 +854,26 @@ entry:
 }
 
 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: uaddo.select.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn x0, x1
+; SDAG-NEXT:    csel x0, x0, x1, hs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.select.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn x0, x1
+; FAST-NEXT:    csel x0, x0, x1, hs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.select.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn x0, x1
+; GISEL-NEXT:    cset w8, hs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    csel x0, x0, x1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  uaddo.select.i64
-; CHECK:        cmn x0, x1
-; CHECK-NEXT:   csel x0, x0, x1, hs
   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = select i1 %obit, i64 %v1, i64 %v2
@@ -357,10 +881,26 @@ entry:
 }
 
 define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: uaddo.not.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn x0, x1
+; SDAG-NEXT:    cset w0, lo
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.not.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn x0, x1
+; FAST-NEXT:    cset w0, lo
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.not.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn x0, x1
+; GISEL-NEXT:    cset w8, hs
+; GISEL-NEXT:    eor w8, w8, #0x1
+; GISEL-NEXT:    and w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  uaddo.not.i64
-; CHECK:        cmn x0, x1
-; CHECK-NEXT:   cset w0, lo
   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -368,10 +908,26 @@ entry:
 }
 
 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: ssubo.select.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp w0, w1
+; SDAG-NEXT:    csel w0, w0, w1, vs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo.select.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp w0, w1
+; FAST-NEXT:    csel w0, w0, w1, vs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo.select.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp w0, w1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    csel w0, w0, w1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  ssubo.select.i32
-; CHECK:        cmp w0, w1
-; CHECK-NEXT:   csel w0, w0, w1, vs
   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = select i1 %obit, i32 %v1, i32 %v2
@@ -379,10 +935,26 @@ entry:
 }
 
 define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: ssubo.not.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp w0, w1
+; SDAG-NEXT:    cset w0, vc
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo.not.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp w0, w1
+; FAST-NEXT:    cset w0, vc
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo.not.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp w0, w1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    eor w8, w8, #0x1
+; GISEL-NEXT:    and w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  ssubo.not.i32
-; CHECK:        cmp w0, w1
-; CHECK-NEXT:   cset w0, vc
   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -390,10 +962,26 @@ entry:
 }
 
 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: ssubo.select.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp x0, x1
+; SDAG-NEXT:    csel x0, x0, x1, vs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo.select.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp x0, x1
+; FAST-NEXT:    csel x0, x0, x1, vs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo.select.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp x0, x1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    csel x0, x0, x1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  ssubo.select.i64
-; CHECK:        cmp x0, x1
-; CHECK-NEXT:   csel x0, x0, x1, vs
   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = select i1 %obit, i64 %v1, i64 %v2
@@ -401,10 +989,26 @@ entry:
 }
 
 define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: ssub.not.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp x0, x1
+; SDAG-NEXT:    cset w0, vc
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssub.not.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp x0, x1
+; FAST-NEXT:    cset w0, vc
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssub.not.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp x0, x1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    eor w8, w8, #0x1
+; GISEL-NEXT:    and w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  ssub.not.i64
-; CHECK:        cmp x0, x1
-; CHECK-NEXT:   cset w0, vc
   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -412,10 +1016,26 @@ entry:
 }
 
 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: usubo.select.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp w0, w1
+; SDAG-NEXT:    csel w0, w0, w1, lo
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.select.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp w0, w1
+; FAST-NEXT:    csel w0, w0, w1, lo
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.select.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp w0, w1
+; GISEL-NEXT:    cset w8, lo
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    csel w0, w0, w1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  usubo.select.i32
-; CHECK:        cmp w0, w1
-; CHECK-NEXT:   csel w0, w0, w1, lo
   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = select i1 %obit, i32 %v1, i32 %v2
@@ -423,10 +1043,26 @@ entry:
 }
 
 define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: usubo.not.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp w0, w1
+; SDAG-NEXT:    cset w0, hs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.not.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp w0, w1
+; FAST-NEXT:    cset w0, hs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.not.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp w0, w1
+; GISEL-NEXT:    cset w8, lo
+; GISEL-NEXT:    eor w8, w8, #0x1
+; GISEL-NEXT:    and w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  usubo.not.i32
-; CHECK:        cmp w0, w1
-; CHECK-NEXT:   cset w0, hs
   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -434,10 +1070,26 @@ entry:
 }
 
 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: usubo.select.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp x0, x1
+; SDAG-NEXT:    csel x0, x0, x1, lo
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.select.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp x0, x1
+; FAST-NEXT:    csel x0, x0, x1, lo
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.select.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp x0, x1
+; GISEL-NEXT:    cset w8, lo
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    csel x0, x0, x1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  usubo.select.i64
-; CHECK:        cmp x0, x1
-; CHECK-NEXT:   csel x0, x0, x1, lo
   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = select i1 %obit, i64 %v1, i64 %v2
@@ -445,10 +1097,26 @@ entry:
 }
 
 define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: usubo.not.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp x0, x1
+; SDAG-NEXT:    cset w0, hs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.not.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp x0, x1
+; FAST-NEXT:    cset w0, hs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.not.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp x0, x1
+; GISEL-NEXT:    cset w8, lo
+; GISEL-NEXT:    eor w8, w8, #0x1
+; GISEL-NEXT:    and w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  usubo.not.i64
-; CHECK:        cmp x0, x1
-; CHECK-NEXT:   cset w0, hs
   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -456,11 +1124,29 @@ entry:
 }
 
 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: smulo.select.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    smull x8, w0, w1
+; SDAG-NEXT:    cmp x8, w8, sxtw
+; SDAG-NEXT:    csel w0, w0, w1, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.select.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    smull x8, w0, w1
+; FAST-NEXT:    cmp x8, w8, sxtw
+; FAST-NEXT:    csel w0, w0, w1, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.select.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    smull x8, w0, w1
+; GISEL-NEXT:    mul w9, w0, w1
+; GISEL-NEXT:    asr x8, x8, #32
+; GISEL-NEXT:    cmp w8, w9, asr #31
+; GISEL-NEXT:    csel w0, w0, w1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo.select.i32
-; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
-; CHECK-NEXT:   cmp     x[[MREG]], w[[MREG]], sxtw
-; CHECK-NEXT:   csel    w0, w0, w1, ne
   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = select i1 %obit, i32 %v1, i32 %v2
@@ -468,11 +1154,30 @@ entry:
 }
 
 define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: smulo.not.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    smull x8, w0, w1
+; SDAG-NEXT:    cmp x8, w8, sxtw
+; SDAG-NEXT:    cset w0, eq
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.not.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    smull x8, w0, w1
+; FAST-NEXT:    cmp x8, w8, sxtw
+; FAST-NEXT:    cset w0, eq
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.not.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    smull x8, w0, w1
+; GISEL-NEXT:    mul w9, w0, w1
+; GISEL-NEXT:    asr x8, x8, #32
+; GISEL-NEXT:    cmp w8, w9, asr #31
+; GISEL-NEXT:    cset w8, ne
+; GISEL-NEXT:    eor w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo.not.i32
-; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
-; CHECK-NEXT:   cmp     x[[MREG]], w[[MREG]], sxtw
-; CHECK-NEXT:   cset    w0, eq
   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -480,12 +1185,14 @@ entry:
 }
 
 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
+; CHECK-LABEL: smulo.select.i64:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    mul x8, x0, x1
+; CHECK-NEXT:    smulh x9, x0, x1
+; CHECK-NEXT:    cmp x9, x8, asr #63
+; CHECK-NEXT:    csel x0, x0, x1, ne
+; CHECK-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo.select.i64
-; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
-; CHECK-NEXT:   csel    x0, x0, x1, ne
   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = select i1 %obit, i64 %v1, i64 %v2
@@ -493,12 +1200,31 @@ entry:
 }
 
 define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: smulo.not.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    mul x8, x0, x1
+; SDAG-NEXT:    smulh x9, x0, x1
+; SDAG-NEXT:    cmp x9, x8, asr #63
+; SDAG-NEXT:    cset w0, eq
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.not.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    mul x8, x0, x1
+; FAST-NEXT:    smulh x9, x0, x1
+; FAST-NEXT:    cmp x9, x8, asr #63
+; FAST-NEXT:    cset w0, eq
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.not.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    mul x8, x0, x1
+; GISEL-NEXT:    smulh x9, x0, x1
+; GISEL-NEXT:    cmp x9, x8, asr #63
+; GISEL-NEXT:    cset w8, ne
+; GISEL-NEXT:    eor w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo.not.i64
-; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
-; CHECK-NEXT:   cset    w0, eq
   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -506,11 +1232,28 @@ entry:
 }
 
 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: umulo.select.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umull x8, w0, w1
+; SDAG-NEXT:    tst x8, #0xffffffff00000000
+; SDAG-NEXT:    csel w0, w0, w1, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.select.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umull x8, w0, w1
+; FAST-NEXT:    tst x8, #0xffffffff00000000
+; FAST-NEXT:    csel w0, w0, w1, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.select.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umull x8, w0, w1
+; GISEL-NEXT:    lsr x8, x8, #32
+; GISEL-NEXT:    cmp w8, #0
+; GISEL-NEXT:    csel w0, w0, w1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo.select.i32
-; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
-; CHECK-NEXT:   tst     [[MREG]], #0xffffffff00000000
-; CHECK-NEXT:   csel    w0, w0, w1, ne
   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = select i1 %obit, i32 %v1, i32 %v2
@@ -518,11 +1261,29 @@ entry:
 }
 
 define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: umulo.not.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umull x8, w0, w1
+; SDAG-NEXT:    tst x8, #0xffffffff00000000
+; SDAG-NEXT:    cset w0, eq
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.not.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umull x8, w0, w1
+; FAST-NEXT:    tst x8, #0xffffffff00000000
+; FAST-NEXT:    cset w0, eq
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.not.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umull x8, w0, w1
+; GISEL-NEXT:    lsr x8, x8, #32
+; GISEL-NEXT:    cmp w8, #0
+; GISEL-NEXT:    cset w8, ne
+; GISEL-NEXT:    eor w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo.not.i32
-; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
-; CHECK-NEXT:   tst     [[MREG]], #0xffffffff00000000
-; CHECK-NEXT:   cset    w0, eq
   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
   %obit = extractvalue {i32, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -530,11 +1291,27 @@ entry:
 }
 
 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: umulo.select.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umulh x8, x0, x1
+; SDAG-NEXT:    cmp xzr, x8
+; SDAG-NEXT:    csel x0, x0, x1, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.select.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umulh x8, x0, x1
+; FAST-NEXT:    cmp xzr, x8
+; FAST-NEXT:    csel x0, x0, x1, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.select.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umulh x8, x0, x1
+; GISEL-NEXT:    cmp x8, #0
+; GISEL-NEXT:    csel x0, x0, x1, ne
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo.select.i64
-; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   cmp     xzr, [[MREG]]
-; CHECK-NEXT:   csel    x0, x0, x1, ne
   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = select i1 %obit, i64 %v1, i64 %v2
@@ -542,11 +1319,28 @@ entry:
 }
 
 define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: umulo.not.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umulh x8, x0, x1
+; SDAG-NEXT:    cmp xzr, x8
+; SDAG-NEXT:    cset w0, eq
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.not.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umulh x8, x0, x1
+; FAST-NEXT:    cmp xzr, x8
+; FAST-NEXT:    cset w0, eq
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.not.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umulh x8, x0, x1
+; GISEL-NEXT:    cmp x8, #0
+; GISEL-NEXT:    cset w8, ne
+; GISEL-NEXT:    eor w0, w8, #0x1
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo.not.i64
-; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   cmp     xzr, [[MREG]]
-; CHECK-NEXT:   cset    w0, eq
   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
   %obit = extractvalue {i64, i1} %t, 1
   %ret = xor i1 %obit, true
@@ -554,14 +1348,821 @@ entry:
 }
 
 
+define i8 @uaddo.selectboth.i8(i8 %a, i8 %b) {
+; SDAG-LABEL: uaddo.selectboth.i8:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    and w8, w0, #0xff
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    add w8, w8, w1, uxtb
+; SDAG-NEXT:    tst w8, #0x100
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.selectboth.i8:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    and w8, w0, #0xff
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    add w8, w8, w1, uxtb
+; FAST-NEXT:    tst w8, #0x100
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.selectboth.i8:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    and w8, w1, #0xff
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    add w8, w8, w0, uxtb
+; GISEL-NEXT:    cmp w8, w8, uxtb
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
+  %m1 = extractvalue { i8, i1 } %m, 0
+  %m2 = extractvalue { i8, i1 } %m, 1
+  %r = select i1 %m2, i8 %m1, i8 10
+  ret i8 %r
+}
+
+define i8 @saddo.selectboth.i8(i8 %a, i8 %b) {
+; SDAG-LABEL: saddo.selectboth.i8:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    sxtb w8, w0
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    add w8, w8, w1, sxtb
+; SDAG-NEXT:    cmp w8, w8, sxtb
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.selectboth.i8:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    sxtb w8, w0
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    add w8, w8, w1, sxtb
+; FAST-NEXT:    cmp w8, w8, sxtb
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.selectboth.i8:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    sxtb w8, w1
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    add w8, w8, w0, sxtb
+; GISEL-NEXT:    cmp w8, w8, sxtb
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 %b)
+  %m1 = extractvalue { i8, i1 } %m, 0
+  %m2 = extractvalue { i8, i1 } %m, 1
+  %r = select i1 %m2, i8 %m1, i8 10
+  ret i8 %r
+}
+
+define i16 @uaddo.selectboth.i16(i16 %a, i16 %b) {
+; SDAG-LABEL: uaddo.selectboth.i16:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    and w8, w0, #0xffff
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    add w8, w8, w1, uxth
+; SDAG-NEXT:    tst w8, #0x10000
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.selectboth.i16:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    and w8, w0, #0xffff
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    add w8, w8, w1, uxth
+; FAST-NEXT:    tst w8, #0x10000
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.selectboth.i16:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    and w8, w1, #0xffff
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    add w8, w8, w0, uxth
+; GISEL-NEXT:    cmp w8, w8, uxth
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %a, i16 %b)
+  %m1 = extractvalue { i16, i1 } %m, 0
+  %m2 = extractvalue { i16, i1 } %m, 1
+  %r = select i1 %m2, i16 %m1, i16 10
+  ret i16 %r
+}
+
+define i16 @saddo.selectboth.i16(i16 %a, i16 %b) {
+; SDAG-LABEL: saddo.selectboth.i16:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    sxth w8, w0
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    add w8, w8, w1, sxth
+; SDAG-NEXT:    cmp w8, w8, sxth
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.selectboth.i16:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    sxth w8, w0
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    add w8, w8, w1, sxth
+; FAST-NEXT:    cmp w8, w8, sxth
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.selectboth.i16:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    sxth w8, w1
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    add w8, w8, w0, sxth
+; GISEL-NEXT:    cmp w8, w8, sxth
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i16, i1 } @llvm.sadd.with.overflow.i16(i16 %a, i16 %b)
+  %m1 = extractvalue { i16, i1 } %m, 0
+  %m2 = extractvalue { i16, i1 } %m, 1
+  %r = select i1 %m2, i16 %m1, i16 10
+  ret i16 %r
+}
+
+define i32 @uaddo.selectboth.i32(i32 %a, i32 %b) {
+; SDAG-LABEL: uaddo.selectboth.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds w8, w0, w1
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel w0, w8, w9, hs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.selectboth.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds w8, w0, w1
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    csel w0, w8, w9, hs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.selectboth.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds w8, w0, w1
+; GISEL-NEXT:    mov w10, #10
+; GISEL-NEXT:    cset w9, hs
+; GISEL-NEXT:    tst w9, #0x1
+; GISEL-NEXT:    csel w0, w8, w10, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
+  %m1 = extractvalue { i32, i1 } %m, 0
+  %m2 = extractvalue { i32, i1 } %m, 1
+  %r = select i1 %m2, i32 %m1, i32 10
+  ret i32 %r
+}
+
+define i32 @saddo.selectboth.i32(i32 %a, i32 %b) {
+; SDAG-LABEL: saddo.selectboth.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds w8, w0, w1
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel w0, w8, w9, vs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.selectboth.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds w8, w0, w1
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    csel w0, w8, w9, vs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.selectboth.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds w8, w0, w1
+; GISEL-NEXT:    mov w10, #10
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    tst w9, #0x1
+; GISEL-NEXT:    csel w0, w8, w10, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)
+  %m1 = extractvalue { i32, i1 } %m, 0
+  %m2 = extractvalue { i32, i1 } %m, 1
+  %r = select i1 %m2, i32 %m1, i32 10
+  ret i32 %r
+}
+
+define i64 @uaddo.selectboth.i64(i64 %a, i64 %b) {
+; SDAG-LABEL: uaddo.selectboth.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds x8, x0, x1
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel x0, x8, x9, hs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.selectboth.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds x8, x0, x1
+; FAST-NEXT:    mov x9, #10
+; FAST-NEXT:    csel x0, x8, x9, hs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.selectboth.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds x8, x0, x1
+; GISEL-NEXT:    mov w10, #10
+; GISEL-NEXT:    cset w9, hs
+; GISEL-NEXT:    tst w9, #0x1
+; GISEL-NEXT:    csel x0, x8, x10, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)
+  %m1 = extractvalue { i64, i1 } %m, 0
+  %m2 = extractvalue { i64, i1 } %m, 1
+  %r = select i1 %m2, i64 %m1, i64 10
+  ret i64 %r
+}
+
+define i64 @saddo.selectboth.i64(i64 %a, i64 %b) {
+; SDAG-LABEL: saddo.selectboth.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    adds x8, x0, x1
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel x0, x8, x9, vs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.selectboth.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    adds x8, x0, x1
+; FAST-NEXT:    mov x9, #10
+; FAST-NEXT:    csel x0, x8, x9, vs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.selectboth.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    adds x8, x0, x1
+; GISEL-NEXT:    mov w10, #10
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    tst w9, #0x1
+; GISEL-NEXT:    csel x0, x8, x10, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
+  %m1 = extractvalue { i64, i1 } %m, 0
+  %m2 = extractvalue { i64, i1 } %m, 1
+  %r = select i1 %m2, i64 %m1, i64 10
+  ret i64 %r
+}
+
+define i8 @usubo.selectboth.i8(i8 %a, i8 %b) {
+; SDAG-LABEL: usubo.selectboth.i8:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    and w8, w0, #0xff
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    sub w8, w8, w1, uxtb
+; SDAG-NEXT:    tst w8, #0xffffff00
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.selectboth.i8:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    and w8, w0, #0xff
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    sub w8, w8, w1, uxtb
+; FAST-NEXT:    tst w8, #0xffffff00
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.selectboth.i8:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    and w8, w0, #0xff
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    sub w8, w8, w1, uxtb
+; GISEL-NEXT:    cmp w8, w8, uxtb
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 %b)
+  %m1 = extractvalue { i8, i1 } %m, 0
+  %m2 = extractvalue { i8, i1 } %m, 1
+  %r = select i1 %m2, i8 %m1, i8 10
+  ret i8 %r
+}
+
+define i8 @ssubo.selectboth.i8(i8 %a, i8 %b) {
+; CHECK-LABEL: ssubo.selectboth.i8:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    sxtb w8, w0
+; CHECK-NEXT:    mov w9, #10
+; CHECK-NEXT:    sub w8, w8, w1, sxtb
+; CHECK-NEXT:    cmp w8, w8, sxtb
+; CHECK-NEXT:    csel w0, w8, w9, ne
+; CHECK-NEXT:    ret
+entry:
+  %m = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 %b)
+  %m1 = extractvalue { i8, i1 } %m, 0
+  %m2 = extractvalue { i8, i1 } %m, 1
+  %r = select i1 %m2, i8 %m1, i8 10
+  ret i8 %r
+}
+
+define i16 @usubo.selectboth.i16(i16 %a, i16 %b) {
+; SDAG-LABEL: usubo.selectboth.i16:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    and w8, w0, #0xffff
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    sub w8, w8, w1, uxth
+; SDAG-NEXT:    tst w8, #0xffff0000
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.selectboth.i16:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    and w8, w0, #0xffff
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    sub w8, w8, w1, uxth
+; FAST-NEXT:    tst w8, #0xffff0000
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.selectboth.i16:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    and w8, w0, #0xffff
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    sub w8, w8, w1, uxth
+; GISEL-NEXT:    cmp w8, w8, uxth
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 %a, i16 %b)
+  %m1 = extractvalue { i16, i1 } %m, 0
+  %m2 = extractvalue { i16, i1 } %m, 1
+  %r = select i1 %m2, i16 %m1, i16 10
+  ret i16 %r
+}
+
+define i16 @ssubo.selectboth.i16(i16 %a, i16 %b) {
+; CHECK-LABEL: ssubo.selectboth.i16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    sxth w8, w0
+; CHECK-NEXT:    mov w9, #10
+; CHECK-NEXT:    sub w8, w8, w1, sxth
+; CHECK-NEXT:    cmp w8, w8, sxth
+; CHECK-NEXT:    csel w0, w8, w9, ne
+; CHECK-NEXT:    ret
+entry:
+  %m = call { i16, i1 } @llvm.ssub.with.overflow.i16(i16 %a, i16 %b)
+  %m1 = extractvalue { i16, i1 } %m, 0
+  %m2 = extractvalue { i16, i1 } %m, 1
+  %r = select i1 %m2, i16 %m1, i16 10
+  ret i16 %r
+}
+
+define i32 @usubo.selectboth.i32(i32 %a, i32 %b) {
+; SDAG-LABEL: usubo.selectboth.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs w8, w0, w1
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel w0, w8, w9, lo
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.selectboth.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs w8, w0, w1
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    csel w0, w8, w9, lo
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.selectboth.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs w8, w0, w1
+; GISEL-NEXT:    mov w10, #10
+; GISEL-NEXT:    cset w9, lo
+; GISEL-NEXT:    tst w9, #0x1
+; GISEL-NEXT:    csel w0, w8, w10, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
+  %m1 = extractvalue { i32, i1 } %m, 0
+  %m2 = extractvalue { i32, i1 } %m, 1
+  %r = select i1 %m2, i32 %m1, i32 10
+  ret i32 %r
+}
+
+define i32 @ssubo.selectboth.i32(i32 %a, i32 %b) {
+; SDAG-LABEL: ssubo.selectboth.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs w8, w0, w1
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel w0, w8, w9, vs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo.selectboth.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs w8, w0, w1
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    csel w0, w8, w9, vs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo.selectboth.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs w8, w0, w1
+; GISEL-NEXT:    mov w10, #10
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    tst w9, #0x1
+; GISEL-NEXT:    csel w0, w8, w10, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
+  %m1 = extractvalue { i32, i1 } %m, 0
+  %m2 = extractvalue { i32, i1 } %m, 1
+  %r = select i1 %m2, i32 %m1, i32 10
+  ret i32 %r
+}
+
+define i64 @usubo.selectboth.i64(i64 %a, i64 %b) {
+; SDAG-LABEL: usubo.selectboth.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs x8, x0, x1
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel x0, x8, x9, lo
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.selectboth.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs x8, x0, x1
+; FAST-NEXT:    mov x9, #10
+; FAST-NEXT:    csel x0, x8, x9, lo
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.selectboth.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs x8, x0, x1
+; GISEL-NEXT:    mov w10, #10
+; GISEL-NEXT:    cset w9, lo
+; GISEL-NEXT:    tst w9, #0x1
+; GISEL-NEXT:    csel x0, x8, x10, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b)
+  %m1 = extractvalue { i64, i1 } %m, 0
+  %m2 = extractvalue { i64, i1 } %m, 1
+  %r = select i1 %m2, i64 %m1, i64 10
+  ret i64 %r
+}
+
+define i64 @ssubo.selectboth.i64(i64 %a, i64 %b) {
+; SDAG-LABEL: ssubo.selectboth.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    subs x8, x0, x1
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel x0, x8, x9, vs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo.selectboth.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    subs x8, x0, x1
+; FAST-NEXT:    mov x9, #10
+; FAST-NEXT:    csel x0, x8, x9, vs
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo.selectboth.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    subs x8, x0, x1
+; GISEL-NEXT:    mov w10, #10
+; GISEL-NEXT:    cset w9, vs
+; GISEL-NEXT:    tst w9, #0x1
+; GISEL-NEXT:    csel x0, x8, x10, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
+  %m1 = extractvalue { i64, i1 } %m, 0
+  %m2 = extractvalue { i64, i1 } %m, 1
+  %r = select i1 %m2, i64 %m1, i64 10
+  ret i64 %r
+}
+
+
+define i8 @umulo.selectboth.i8(i8 %a, i8 %b) {
+; SDAG-LABEL: umulo.selectboth.i8:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    and w8, w1, #0xff
+; SDAG-NEXT:    and w9, w0, #0xff
+; SDAG-NEXT:    mul w8, w9, w8
+; SDAG-NEXT:    lsr w9, w8, #8
+; SDAG-NEXT:    cmp w9, #0
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.selectboth.i8:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    and w8, w1, #0xff
+; FAST-NEXT:    and w9, w0, #0xff
+; FAST-NEXT:    mul w8, w9, w8
+; FAST-NEXT:    lsr w9, w8, #8
+; FAST-NEXT:    cmp w9, #0
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.selectboth.i8:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    and w8, w0, #0xff
+; GISEL-NEXT:    and w9, w1, #0xff
+; GISEL-NEXT:    mul w8, w8, w9
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    cmp w8, w8, uxtb
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 %b)
+  %m1 = extractvalue { i8, i1 } %m, 0
+  %m2 = extractvalue { i8, i1 } %m, 1
+  %r = select i1 %m2, i8 %m1, i8 10
+  ret i8 %r
+}
+
+define i8 @smulo.selectboth.i8(i8 %a, i8 %b) {
+; SDAG-LABEL: smulo.selectboth.i8:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    sxtb w8, w1
+; SDAG-NEXT:    sxtb w9, w0
+; SDAG-NEXT:    mul w8, w9, w8
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    cmp w8, w8, sxtb
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.selectboth.i8:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    sxtb w8, w1
+; FAST-NEXT:    sxtb w9, w0
+; FAST-NEXT:    mul w8, w9, w8
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    cmp w8, w8, sxtb
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.selectboth.i8:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    sxtb w8, w0
+; GISEL-NEXT:    sxtb w9, w1
+; GISEL-NEXT:    mul w8, w8, w9
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    cmp w8, w8, sxtb
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 %b)
+  %m1 = extractvalue { i8, i1 } %m, 0
+  %m2 = extractvalue { i8, i1 } %m, 1
+  %r = select i1 %m2, i8 %m1, i8 10
+  ret i8 %r
+}
+
+define i16 @umulo.selectboth.i16(i16 %a, i16 %b) {
+; SDAG-LABEL: umulo.selectboth.i16:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    and w8, w1, #0xffff
+; SDAG-NEXT:    and w9, w0, #0xffff
+; SDAG-NEXT:    mul w8, w9, w8
+; SDAG-NEXT:    lsr w9, w8, #16
+; SDAG-NEXT:    cmp w9, #0
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.selectboth.i16:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    and w8, w1, #0xffff
+; FAST-NEXT:    and w9, w0, #0xffff
+; FAST-NEXT:    mul w8, w9, w8
+; FAST-NEXT:    lsr w9, w8, #16
+; FAST-NEXT:    cmp w9, #0
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.selectboth.i16:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    and w8, w0, #0xffff
+; GISEL-NEXT:    and w9, w1, #0xffff
+; GISEL-NEXT:    mul w8, w8, w9
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    cmp w8, w8, uxth
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 %a, i16 %b)
+  %m1 = extractvalue { i16, i1 } %m, 0
+  %m2 = extractvalue { i16, i1 } %m, 1
+  %r = select i1 %m2, i16 %m1, i16 10
+  ret i16 %r
+}
+
+define i16 @smulo.selectboth.i16(i16 %a, i16 %b) {
+; SDAG-LABEL: smulo.selectboth.i16:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    sxth w8, w1
+; SDAG-NEXT:    sxth w9, w0
+; SDAG-NEXT:    mul w8, w9, w8
+; SDAG-NEXT:    mov w9, #10
+; SDAG-NEXT:    cmp w8, w8, sxth
+; SDAG-NEXT:    csel w0, w8, w9, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.selectboth.i16:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    sxth w8, w1
+; FAST-NEXT:    sxth w9, w0
+; FAST-NEXT:    mul w8, w9, w8
+; FAST-NEXT:    mov w9, #10
+; FAST-NEXT:    cmp w8, w8, sxth
+; FAST-NEXT:    csel w0, w8, w9, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.selectboth.i16:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    sxth w8, w0
+; GISEL-NEXT:    sxth w9, w1
+; GISEL-NEXT:    mul w8, w8, w9
+; GISEL-NEXT:    mov w9, #10
+; GISEL-NEXT:    cmp w8, w8, sxth
+; GISEL-NEXT:    csel w0, w8, w9, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i16, i1 } @llvm.smul.with.overflow.i16(i16 %a, i16 %b)
+  %m1 = extractvalue { i16, i1 } %m, 0
+  %m2 = extractvalue { i16, i1 } %m, 1
+  %r = select i1 %m2, i16 %m1, i16 10
+  ret i16 %r
+}
+
+define i32 @umulo.selectboth.i32(i32 %a, i32 %b) {
+; SDAG-LABEL: umulo.selectboth.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umull x9, w0, w1
+; SDAG-NEXT:    mov w8, #10
+; SDAG-NEXT:    tst x9, #0xffffffff00000000
+; SDAG-NEXT:    csel w0, w9, w8, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.selectboth.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umull x9, w0, w1
+; FAST-NEXT:    mov w8, #10
+; FAST-NEXT:    tst x9, #0xffffffff00000000
+; FAST-NEXT:    csel w0, w9, w8, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.selectboth.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umull x9, w0, w1
+; GISEL-NEXT:    mov w8, #10
+; GISEL-NEXT:    mul w10, w0, w1
+; GISEL-NEXT:    lsr x9, x9, #32
+; GISEL-NEXT:    cmp w9, #0
+; GISEL-NEXT:    csel w0, w10, w8, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %a, i32 %b)
+  %m1 = extractvalue { i32, i1 } %m, 0
+  %m2 = extractvalue { i32, i1 } %m, 1
+  %r = select i1 %m2, i32 %m1, i32 10
+  ret i32 %r
+}
+
+define i32 @smulo.selectboth.i32(i32 %a, i32 %b) {
+; SDAG-LABEL: smulo.selectboth.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    smull x9, w0, w1
+; SDAG-NEXT:    mov w8, #10
+; SDAG-NEXT:    cmp x9, w9, sxtw
+; SDAG-NEXT:    csel w0, w9, w8, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.selectboth.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    smull x9, w0, w1
+; FAST-NEXT:    mov w8, #10
+; FAST-NEXT:    cmp x9, w9, sxtw
+; FAST-NEXT:    csel w0, w9, w8, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.selectboth.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    smull x9, w0, w1
+; GISEL-NEXT:    mov w8, #10
+; GISEL-NEXT:    mul w10, w0, w1
+; GISEL-NEXT:    asr x9, x9, #32
+; GISEL-NEXT:    cmp w9, w10, asr #31
+; GISEL-NEXT:    csel w0, w10, w8, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %a, i32 %b)
+  %m1 = extractvalue { i32, i1 } %m, 0
+  %m2 = extractvalue { i32, i1 } %m, 1
+  %r = select i1 %m2, i32 %m1, i32 10
+  ret i32 %r
+}
+
+define i64 @umulo.selectboth.i64(i64 %a, i64 %b) {
+; SDAG-LABEL: umulo.selectboth.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umulh x9, x0, x1
+; SDAG-NEXT:    mov w8, #10
+; SDAG-NEXT:    mul x10, x0, x1
+; SDAG-NEXT:    cmp xzr, x9
+; SDAG-NEXT:    csel x0, x10, x8, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.selectboth.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umulh x9, x0, x1
+; FAST-NEXT:    mov x8, #10
+; FAST-NEXT:    mul x10, x0, x1
+; FAST-NEXT:    cmp xzr, x9
+; FAST-NEXT:    csel x0, x10, x8, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.selectboth.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umulh x9, x0, x1
+; GISEL-NEXT:    mov w8, #10
+; GISEL-NEXT:    mul x10, x0, x1
+; GISEL-NEXT:    cmp x9, #0
+; GISEL-NEXT:    csel x0, x10, x8, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
+  %m1 = extractvalue { i64, i1 } %m, 0
+  %m2 = extractvalue { i64, i1 } %m, 1
+  %r = select i1 %m2, i64 %m1, i64 10
+  ret i64 %r
+}
+
+define i64 @smulo.selectboth.i64(i64 %a, i64 %b) {
+; SDAG-LABEL: smulo.selectboth.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    mul x9, x0, x1
+; SDAG-NEXT:    mov w8, #10
+; SDAG-NEXT:    smulh x10, x0, x1
+; SDAG-NEXT:    cmp x10, x9, asr #63
+; SDAG-NEXT:    csel x0, x9, x8, ne
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.selectboth.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    mul x9, x0, x1
+; FAST-NEXT:    mov x8, #10
+; FAST-NEXT:    smulh x10, x0, x1
+; FAST-NEXT:    cmp x10, x9, asr #63
+; FAST-NEXT:    csel x0, x9, x8, ne
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.selectboth.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    mul x9, x0, x1
+; GISEL-NEXT:    mov w8, #10
+; GISEL-NEXT:    smulh x10, x0, x1
+; GISEL-NEXT:    cmp x10, x9, asr #63
+; GISEL-NEXT:    csel x0, x9, x8, ne
+; GISEL-NEXT:    ret
+entry:
+  %m = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %a, i64 %b)
+  %m1 = extractvalue { i64, i1 } %m, 0
+  %m2 = extractvalue { i64, i1 } %m, 1
+  %r = select i1 %m2, i64 %m1, i64 10
+  ret i64 %r
+}
+
+
 ;
 ; Check the use of the overflow bit in combination with a branch instruction.
 ;
 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: saddo.br.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn w0, w1
+; SDAG-NEXT:    cset w0, vc
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.br.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn w0, w1
+; FAST-NEXT:    mov w9, #1
+; FAST-NEXT:    cset w8, vs
+; FAST-NEXT:    bic w8, w9, w8
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.br.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn w0, w1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo.br.i32
-; CHECK:        cmn w0, w1
-; CHECK-NEXT:   b.vc
   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -575,10 +2176,29 @@ continue:
 }
 
 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: saddo.br.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn x0, x1
+; SDAG-NEXT:    cset w0, vc
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: saddo.br.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn x0, x1
+; FAST-NEXT:    mov w9, #1
+; FAST-NEXT:    cset w8, vs
+; FAST-NEXT:    bic w8, w9, w8
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: saddo.br.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn x0, x1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  saddo.br.i64
-; CHECK:        cmn x0, x1
-; CHECK-NEXT:   b.vc
   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -592,10 +2212,29 @@ continue:
 }
 
 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: uaddo.br.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn w0, w1
+; SDAG-NEXT:    cset w0, lo
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.br.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn w0, w1
+; FAST-NEXT:    mov w9, #1
+; FAST-NEXT:    cset w8, hs
+; FAST-NEXT:    bic w8, w9, w8
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.br.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn w0, w1
+; GISEL-NEXT:    cset w8, hs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  uaddo.br.i32
-; CHECK:        cmn w0, w1
-; CHECK-NEXT:   b.lo
   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -609,10 +2248,29 @@ continue:
 }
 
 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: uaddo.br.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn x0, x1
+; SDAG-NEXT:    cset w0, lo
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: uaddo.br.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn x0, x1
+; FAST-NEXT:    mov w9, #1
+; FAST-NEXT:    cset w8, hs
+; FAST-NEXT:    bic w8, w9, w8
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: uaddo.br.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn x0, x1
+; GISEL-NEXT:    cset w8, hs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  uaddo.br.i64
-; CHECK:        cmn x0, x1
-; CHECK-NEXT:   b.lo
   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -626,10 +2284,29 @@ continue:
 }
 
 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: ssubo.br.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp w0, w1
+; SDAG-NEXT:    cset w0, vc
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo.br.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp w0, w1
+; FAST-NEXT:    mov w9, #1
+; FAST-NEXT:    cset w8, vs
+; FAST-NEXT:    bic w8, w9, w8
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo.br.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp w0, w1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  ssubo.br.i32
-; CHECK:        cmp w0, w1
-; CHECK-NEXT:   b.vc
   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -643,10 +2320,29 @@ continue:
 }
 
 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: ssubo.br.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp x0, x1
+; SDAG-NEXT:    cset w0, vc
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: ssubo.br.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp x0, x1
+; FAST-NEXT:    mov w9, #1
+; FAST-NEXT:    cset w8, vs
+; FAST-NEXT:    bic w8, w9, w8
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: ssubo.br.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp x0, x1
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  ssubo.br.i64
-; CHECK:        cmp x0, x1
-; CHECK-NEXT:   b.vc
   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -660,10 +2356,29 @@ continue:
 }
 
 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: usubo.br.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp w0, w1
+; SDAG-NEXT:    cset w0, hs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.br.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp w0, w1
+; FAST-NEXT:    mov w9, #1
+; FAST-NEXT:    cset w8, lo
+; FAST-NEXT:    bic w8, w9, w8
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.br.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp w0, w1
+; GISEL-NEXT:    cset w8, lo
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  usubo.br.i32
-; CHECK:        cmp w0, w1
-; CHECK-NEXT:   b.hs
   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -677,10 +2392,29 @@ continue:
 }
 
 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: usubo.br.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmp x0, x1
+; SDAG-NEXT:    cset w0, hs
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: usubo.br.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmp x0, x1
+; FAST-NEXT:    mov w9, #1
+; FAST-NEXT:    cset w8, lo
+; FAST-NEXT:    bic w8, w9, w8
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: usubo.br.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmp x0, x1
+; GISEL-NEXT:    cset w8, lo
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  usubo.br.i64
-; CHECK:        cmp x0, x1
-; CHECK-NEXT:   b.hs
   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -694,11 +2428,32 @@ continue:
 }
 
 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: smulo.br.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    smull x8, w0, w1
+; SDAG-NEXT:    cmp x8, w8, sxtw
+; SDAG-NEXT:    cset w0, eq
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.br.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    smull x9, w0, w1
+; FAST-NEXT:    mov w8, #1
+; FAST-NEXT:    cmp x9, w9, sxtw
+; FAST-NEXT:    cset w9, ne
+; FAST-NEXT:    bic w8, w8, w9
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.br.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    smull x8, w0, w1
+; GISEL-NEXT:    mul w9, w0, w1
+; GISEL-NEXT:    asr x8, x8, #32
+; GISEL-NEXT:    cmp w8, w9, asr #31
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo.br.i32
-; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
-; CHECK-NEXT:   cmp     x[[MREG]], w[[MREG]], sxtw
-; CHECK-NEXT:   b.eq
   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -712,12 +2467,33 @@ continue:
 }
 
 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: smulo.br.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    mul x8, x0, x1
+; SDAG-NEXT:    smulh x9, x0, x1
+; SDAG-NEXT:    cmp x9, x8, asr #63
+; SDAG-NEXT:    cset w0, eq
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo.br.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    mul x9, x0, x1
+; FAST-NEXT:    mov w8, #1
+; FAST-NEXT:    smulh x10, x0, x1
+; FAST-NEXT:    cmp x10, x9, asr #63
+; FAST-NEXT:    cset w9, ne
+; FAST-NEXT:    bic w8, w8, w9
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo.br.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    mul x8, x0, x1
+; GISEL-NEXT:    smulh x9, x0, x1
+; GISEL-NEXT:    cmp x9, x8, asr #63
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo.br.i64
-; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
-; CHECK-NEXT:   b.eq
   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -731,10 +2507,29 @@ continue:
 }
 
 define zeroext i1 @smulo2.br.i64(i64 %v1) {
+; SDAG-LABEL: smulo2.br.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn x0, x0
+; SDAG-NEXT:    cset w0, vc
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: smulo2.br.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn x0, x0
+; FAST-NEXT:    mov w8, #1
+; FAST-NEXT:    cset w9, vs
+; FAST-NEXT:    bic w8, w8, w9
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: smulo2.br.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn x0, x0
+; GISEL-NEXT:    cset w8, vs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  smulo2.br.i64
-; CHECK:        cmn  x0, x0
-; CHECK-NEXT:   b.vc
   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -748,11 +2543,31 @@ continue:
 }
 
 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
+; SDAG-LABEL: umulo.br.i32:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umull x8, w0, w1
+; SDAG-NEXT:    tst x8, #0xffffffff00000000
+; SDAG-NEXT:    cset w0, eq
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.br.i32:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umull x9, w0, w1
+; FAST-NEXT:    mov w8, #1
+; FAST-NEXT:    tst x9, #0xffffffff00000000
+; FAST-NEXT:    cset w9, ne
+; FAST-NEXT:    bic w8, w8, w9
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.br.i32:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umull x8, w0, w1
+; GISEL-NEXT:    lsr x8, x8, #32
+; GISEL-NEXT:    cmp w8, #0
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo.br.i32
-; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
-; CHECK-NEXT:   tst     [[MREG]], #0xffffffff00000000
-; CHECK-NEXT:   b.eq
   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
   %val = extractvalue {i32, i1} %t, 0
   %obit = extractvalue {i32, i1} %t, 1
@@ -766,10 +2581,30 @@ continue:
 }
 
 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
+; SDAG-LABEL: umulo.br.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    umulh x8, x0, x1
+; SDAG-NEXT:    cmp xzr, x8
+; SDAG-NEXT:    cset w0, eq
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo.br.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    umulh x9, x0, x1
+; FAST-NEXT:    mov w8, #1
+; FAST-NEXT:    cmp xzr, x9
+; FAST-NEXT:    cset w9, ne
+; FAST-NEXT:    bic w8, w8, w9
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo.br.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    umulh x8, x0, x1
+; GISEL-NEXT:    cmp x8, #0
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo.br.i64
-; CHECK:        umulh   [[REG:x[0-9]+]], x0, x1
-; CHECK-NEXT:   {{cbz|cmp}}
   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -783,10 +2618,29 @@ continue:
 }
 
 define zeroext i1 @umulo2.br.i64(i64 %v1) {
+; SDAG-LABEL: umulo2.br.i64:
+; SDAG:       // %bb.0: // %entry
+; SDAG-NEXT:    cmn x0, x0
+; SDAG-NEXT:    cset w0, lo
+; SDAG-NEXT:    ret
+;
+; FAST-LABEL: umulo2.br.i64:
+; FAST:       // %bb.0: // %entry
+; FAST-NEXT:    cmn x0, x0
+; FAST-NEXT:    mov w8, #1
+; FAST-NEXT:    cset w9, hs
+; FAST-NEXT:    bic w8, w8, w9
+; FAST-NEXT:    and w0, w8, #0x1
+; FAST-NEXT:    ret
+;
+; GISEL-LABEL: umulo2.br.i64:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    cmn x0, x0
+; GISEL-NEXT:    cset w8, hs
+; GISEL-NEXT:    tst w8, #0x1
+; GISEL-NEXT:    cset w0, eq
+; GISEL-NEXT:    ret
 entry:
-; CHECK-LABEL:  umulo2.br.i64
-; CHECK:        cmn  x0, x0
-; CHECK-NEXT:   b.lo
   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
   %val = extractvalue {i64, i1} %t, 0
   %obit = extractvalue {i64, i1} %t, 1
@@ -799,16 +2653,28 @@ continue:
   ret i1 true
 }
 
+declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8) nounwind readnone
+declare {i16, i1} @llvm.sadd.with.overflow.i16(i16, i16) nounwind readnone
 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
+declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone
+declare {i16, i1} @llvm.uadd.with.overflow.i16(i16, i16) nounwind readnone
 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
+declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8) nounwind readnone
+declare {i16, i1} @llvm.ssub.with.overflow.i16(i16, i16) nounwind readnone
 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
+declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8) nounwind readnone
+declare {i16, i1} @llvm.usub.with.overflow.i16(i16, i16) nounwind readnone
 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
+declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone
+declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
+declare {i8, i1} @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone
+declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
 


        


More information about the llvm-commits mailing list