[llvm] [CodeGenPrepare] Prepare the usubo check with the opposite overflow condition (PR #147194)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 6 08:40:44 PDT 2025


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/147194

>From 4089c5d68daf8c3b7d6ccfe3f8975a19e43ce710 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sat, 5 Jul 2025 20:15:53 -0400
Subject: [PATCH 1/2] Pre-commit tests (NFC)

---
 llvm/test/CodeGen/X86/sub-with-overflow.ll    |  76 +++
 .../CodeGenPrepare/X86/overflow-intrinsics.ll | 517 +++++++++++++++++-
 2 files changed, 568 insertions(+), 25 deletions(-)

diff --git a/llvm/test/CodeGen/X86/sub-with-overflow.ll b/llvm/test/CodeGen/X86/sub-with-overflow.ll
index d3bd3b1cdf0ac..ca28cfe2d3d14 100644
--- a/llvm/test/CodeGen/X86/sub-with-overflow.ll
+++ b/llvm/test/CodeGen/X86/sub-with-overflow.ll
@@ -93,3 +93,79 @@ entry:
   ret i1 %obit
 
 }
+
+define i1 @usubo_uge_i64_overflow_used(i64 %x, i64 %y, ptr %p) {
+; CHECK-LABEL: usubo_uge_i64_overflow_used:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    cmpl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    setae %al
+; CHECK-NEXT:    retl
+  %s = sub i64 %x, %y
+  %ov = icmp uge i64 %x, %y
+  ret i1 %ov
+}
+
+define i1 @usubo_uge_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {
+; CHECK-LABEL: usubo_uge_i64_math_overflow_used:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; CHECK-NEXT:    subl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    movl %ecx, (%eax)
+; CHECK-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
+; CHECK-NEXT:    movl %edx, 4(%eax)
+; CHECK-NEXT:    setae %al
+; CHECK-NEXT:    retl
+  %s = sub i64 %x, %y
+  store i64 %s, ptr %p
+  %ov = icmp uge i64 %x, %y
+  ret i1 %ov
+}
+
+define i1 @usubo_ule_i32_overflow_used(i32 %x, i32 %y, ptr %p) {
+; CHECK-LABEL: usubo_ule_i32_overflow_used:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    cmpl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    setae %al
+; CHECK-NEXT:    retl
+  %s = sub i32 %y, %x
+  %ov = icmp ule i32 %x, %y
+  ret i1 %ov
+}
+
+define i1 @usubo_ne_zero_i16_overflow_used(i16 %x, ptr %p) {
+; CHECK-LABEL: usubo_ne_zero_i16_overflow_used:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    movl %eax, %edx
+; CHECK-NEXT:    decl %edx
+; CHECK-NEXT:    movw %dx, (%ecx)
+; CHECK-NEXT:    testw %ax, %ax
+; CHECK-NEXT:    setne %al
+; CHECK-NEXT:    retl
+  %s = sub i16 %x, 1
+  store i16 %s, ptr %p
+  %ov = icmp ne i16 %x, 0
+  ret i1 %ov
+}
+
+define i1 @usubo_eq_zero_i8_overflow_used(i8 %x, ptr %p) {
+; CHECK-LABEL: usubo_eq_zero_i8_overflow_used:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    negb %cl
+; CHECK-NEXT:    movb %cl, (%eax)
+; CHECK-NEXT:    setae %al
+; CHECK-NEXT:    retl
+  %s = sub i8 0, %x
+  store i8 %s, ptr %p
+  %ov = icmp eq i8 %x, 0
+  ret i1 %ov
+}
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll b/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
index 653f346356488..768587f16c335 100644
--- a/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
@@ -12,6 +12,16 @@ define i64 @uaddo1_overflow_used(i64 %a, i64 %b) nounwind ssp {
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
 ; CHECK-NEXT:    ret i64 [[Q]]
+;
+; DEBUG-LABEL: @uaddo1_overflow_used(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG14:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG14]]
+; DEBUG-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG14]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META9:![0-9]+]], !DIExpression(), [[DBG14]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META11:![0-9]+]], !DIExpression(), [[META15:![0-9]+]])
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG16:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META13:![0-9]+]], !DIExpression(), [[DBG16]])
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG17:![0-9]+]]
 ;
   %add = add i64 %b, %a
   %cmp = icmp ult i64 %add, %a
@@ -25,8 +35,19 @@ define i64 @uaddo1_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]], align 8
 ; CHECK-NEXT:    ret i64 [[Q]]
+;
+; DEBUG-LABEL: @uaddo1_math_overflow_used(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG23:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG23]]
+; DEBUG-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG23]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META20:![0-9]+]], !DIExpression(), [[DBG23]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META21:![0-9]+]], !DIExpression(), [[META24:![0-9]+]])
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG25:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META22:![0-9]+]], !DIExpression(), [[DBG25]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]], align 8, !dbg [[DBG26:![0-9]+]]
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG27:![0-9]+]]
 ;
   %add = add i64 %b, %a
   %cmp = icmp ult i64 %add, %a
@@ -42,6 +63,16 @@ define i64 @uaddo2_overflow_used(i64 %a, i64 %b) nounwind ssp {
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
 ; CHECK-NEXT:    ret i64 [[Q]]
+;
+; DEBUG-LABEL: @uaddo2_overflow_used(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG33:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG33]]
+; DEBUG-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG33]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META30:![0-9]+]], !DIExpression(), [[DBG33]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META31:![0-9]+]], !DIExpression(), [[META34:![0-9]+]])
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG35:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META32:![0-9]+]], !DIExpression(), [[DBG35]])
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG36:![0-9]+]]
 ;
   %add = add i64 %b, %a
   %cmp = icmp ult i64 %add, %b
@@ -55,8 +86,19 @@ define i64 @uaddo2_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]], align 8
 ; CHECK-NEXT:    ret i64 [[Q]]
+;
+; DEBUG-LABEL: @uaddo2_math_overflow_used(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG42:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG42]]
+; DEBUG-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG42]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META39:![0-9]+]], !DIExpression(), [[DBG42]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META40:![0-9]+]], !DIExpression(), [[META43:![0-9]+]])
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG44:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META41:![0-9]+]], !DIExpression(), [[DBG44]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]], align 8, !dbg [[DBG45:![0-9]+]]
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG46:![0-9]+]]
 ;
   %add = add i64 %b, %a
   %cmp = icmp ult i64 %add, %b
@@ -72,6 +114,16 @@ define i64 @uaddo3_overflow_used(i64 %a, i64 %b) nounwind ssp {
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
 ; CHECK-NEXT:    ret i64 [[Q]]
+;
+; DEBUG-LABEL: @uaddo3_overflow_used(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG52:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG52]]
+; DEBUG-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG52]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META49:![0-9]+]], !DIExpression(), [[DBG52]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META50:![0-9]+]], !DIExpression(), [[META53:![0-9]+]])
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG54:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META51:![0-9]+]], !DIExpression(), [[DBG54]])
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG55:![0-9]+]]
 ;
   %add = add i64 %b, %a
   %cmp = icmp ugt i64 %b, %add
@@ -85,8 +137,19 @@ define i64 @uaddo3_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]], align 8
 ; CHECK-NEXT:    ret i64 [[Q]]
+;
+; DEBUG-LABEL: @uaddo3_math_overflow_used(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG61:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG61]]
+; DEBUG-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG61]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META58:![0-9]+]], !DIExpression(), [[DBG61]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META59:![0-9]+]], !DIExpression(), [[META62:![0-9]+]])
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG63:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META60:![0-9]+]], !DIExpression(), [[DBG63]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]], align 8, !dbg [[DBG64:![0-9]+]]
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG65:![0-9]+]]
 ;
   %add = add i64 %b, %a
   %cmp = icmp ugt i64 %b, %add
@@ -109,6 +172,20 @@ define i64 @uaddo4(i64 %a, i64 %b, i1 %c) nounwind ssp {
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret i64 0
 ;
+; DEBUG-LABEL: @uaddo4(
+; DEBUG-NEXT:  entry:
+; DEBUG-NEXT:    [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG71:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[ADD]], [[META68:![0-9]+]], !DIExpression(), [[DBG71]])
+; DEBUG-NEXT:      #dbg_value(i1 poison, [[META69:![0-9]+]], !DIExpression(), [[META72:![0-9]+]])
+; DEBUG-NEXT:    br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]], !dbg [[DBG73:![0-9]+]]
+; DEBUG:       next:
+; DEBUG-NEXT:    [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]], !dbg [[META72]]
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[TMP0]], i64 [[B]], i64 42, !dbg [[DBG74:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META70:![0-9]+]], !DIExpression(), [[DBG74]])
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG75:![0-9]+]]
+; DEBUG:       exit:
+; DEBUG-NEXT:    ret i64 0, !dbg [[DBG76:![0-9]+]]
+;
 entry:
   %add = add i64 %b, %a
   %cmp = icmp ugt i64 %b, %add
@@ -126,7 +203,7 @@ define i64 @uaddo5(i64 %a, i64 %b, ptr %ptr, i1 %c) nounwind ssp {
 ; CHECK-LABEL: @uaddo5(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]]
-; CHECK-NEXT:    store i64 [[ADD]], ptr [[PTR:%.*]]
+; CHECK-NEXT:    store i64 [[ADD]], ptr [[PTR:%.*]], align 8
 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]]
 ; CHECK:       next:
 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]]
@@ -135,6 +212,21 @@ define i64 @uaddo5(i64 %a, i64 %b, ptr %ptr, i1 %c) nounwind ssp {
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret i64 0
 ;
+; DEBUG-LABEL: @uaddo5(
+; DEBUG-NEXT:  entry:
+; DEBUG-NEXT:    [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG82:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[ADD]], [[META79:![0-9]+]], !DIExpression(), [[DBG82]])
+; DEBUG-NEXT:    store i64 [[ADD]], ptr [[PTR:%.*]], align 8, !dbg [[DBG83:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 poison, [[META80:![0-9]+]], !DIExpression(), [[META84:![0-9]+]])
+; DEBUG-NEXT:    br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]], !dbg [[DBG85:![0-9]+]]
+; DEBUG:       next:
+; DEBUG-NEXT:    [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]], !dbg [[META84]]
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[TMP0]], i64 [[B]], i64 42, !dbg [[DBG86:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META81:![0-9]+]], !DIExpression(), [[DBG86]])
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG87:![0-9]+]]
+; DEBUG:       exit:
+; DEBUG-NEXT:    ret i64 0, !dbg [[DBG88:![0-9]+]]
+;
 entry:
   %add = add i64 %b, %a
   store i64 %add, ptr %ptr
@@ -157,6 +249,15 @@ define i64 @uaddo6_xor(i64 %a, i64 %b) {
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
 ; CHECK-NEXT:    ret i64 [[Q]]
+;
+; DEBUG-LABEL: @uaddo6_xor(
+; DEBUG-NEXT:      #dbg_value(i64 poison, [[META91:![0-9]+]], !DIExpression(), [[META94:![0-9]+]])
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]), !dbg [[DBG95:![0-9]+]]
+; DEBUG-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG95]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META92:![0-9]+]], !DIExpression(), [[DBG95]])
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG96:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META93:![0-9]+]], !DIExpression(), [[DBG96]])
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG97:![0-9]+]]
 ;
   %x = xor i64 %a, -1
   %cmp = icmp ult i64 %x, %b
@@ -170,6 +271,15 @@ define i64 @uaddo6_xor_commuted(i64 %a, i64 %b) {
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
 ; CHECK-NEXT:    ret i64 [[Q]]
+;
+; DEBUG-LABEL: @uaddo6_xor_commuted(
+; DEBUG-NEXT:      #dbg_value(i64 poison, [[META100:![0-9]+]], !DIExpression(), [[META103:![0-9]+]])
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]), !dbg [[DBG104:![0-9]+]]
+; DEBUG-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG104]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META101:![0-9]+]], !DIExpression(), [[DBG104]])
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG105:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META102:![0-9]+]], !DIExpression(), [[DBG105]])
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG106:![0-9]+]]
 ;
   %x = xor i64 %a, -1
   %cmp = icmp ult i64 %x, %b
@@ -186,6 +296,16 @@ define i64 @uaddo6_xor_multi_use(i64 %a, i64 %b) {
 ; CHECK-NEXT:    [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42
 ; CHECK-NEXT:    call void @use(i64 [[X]])
 ; CHECK-NEXT:    ret i64 [[Q]]
+;
+; DEBUG-LABEL: @uaddo6_xor_multi_use(
+; DEBUG-NEXT:    [[X:%.*]] = xor i64 -1, [[A:%.*]], !dbg [[DBG112:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[X]], [[META109:![0-9]+]], !DIExpression(), [[DBG112]])
+; DEBUG-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X]], [[B:%.*]], !dbg [[DBG113:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[CMP]], [[META110:![0-9]+]], !DIExpression(), [[DBG113]])
+; DEBUG-NEXT:    [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG114:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[Q]], [[META111:![0-9]+]], !DIExpression(), [[DBG114]])
+; DEBUG-NEXT:    call void @use(i64 [[X]]), !dbg [[DBG115:![0-9]+]]
+; DEBUG-NEXT:    ret i64 [[Q]], !dbg [[DBG116:![0-9]+]]
 ;
   %x = xor i64 -1, %a
   %cmp = icmp ult i64 %x, %b
@@ -203,6 +323,17 @@ define i1 @uaddo6_xor_op_after_XOR(i32 %a, ptr %b.ptr) {
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    [[OV:%.*]] = xor i1 [[OV1]], true
 ; CHECK-NEXT:    ret i1 [[OV]]
+;
+; DEBUG-LABEL: @uaddo6_xor_op_after_XOR(
+; DEBUG-NEXT:      #dbg_value(i32 poison, [[META119:![0-9]+]], !DIExpression(), [[META124:![0-9]+]])
+; DEBUG-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 8, !dbg [[DBG125:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i32 [[B]], [[META121:![0-9]+]], !DIExpression(), [[DBG125]])
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B]]), !dbg [[DBG126:![0-9]+]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG126]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META122:![0-9]+]], !DIExpression(), [[DBG126]])
+; DEBUG-NEXT:    [[OV:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG127:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META123:![0-9]+]], !DIExpression(), [[DBG127]])
+; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG128:![0-9]+]]
 ;
   %x = xor i32 %a, -1
   %b = load i32, ptr %b.ptr, align 8
@@ -219,8 +350,17 @@ define i1 @uaddo_i64_increment(i64 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1)
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @uaddo_i64_increment(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1), !dbg [[DBG133:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG133]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG133]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META131:![0-9]+]], !DIExpression(), [[DBG133]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META132:![0-9]+]], !DIExpression(), [[META134:![0-9]+]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG135:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG136:![0-9]+]]
 ;
   %a = add i64 %x, 1
   %ov = icmp eq i64 %a, 0
@@ -233,8 +373,17 @@ define i1 @uaddo_i8_increment_noncanonical_1(i8 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 1, i8 [[X:%.*]])
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i8 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i8 [[MATH]], ptr [[P:%.*]], align 1
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @uaddo_i8_increment_noncanonical_1(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 1, i8 [[X:%.*]]), !dbg [[DBG141:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0, !dbg [[DBG141]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !dbg [[DBG141]]
+; DEBUG-NEXT:      #dbg_value(i8 [[MATH]], [[META139:![0-9]+]], !DIExpression(), [[DBG141]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META140:![0-9]+]], !DIExpression(), [[META142:![0-9]+]])
+; DEBUG-NEXT:    store i8 [[MATH]], ptr [[P:%.*]], align 1, !dbg [[DBG143:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG144:![0-9]+]]
 ;
   %a = add i8 1, %x        ; commute
   %ov = icmp eq i8 %a, 0
@@ -247,8 +396,17 @@ define i1 @uaddo_i32_increment_noncanonical_2(i32 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X:%.*]], i32 1)
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]], align 4
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @uaddo_i32_increment_noncanonical_2(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X:%.*]], i32 1), !dbg [[DBG149:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG149]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG149]]
+; DEBUG-NEXT:      #dbg_value(i32 [[MATH]], [[META147:![0-9]+]], !DIExpression(), [[DBG149]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META148:![0-9]+]], !DIExpression(), [[META150:![0-9]+]])
+; DEBUG-NEXT:    store i32 [[MATH]], ptr [[P:%.*]], align 4, !dbg [[DBG151:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG152:![0-9]+]]
 ;
   %a = add i32 %x, 1
   %ov = icmp eq i32 0, %a   ; commute
@@ -261,8 +419,17 @@ define i1 @uaddo_i16_increment_noncanonical_3(i16 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 1, i16 [[X:%.*]])
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i16 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i16 [[MATH]], ptr [[P:%.*]], align 2
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @uaddo_i16_increment_noncanonical_3(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 1, i16 [[X:%.*]]), !dbg [[DBG158:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0, !dbg [[DBG158]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !dbg [[DBG158]]
+; DEBUG-NEXT:      #dbg_value(i16 [[MATH]], [[META155:![0-9]+]], !DIExpression(), [[DBG158]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META157:![0-9]+]], !DIExpression(), [[META159:![0-9]+]])
+; DEBUG-NEXT:    store i16 [[MATH]], ptr [[P:%.*]], align 2, !dbg [[DBG160:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG161:![0-9]+]]
 ;
   %a = add i16 1, %x        ; commute
   %ov = icmp eq i16 0, %a   ; commute
@@ -277,8 +444,17 @@ define i1 @uaddo_i64_increment_alt(i64 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1)
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @uaddo_i64_increment_alt(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1), !dbg [[DBG166:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG166]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG166]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META164:![0-9]+]], !DIExpression(), [[DBG166]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG167:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META165:![0-9]+]], !DIExpression(), [[META168:![0-9]+]])
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG169:![0-9]+]]
 ;
   %a = add i64 %x, 1
   store i64 %a, ptr %p
@@ -293,8 +469,17 @@ define i1 @uaddo_i64_increment_alt_dom(i64 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1)
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @uaddo_i64_increment_alt_dom(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1), !dbg [[DBG174:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG174]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG174]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META172:![0-9]+]], !DIExpression(), [[DBG174]])
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META173:![0-9]+]], !DIExpression(), [[META175:![0-9]+]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG176:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG177:![0-9]+]]
 ;
   %ov = icmp eq i64 %x, -1
   %a = add i64 %x, 1
@@ -309,8 +494,17 @@ define i1 @uaddo_i64_decrement_alt(i64 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1)
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @uaddo_i64_decrement_alt(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1), !dbg [[DBG182:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG182]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG182]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META180:![0-9]+]], !DIExpression(), [[DBG182]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG183:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META181:![0-9]+]], !DIExpression(), [[META184:![0-9]+]])
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG185:![0-9]+]]
 ;
   %a = add i64 %x, -1
   store i64 %a, ptr %p
@@ -325,8 +519,17 @@ define i1 @uaddo_i64_decrement_alt_dom(i64 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1)
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @uaddo_i64_decrement_alt_dom(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1), !dbg [[DBG190:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG190]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG190]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META188:![0-9]+]], !DIExpression(), [[DBG190]])
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META189:![0-9]+]], !DIExpression(), [[META191:![0-9]+]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG192:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG193:![0-9]+]]
 ;
   %ov = icmp ne i64 %x, 0
   %a = add i64 %x, -1
@@ -340,8 +543,16 @@ define i1 @uaddo_i42_increment_illegal_type(i42 %x, ptr %p) {
 ; CHECK-LABEL: @uaddo_i42_increment_illegal_type(
 ; CHECK-NEXT:    [[A:%.*]] = add i42 [[X:%.*]], 1
 ; CHECK-NEXT:    [[OV:%.*]] = icmp eq i42 [[A]], 0
-; CHECK-NEXT:    store i42 [[A]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i42 [[A]], ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    ret i1 [[OV]]
+;
+; DEBUG-LABEL: @uaddo_i42_increment_illegal_type(
+; DEBUG-NEXT:    [[A:%.*]] = add i42 [[X:%.*]], 1, !dbg [[DBG198:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i42 [[A]], [[META196:![0-9]+]], !DIExpression(), [[DBG198]])
+; DEBUG-NEXT:    [[OV:%.*]] = icmp eq i42 [[A]], 0, !dbg [[DBG199:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META197:![0-9]+]], !DIExpression(), [[DBG199]])
+; DEBUG-NEXT:    store i42 [[A]], ptr [[P:%.*]], align 8, !dbg [[DBG200:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG201:![0-9]+]]
 ;
   %a = add i42 %x, 1
   %ov = icmp eq i42 %a, 0
@@ -355,6 +566,14 @@ define i1 @usubo_ult_i64_overflow_used(i64 %x, i64 %y, ptr %p) {
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @usubo_ult_i64_overflow_used(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]), !dbg [[DBG206:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG206]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG206]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META204:![0-9]+]], !DIExpression(), [[DBG206]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META205:![0-9]+]], !DIExpression(), [[META207:![0-9]+]])
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG208:![0-9]+]]
 ;
   %s = sub i64 %x, %y
   %ov = icmp ult i64 %x, %y
@@ -366,8 +585,17 @@ define i1 @usubo_ult_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]])
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @usubo_ult_i64_math_overflow_used(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]), !dbg [[DBG213:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG213]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG213]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META211:![0-9]+]], !DIExpression(), [[DBG213]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG214:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META212:![0-9]+]], !DIExpression(), [[META215:![0-9]+]])
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG216:![0-9]+]]
 ;
   %s = sub i64 %x, %y
   store i64 %s, ptr %p
@@ -382,8 +610,17 @@ define i1 @usubo_ugt_i32(i32 %x, i32 %y, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]], align 4
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @usubo_ugt_i32(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]]), !dbg [[DBG221:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG221]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG221]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META219:![0-9]+]], !DIExpression(), [[DBG221]])
+; DEBUG-NEXT:      #dbg_value(i32 [[MATH]], [[META220:![0-9]+]], !DIExpression(), [[META222:![0-9]+]])
+; DEBUG-NEXT:    store i32 [[MATH]], ptr [[P:%.*]], align 4, !dbg [[DBG223:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG224:![0-9]+]]
 ;
   %ov = icmp ugt i32 %y, %x
   %s = sub i32 %x, %y
@@ -398,8 +635,17 @@ define i1 @usubo_ugt_constant_op0_i8(i8 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 42, i8 [[X:%.*]])
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i8 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i8 [[MATH]], ptr [[P:%.*]], align 1
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @usubo_ugt_constant_op0_i8(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 42, i8 [[X:%.*]]), !dbg [[DBG229:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0, !dbg [[DBG229]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !dbg [[DBG229]]
+; DEBUG-NEXT:      #dbg_value(i8 [[MATH]], [[META227:![0-9]+]], !DIExpression(), [[DBG229]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META228:![0-9]+]], !DIExpression(), [[META230:![0-9]+]])
+; DEBUG-NEXT:    store i8 [[MATH]], ptr [[P:%.*]], align 1, !dbg [[DBG231:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG232:![0-9]+]]
 ;
   %s = sub i8 42, %x
   %ov = icmp ugt i8 %x, 42
@@ -414,8 +660,17 @@ define i1 @usubo_ult_constant_op0_i16(i16 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 43, i16 [[X:%.*]])
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i16 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i16 [[MATH]], ptr [[P:%.*]], align 2
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @usubo_ult_constant_op0_i16(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 43, i16 [[X:%.*]]), !dbg [[DBG237:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0, !dbg [[DBG237]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !dbg [[DBG237]]
+; DEBUG-NEXT:      #dbg_value(i16 [[MATH]], [[META235:![0-9]+]], !DIExpression(), [[DBG237]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META236:![0-9]+]], !DIExpression(), [[META238:![0-9]+]])
+; DEBUG-NEXT:    store i16 [[MATH]], ptr [[P:%.*]], align 2, !dbg [[DBG239:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG240:![0-9]+]]
 ;
   %s = sub i16 43, %x
   %ov = icmp ult i16 43, %x
@@ -430,8 +685,17 @@ define i1 @usubo_ult_constant_op1_i16(i16 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 44)
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i16 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i16 [[MATH]], ptr [[P:%.*]], align 2
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @usubo_ult_constant_op1_i16(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 44), !dbg [[DBG245:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0, !dbg [[DBG245]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !dbg [[DBG245]]
+; DEBUG-NEXT:      #dbg_value(i16 [[MATH]], [[META243:![0-9]+]], !DIExpression(), [[DBG245]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META244:![0-9]+]], !DIExpression(), [[META246:![0-9]+]])
+; DEBUG-NEXT:    store i16 [[MATH]], ptr [[P:%.*]], align 2, !dbg [[DBG247:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG248:![0-9]+]]
 ;
   %s = add i16 %x, -44
   %ov = icmp ult i16 %x, 44
@@ -444,8 +708,17 @@ define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 45)
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i8 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i8 [[MATH]], ptr [[P:%.*]], align 1
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @usubo_ugt_constant_op1_i8(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 45), !dbg [[DBG253:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0, !dbg [[DBG253]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !dbg [[DBG253]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META251:![0-9]+]], !DIExpression(), [[DBG253]])
+; DEBUG-NEXT:      #dbg_value(i8 [[MATH]], [[META252:![0-9]+]], !DIExpression(), [[META254:![0-9]+]])
+; DEBUG-NEXT:    store i8 [[MATH]], ptr [[P:%.*]], align 1, !dbg [[DBG255:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG256:![0-9]+]]
 ;
   %ov = icmp ugt i8 45, %x
   %s = add i8 %x, -45
@@ -460,8 +733,17 @@ define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 1)
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]], align 4
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @usubo_eq_constant1_op1_i32(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 1), !dbg [[DBG261:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG261]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG261]]
+; DEBUG-NEXT:      #dbg_value(i32 [[MATH]], [[META259:![0-9]+]], !DIExpression(), [[DBG261]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META260:![0-9]+]], !DIExpression(), [[META262:![0-9]+]])
+; DEBUG-NEXT:    store i32 [[MATH]], ptr [[P:%.*]], align 4, !dbg [[DBG263:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG264:![0-9]+]]
 ;
   %s = add i32 %x, -1
   %ov = icmp eq i32 %x, 0
@@ -476,8 +758,17 @@ define i1 @usubo_ne_constant0_op1_i32(i32 %x, ptr %p) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 [[X:%.*]])
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
-; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]], align 4
 ; CHECK-NEXT:    ret i1 [[OV1]]
+;
+; DEBUG-LABEL: @usubo_ne_constant0_op1_i32(
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 [[X:%.*]]), !dbg [[DBG269:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG269]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG269]]
+; DEBUG-NEXT:      #dbg_value(i32 [[MATH]], [[META267:![0-9]+]], !DIExpression(), [[DBG269]])
+; DEBUG-NEXT:      #dbg_value(i1 [[OV1]], [[META268:![0-9]+]], !DIExpression(), [[META270:![0-9]+]])
+; DEBUG-NEXT:    store i32 [[MATH]], ptr [[P:%.*]], align 4, !dbg [[DBG271:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG272:![0-9]+]]
 ;
   %s = sub i32 0, %x
   %ov = icmp ne i32 %x, 0
@@ -495,7 +786,7 @@ define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) {
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]
 ; CHECK:       t:
 ; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    store i64 [[S]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i64 [[S]], ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    br i1 [[COND]], label [[END:%.*]], label [[F]]
 ; CHECK:       f:
 ; CHECK-NEXT:    ret i1 [[COND]]
@@ -503,6 +794,21 @@ define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) {
 ; CHECK-NEXT:    [[OV:%.*]] = icmp ult i64 [[X]], [[Y]]
 ; CHECK-NEXT:    ret i1 [[OV]]
 ;
+; DEBUG-LABEL: @usubo_ult_sub_dominates_i64(
+; DEBUG-NEXT:  entry:
+; DEBUG-NEXT:    br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]], !dbg [[DBG277:![0-9]+]]
+; DEBUG:       t:
+; DEBUG-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]], !dbg [[DBG278:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[S]], [[META275:![0-9]+]], !DIExpression(), [[DBG278]])
+; DEBUG-NEXT:    store i64 [[S]], ptr [[P:%.*]], align 8, !dbg [[DBG279:![0-9]+]]
+; DEBUG-NEXT:    br i1 [[COND]], label [[END:%.*]], label [[F]], !dbg [[DBG280:![0-9]+]]
+; DEBUG:       f:
+; DEBUG-NEXT:    ret i1 [[COND]], !dbg [[DBG281:![0-9]+]]
+; DEBUG:       end:
+; DEBUG-NEXT:    [[OV:%.*]] = icmp ult i64 [[X]], [[Y]], !dbg [[DBG282:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META276:![0-9]+]], !DIExpression(), [[DBG282]])
+; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG283:![0-9]+]]
+;
 entry:
   br i1 %cond, label %t, label %f
 
@@ -533,9 +839,27 @@ define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) {
 ; CHECK-NEXT:    [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X]], i64 [[Y]])
 ; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
 ; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
-; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]
+; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    ret i1 [[OV1]]
 ;
+; DEBUG-LABEL: @usubo_ult_cmp_dominates_i64(
+; DEBUG-NEXT:  entry:
+; DEBUG-NEXT:    br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]], !dbg [[DBG288:![0-9]+]]
+; DEBUG:       t:
+; DEBUG-NEXT:    [[OV:%.*]] = icmp ult i64 [[X:%.*]], [[Y:%.*]], !dbg [[DBG289:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META286:![0-9]+]], !DIExpression(), [[DBG289]])
+; DEBUG-NEXT:    call void @call(i1 [[OV]]), !dbg [[DBG290:![0-9]+]]
+; DEBUG-NEXT:    br i1 [[OV]], label [[END:%.*]], label [[F]], !dbg [[DBG291:![0-9]+]]
+; DEBUG:       f:
+; DEBUG-NEXT:    ret i1 [[COND]], !dbg [[DBG292:![0-9]+]]
+; DEBUG:       end:
+; DEBUG-NEXT:    [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X]], i64 [[Y]]), !dbg [[DBG289]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0, !dbg [[DBG289]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1, !dbg [[DBG289]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META287:![0-9]+]], !DIExpression(), [[META293:![0-9]+]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG294:![0-9]+]]
+; DEBUG-NEXT:    ret i1 [[OV1]], !dbg [[DBG295:![0-9]+]]
+;
 entry:
   br i1 %cond, label %t, label %f
 
@@ -560,6 +884,13 @@ define void @bar() {
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 1, -1
 ; CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[CMP]] to i8
 ; CHECK-NEXT:    unreachable
+;
+; DEBUG-LABEL: @bar(
+; DEBUG-NEXT:    [[CMP:%.*]] = icmp eq i64 1, -1, !dbg [[DBG300:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[CMP]], [[META298:![0-9]+]], !DIExpression(), [[DBG300]])
+; DEBUG-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[CMP]] to i8, !dbg [[DBG301:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i8 [[FROMBOOL]], [[META299:![0-9]+]], !DIExpression(), [[DBG301]])
+; DEBUG-NEXT:    unreachable, !dbg [[DBG302:![0-9]+]]
 ;
   %cmp = icmp eq i64 1, -1
   %frombool = zext i1 %cmp to i8
@@ -571,6 +902,13 @@ define void @foo() {
 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i64 1, 1
 ; CHECK-NEXT:    [[CONV:%.*]] = trunc i64 [[SUB]] to i32
 ; CHECK-NEXT:    unreachable
+;
+; DEBUG-LABEL: @foo(
+; DEBUG-NEXT:    [[SUB:%.*]] = add nsw i64 1, 1, !dbg [[DBG307:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[SUB]], [[META305:![0-9]+]], !DIExpression(), [[DBG307]])
+; DEBUG-NEXT:    [[CONV:%.*]] = trunc i64 [[SUB]] to i32, !dbg [[DBG308:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i32 [[CONV]], [[META306:![0-9]+]], !DIExpression(), [[DBG308]])
+; DEBUG-NEXT:    unreachable, !dbg [[DBG309:![0-9]+]]
 ;
   %sub = add nsw i64 1, 1
   %conv = trunc i64 %sub to i32
@@ -583,6 +921,11 @@ define i1 @bar2() {
 ; CHECK-LABEL: @bar2(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 1, 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
+;
+; DEBUG-LABEL: @bar2(
+; DEBUG-NEXT:    [[CMP:%.*]] = icmp eq i64 1, 0, !dbg [[DBG313:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[CMP]], [[META312:![0-9]+]], !DIExpression(), [[DBG313]])
+; DEBUG-NEXT:    ret i1 [[CMP]], !dbg [[DBG314:![0-9]+]]
 ;
   %cmp = icmp eq i64 1, 0
   ret i1 %cmp
@@ -592,6 +935,11 @@ define i64 @foo2(ptr %p) {
 ; CHECK-LABEL: @foo2(
 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i64 1, -1
 ; CHECK-NEXT:    ret i64 [[SUB]]
+;
+; DEBUG-LABEL: @foo2(
+; DEBUG-NEXT:    [[SUB:%.*]] = add nsw i64 1, -1, !dbg [[DBG318:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[SUB]], [[META317:![0-9]+]], !DIExpression(), [[DBG318]])
+; DEBUG-NEXT:    ret i64 [[SUB]], !dbg [[DBG319:![0-9]+]]
 ;
   %sub = add nsw i64 1, -1
   ret i64 %sub
@@ -608,15 +956,35 @@ define void @PR41129(ptr %p64) {
 ; CHECK-NEXT:    br i1 [[COND17]], label [[TRUE:%.*]], label [[FALSE:%.*]]
 ; CHECK:       false:
 ; CHECK-NEXT:    [[ANDVAL:%.*]] = and i64 [[KEY]], 7
-; CHECK-NEXT:    store i64 [[ANDVAL]], ptr [[P64]]
+; CHECK-NEXT:    store i64 [[ANDVAL]], ptr [[P64]], align 8
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       true:
 ; CHECK-NEXT:    [[SVALUE:%.*]] = add i64 [[KEY]], -1
-; CHECK-NEXT:    store i64 [[SVALUE]], ptr [[P64]]
+; CHECK-NEXT:    store i64 [[SVALUE]], ptr [[P64]], align 8
 ; CHECK-NEXT:    br label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ;
+; DEBUG-LABEL: @PR41129(
+; DEBUG-NEXT:  entry:
+; DEBUG-NEXT:    [[KEY:%.*]] = load i64, ptr [[P64:%.*]], align 8, !dbg [[DBG326:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[KEY]], [[META322:![0-9]+]], !DIExpression(), [[DBG326]])
+; DEBUG-NEXT:    [[COND17:%.*]] = icmp eq i64 [[KEY]], 0, !dbg [[DBG327:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[COND17]], [[META323:![0-9]+]], !DIExpression(), [[DBG327]])
+; DEBUG-NEXT:    br i1 [[COND17]], label [[TRUE:%.*]], label [[FALSE:%.*]], !dbg [[DBG328:![0-9]+]]
+; DEBUG:       false:
+; DEBUG-NEXT:    [[ANDVAL:%.*]] = and i64 [[KEY]], 7, !dbg [[DBG329:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[ANDVAL]], [[META324:![0-9]+]], !DIExpression(), [[DBG329]])
+; DEBUG-NEXT:    store i64 [[ANDVAL]], ptr [[P64]], align 8, !dbg [[DBG330:![0-9]+]]
+; DEBUG-NEXT:    br label [[EXIT:%.*]], !dbg [[DBG331:![0-9]+]]
+; DEBUG:       true:
+; DEBUG-NEXT:    [[SVALUE:%.*]] = add i64 [[KEY]], -1, !dbg [[DBG332:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[SVALUE]], [[META325:![0-9]+]], !DIExpression(), [[DBG332]])
+; DEBUG-NEXT:    store i64 [[SVALUE]], ptr [[P64]], align 8, !dbg [[DBG333:![0-9]+]]
+; DEBUG-NEXT:    br label [[EXIT]], !dbg [[DBG334:![0-9]+]]
+; DEBUG:       exit:
+; DEBUG-NEXT:    ret void, !dbg [[DBG335:![0-9]+]]
+;
 entry:
   %key = load i64, ptr %p64, align 8
   %cond17 = icmp eq i64 %key, 0
@@ -636,6 +1004,105 @@ exit:
   ret void
 }
 
+define i1 @usubo_uge_i64_overflow_used(i64 %x, i64 %y, ptr %p) {
+; CHECK-LABEL: @usubo_uge_i64_overflow_used(
+; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[OV:%.*]] = icmp uge i64 [[X]], [[Y]]
+; CHECK-NEXT:    ret i1 [[OV]]
+;
+; DEBUG-LABEL: @usubo_uge_i64_overflow_used(
+; DEBUG-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]], !dbg [[DBG340:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[S]], [[META338:![0-9]+]], !DIExpression(), [[DBG340]])
+; DEBUG-NEXT:    [[OV:%.*]] = icmp uge i64 [[X]], [[Y]], !dbg [[DBG341:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META339:![0-9]+]], !DIExpression(), [[DBG341]])
+; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG342:![0-9]+]]
+;
+  %s = sub i64 %x, %y
+  %ov = icmp uge i64 %x, %y
+  ret i1 %ov
+}
+
+define i1 @usubo_uge_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {
+; CHECK-LABEL: @usubo_uge_i64_math_overflow_used(
+; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    store i64 [[S]], ptr [[P:%.*]], align 8
+; CHECK-NEXT:    [[OV:%.*]] = icmp uge i64 [[X]], [[Y]]
+; CHECK-NEXT:    ret i1 [[OV]]
+;
+; DEBUG-LABEL: @usubo_uge_i64_math_overflow_used(
+; DEBUG-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]], !dbg [[DBG347:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i64 [[S]], [[META345:![0-9]+]], !DIExpression(), [[DBG347]])
+; DEBUG-NEXT:    store i64 [[S]], ptr [[P:%.*]], align 8, !dbg [[DBG348:![0-9]+]]
+; DEBUG-NEXT:    [[OV:%.*]] = icmp uge i64 [[X]], [[Y]], !dbg [[DBG349:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META346:![0-9]+]], !DIExpression(), [[DBG349]])
+; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG350:![0-9]+]]
+;
+  %s = sub i64 %x, %y
+  store i64 %s, ptr %p
+  %ov = icmp uge i64 %x, %y
+  ret i1 %ov
+}
+
+define i1 @usubo_ule_i32_overflow_used(i32 %x, i32 %y, ptr %p) {
+; CHECK-LABEL: @usubo_ule_i32_overflow_used(
+; CHECK-NEXT:    [[S:%.*]] = sub i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[OV:%.*]] = icmp uge i32 [[Y]], [[X]]
+; CHECK-NEXT:    ret i1 [[OV]]
+;
+; DEBUG-LABEL: @usubo_ule_i32_overflow_used(
+; DEBUG-NEXT:    [[S:%.*]] = sub i32 [[Y:%.*]], [[X:%.*]], !dbg [[DBG355:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i32 [[S]], [[META353:![0-9]+]], !DIExpression(), [[DBG355]])
+; DEBUG-NEXT:    [[OV:%.*]] = icmp uge i32 [[Y]], [[X]], !dbg [[DBG356:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META354:![0-9]+]], !DIExpression(), [[DBG356]])
+; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG357:![0-9]+]]
+;
+  %s = sub i32 %y, %x
+  %ov = icmp ule i32 %x, %y
+  ret i1 %ov
+}
+
+define i1 @usubo_ne_zero_i16_overflow_used(i16 %x, ptr %p) {
+; CHECK-LABEL: @usubo_ne_zero_i16_overflow_used(
+; CHECK-NEXT:    [[S:%.*]] = sub i16 [[X:%.*]], 1
+; CHECK-NEXT:    store i16 [[S]], ptr [[P:%.*]], align 2
+; CHECK-NEXT:    [[OV:%.*]] = icmp ne i16 [[X]], 0
+; CHECK-NEXT:    ret i1 [[OV]]
+;
+; DEBUG-LABEL: @usubo_ne_zero_i16_overflow_used(
+; DEBUG-NEXT:    [[S:%.*]] = sub i16 [[X:%.*]], 1, !dbg [[DBG362:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i16 [[S]], [[META360:![0-9]+]], !DIExpression(), [[DBG362]])
+; DEBUG-NEXT:    store i16 [[S]], ptr [[P:%.*]], align 2, !dbg [[DBG363:![0-9]+]]
+; DEBUG-NEXT:    [[OV:%.*]] = icmp ne i16 [[X]], 0, !dbg [[DBG364:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META361:![0-9]+]], !DIExpression(), [[DBG364]])
+; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG365:![0-9]+]]
+;
+  %s = sub i16 %x, 1
+  store i16 %s, ptr %p
+  %ov = icmp ne i16 %x, 0
+  ret i1 %ov
+}
+
+define i1 @usubo_eq_zero_i8_overflow_used(i8 %x, ptr %p) {
+; CHECK-LABEL: @usubo_eq_zero_i8_overflow_used(
+; CHECK-NEXT:    [[S:%.*]] = sub i8 0, [[X:%.*]]
+; CHECK-NEXT:    store i8 [[S]], ptr [[P:%.*]], align 1
+; CHECK-NEXT:    [[OV:%.*]] = icmp eq i8 [[X]], 0
+; CHECK-NEXT:    ret i1 [[OV]]
+;
+; DEBUG-LABEL: @usubo_eq_zero_i8_overflow_used(
+; DEBUG-NEXT:    [[S:%.*]] = sub i8 0, [[X:%.*]], !dbg [[DBG370:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i8 [[S]], [[META368:![0-9]+]], !DIExpression(), [[DBG370]])
+; DEBUG-NEXT:    store i8 [[S]], ptr [[P:%.*]], align 1, !dbg [[DBG371:![0-9]+]]
+; DEBUG-NEXT:    [[OV:%.*]] = icmp eq i8 [[X]], 0, !dbg [[DBG372:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META369:![0-9]+]], !DIExpression(), [[DBG372]])
+; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG373:![0-9]+]]
+;
+  %s = sub i8 0, %x
+  store i8 %s, ptr %p
+  %ov = icmp eq i8 %x, 0
+  ret i1 %ov
+}
+
 ; Check that every instruction inserted by -passes='require<profile-summary>,function(codegenprepare)' has a debug location.
 ; DEBUG: CheckModuleDebugify: PASS
 

>From 32c932b2adfd578dda6c8805e0836525a9f413b2 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sun, 6 Jul 2025 10:42:04 -0400
Subject: [PATCH 2/2] [CodeGenPrepare] Prepare the usubo check with the
 opposite overflow condition

We check the overflow condition before codegenprepare makes it into the intrinsic, but not the opposite.
---
 llvm/lib/CodeGen/CodeGenPrepare.cpp           | 77 ++++++++++++++-
 llvm/test/CodeGen/X86/sub-with-overflow.ll    | 31 +++---
 .../CodeGenPrepare/X86/overflow-intrinsics.ll | 96 +++++++++++--------
 3 files changed, 150 insertions(+), 54 deletions(-)

diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 9bbb89e37865d..ee0f9e8554489 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -470,10 +470,12 @@ class CodeGenPrepare {
 
   bool tryToSinkFreeOperands(Instruction *I);
   bool replaceMathCmpWithIntrinsic(BinaryOperator *BO, Value *Arg0, Value *Arg1,
-                                   CmpInst *Cmp, Intrinsic::ID IID);
+                                   CmpInst *Cmp, Intrinsic::ID IID,
+                                   bool NegateOverflow = false);
   bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
   bool optimizeURem(Instruction *Rem);
   bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
+  bool combineToUSubWithNegatedOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
   bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
   bool unfoldPowerOf2Test(CmpInst *Cmp);
   void verifyBFIUpdates(Function &F);
@@ -1552,7 +1554,8 @@ static bool isIVIncrement(const Value *V, const LoopInfo *LI) {
 bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
                                                  Value *Arg0, Value *Arg1,
                                                  CmpInst *Cmp,
-                                                 Intrinsic::ID IID) {
+                                                 Intrinsic::ID IID,
+                                                 bool NegateOverflow) {
   auto IsReplacableIVIncrement = [this, &Cmp](BinaryOperator *BO) {
     if (!isIVIncrement(BO, LI))
       return false;
@@ -1624,6 +1627,8 @@ bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO,
     assert(BO->hasOneUse() &&
            "Patterns with XOr should use the BO only in the compare");
   Value *OV = Builder.CreateExtractValue(MathOV, 1, "ov");
+  if (NegateOverflow)
+    OV = Builder.CreateXor(OV, ConstantInt::getAllOnesValue(OV->getType()));
   replaceAllUsesWith(Cmp, OV, FreshBBs, IsHugeFunc);
   Cmp->eraseFromParent();
   BO->eraseFromParent();
@@ -1759,6 +1764,71 @@ bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
   return true;
 }
 
+bool CodeGenPrepare::combineToUSubWithNegatedOverflow(CmpInst *Cmp,
+                                                      ModifyDT &ModifiedDT) {
+  // We are not expecting non-canonical/degenerate code. Just bail out.
+  Value *A = Cmp->getOperand(0), *B = Cmp->getOperand(1);
+  if (isa<Constant>(A) && isa<Constant>(B))
+    return false;
+
+  // Convert (A u<= B) to (A u>= B) to simplify pattern matching.
+  ICmpInst::Predicate Pred = Cmp->getPredicate();
+  if (Pred == ICmpInst::ICMP_ULE) {
+    std::swap(A, B);
+    Pred = ICmpInst::ICMP_UGE;
+  }
+  // Convert special-case: (A != 0) is the same as (A u>= 1).
+  if (Pred == ICmpInst::ICMP_NE && match(B, m_ZeroInt())) {
+    B = ConstantInt::get(B->getType(), 1);
+    Pred = ICmpInst::ICMP_UGE;
+  }
+
+  // Convert special-case: (A == 0) is the same as (0 u>= A).
+  if (Pred == ICmpInst::ICMP_EQ && match(B, m_ZeroInt())) {
+    std::swap(A, B);
+    Pred = ICmpInst::ICMP_UGE;
+  }
+
+  if (Pred != ICmpInst::ICMP_UGE)
+    return false;
+
+  // Walk the users of a variable operand of a compare looking for a subtract or
+  // add with that same operand. Also match the 2nd operand of the compare to
+  // the add/sub, but that may be a negated constant operand of an add.
+  Value *CmpVariableOperand = isa<Constant>(A) ? B : A;
+  BinaryOperator *Sub = nullptr;
+  for (User *U : CmpVariableOperand->users()) {
+    // A - B, A u> B --> usubo(A, B)
+    if (match(U, m_Sub(m_Specific(A), m_Specific(B)))) {
+      Sub = cast<BinaryOperator>(U);
+      break;
+    }
+
+    // A + (-C), A u> C (canonicalized form of (sub A, C))
+    const APInt *CmpC, *AddC;
+    if (match(U, m_Add(m_Specific(A), m_APInt(AddC))) &&
+        match(B, m_APInt(CmpC)) && *AddC == -(*CmpC)) {
+      Sub = cast<BinaryOperator>(U);
+      break;
+    }
+  }
+  if (!Sub)
+    return false;
+
+  if (!TLI->shouldFormOverflowOp(ISD::USUBO,
+                                 TLI->getValueType(*DL, Sub->getType()),
+                                 Sub->hasNUsesOrMore(1)))
+    return false;
+
+  if (!replaceMathCmpWithIntrinsic(Sub, Sub->getOperand(0), Sub->getOperand(1),
+                                   Cmp, Intrinsic::usub_with_overflow, true))
+    return false;
+
+  // Reset callers - do not crash by iterating over a dead instruction.
+  ModifiedDT = ModifyDT::ModifyInstDT;
+  return true;
+}
+
 // Decanonicalizes icmp+ctpop power-of-two test if ctpop is slow.
 // The same transformation exists in DAG combiner, but we repeat it here because
 // DAG builder can break the pattern by moving icmp into a successor block.
@@ -2224,6 +2294,9 @@ bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
   if (combineToUSubWithOverflow(Cmp, ModifiedDT))
     return true;
 
+  if (combineToUSubWithNegatedOverflow(Cmp, ModifiedDT))
+    return true;
+
   if (unfoldPowerOf2Test(Cmp))
     return true;
 
diff --git a/llvm/test/CodeGen/X86/sub-with-overflow.ll b/llvm/test/CodeGen/X86/sub-with-overflow.ll
index ca28cfe2d3d14..3aa1c8e217ac8 100644
--- a/llvm/test/CodeGen/X86/sub-with-overflow.ll
+++ b/llvm/test/CodeGen/X86/sub-with-overflow.ll
@@ -111,14 +111,19 @@ define i1 @usubo_uge_i64_overflow_used(i64 %x, i64 %y, ptr %p) {
 define i1 @usubo_uge_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {
 ; CHECK-LABEL: usubo_uge_i64_math_overflow_used:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    pushl %esi
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset %esi, -8
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; CHECK-NEXT:    subl {{[0-9]+}}(%esp), %ecx
-; CHECK-NEXT:    movl %ecx, (%eax)
-; CHECK-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
-; CHECK-NEXT:    movl %edx, 4(%eax)
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; CHECK-NEXT:    subl {{[0-9]+}}(%esp), %edx
+; CHECK-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
 ; CHECK-NEXT:    setae %al
+; CHECK-NEXT:    movl %edx, (%ecx)
+; CHECK-NEXT:    movl %esi, 4(%ecx)
+; CHECK-NEXT:    popl %esi
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    retl
   %s = sub i64 %x, %y
   store i64 %s, ptr %p
@@ -141,13 +146,11 @@ define i1 @usubo_ule_i32_overflow_used(i32 %x, i32 %y, ptr %p) {
 define i1 @usubo_ne_zero_i16_overflow_used(i16 %x, ptr %p) {
 ; CHECK-LABEL: usubo_ne_zero_i16_overflow_used:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; CHECK-NEXT:    movl %eax, %edx
-; CHECK-NEXT:    decl %edx
+; CHECK-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
+; CHECK-NEXT:    subw $1, %dx
+; CHECK-NEXT:    setae %al
 ; CHECK-NEXT:    movw %dx, (%ecx)
-; CHECK-NEXT:    testw %ax, %ax
-; CHECK-NEXT:    setne %al
 ; CHECK-NEXT:    retl
   %s = sub i16 %x, 1
   store i16 %s, ptr %p
@@ -158,11 +161,11 @@ define i1 @usubo_ne_zero_i16_overflow_used(i16 %x, ptr %p) {
 define i1 @usubo_eq_zero_i8_overflow_used(i8 %x, ptr %p) {
 ; CHECK-LABEL: usubo_eq_zero_i8_overflow_used:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
-; CHECK-NEXT:    negb %cl
-; CHECK-NEXT:    movb %cl, (%eax)
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    subb {{[0-9]+}}(%esp), %dl
 ; CHECK-NEXT:    setae %al
+; CHECK-NEXT:    movb %dl, (%ecx)
 ; CHECK-NEXT:    retl
   %s = sub i8 0, %x
   store i8 %s, ptr %p
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll b/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
index 768587f16c335..e6c99b32ea0dd 100644
--- a/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
@@ -1006,16 +1006,20 @@ exit:
 
 define i1 @usubo_uge_i64_overflow_used(i64 %x, i64 %y, ptr %p) {
 ; CHECK-LABEL: @usubo_uge_i64_overflow_used(
-; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[OV:%.*]] = icmp uge i64 [[X]], [[Y]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]])
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
+; CHECK-NEXT:    [[OV:%.*]] = xor i1 [[OV1]], true
 ; CHECK-NEXT:    ret i1 [[OV]]
 ;
 ; DEBUG-LABEL: @usubo_uge_i64_overflow_used(
-; DEBUG-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]], !dbg [[DBG340:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i64 [[S]], [[META338:![0-9]+]], !DIExpression(), [[DBG340]])
-; DEBUG-NEXT:    [[OV:%.*]] = icmp uge i64 [[X]], [[Y]], !dbg [[DBG341:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META339:![0-9]+]], !DIExpression(), [[DBG341]])
-; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG342:![0-9]+]]
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]), !dbg [[DBG340:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG340]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG340]]
+; DEBUG-NEXT:    [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG340]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META338:![0-9]+]], !DIExpression(), [[DBG340]])
+; DEBUG-NEXT:      #dbg_value(i1 [[TMP2]], [[META339:![0-9]+]], !DIExpression(), [[META341:![0-9]+]])
+; DEBUG-NEXT:    ret i1 [[TMP2]], !dbg [[DBG342:![0-9]+]]
 ;
   %s = sub i64 %x, %y
   %ov = icmp uge i64 %x, %y
@@ -1024,18 +1028,22 @@ define i1 @usubo_uge_i64_overflow_used(i64 %x, i64 %y, ptr %p) {
 
 define i1 @usubo_uge_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {
 ; CHECK-LABEL: @usubo_uge_i64_math_overflow_used(
-; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]])
+; CHECK-NEXT:    [[S:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
+; CHECK-NEXT:    [[OV:%.*]] = xor i1 [[OV1]], true
 ; CHECK-NEXT:    store i64 [[S]], ptr [[P:%.*]], align 8
-; CHECK-NEXT:    [[OV:%.*]] = icmp uge i64 [[X]], [[Y]]
 ; CHECK-NEXT:    ret i1 [[OV]]
 ;
 ; DEBUG-LABEL: @usubo_uge_i64_math_overflow_used(
-; DEBUG-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]], !dbg [[DBG347:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i64 [[S]], [[META345:![0-9]+]], !DIExpression(), [[DBG347]])
-; DEBUG-NEXT:    store i64 [[S]], ptr [[P:%.*]], align 8, !dbg [[DBG348:![0-9]+]]
-; DEBUG-NEXT:    [[OV:%.*]] = icmp uge i64 [[X]], [[Y]], !dbg [[DBG349:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META346:![0-9]+]], !DIExpression(), [[DBG349]])
-; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG350:![0-9]+]]
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]), !dbg [[DBG347:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG347]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG347]]
+; DEBUG-NEXT:    [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG347]]
+; DEBUG-NEXT:      #dbg_value(i64 [[MATH]], [[META345:![0-9]+]], !DIExpression(), [[DBG347]])
+; DEBUG-NEXT:    store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG348:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[TMP2]], [[META346:![0-9]+]], !DIExpression(), [[META349:![0-9]+]])
+; DEBUG-NEXT:    ret i1 [[TMP2]], !dbg [[DBG350:![0-9]+]]
 ;
   %s = sub i64 %x, %y
   store i64 %s, ptr %p
@@ -1045,16 +1053,20 @@ define i1 @usubo_uge_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {
 
 define i1 @usubo_ule_i32_overflow_used(i32 %x, i32 %y, ptr %p) {
 ; CHECK-LABEL: @usubo_ule_i32_overflow_used(
-; CHECK-NEXT:    [[S:%.*]] = sub i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[OV:%.*]] = icmp uge i32 [[Y]], [[X]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
+; CHECK-NEXT:    [[OV:%.*]] = xor i1 [[OV1]], true
 ; CHECK-NEXT:    ret i1 [[OV]]
 ;
 ; DEBUG-LABEL: @usubo_ule_i32_overflow_used(
-; DEBUG-NEXT:    [[S:%.*]] = sub i32 [[Y:%.*]], [[X:%.*]], !dbg [[DBG355:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i32 [[S]], [[META353:![0-9]+]], !DIExpression(), [[DBG355]])
-; DEBUG-NEXT:    [[OV:%.*]] = icmp uge i32 [[Y]], [[X]], !dbg [[DBG356:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META354:![0-9]+]], !DIExpression(), [[DBG356]])
-; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG357:![0-9]+]]
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[Y:%.*]], i32 [[X:%.*]]), !dbg [[DBG355:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG355]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG355]]
+; DEBUG-NEXT:    [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG355]]
+; DEBUG-NEXT:      #dbg_value(i32 [[MATH]], [[META353:![0-9]+]], !DIExpression(), [[DBG355]])
+; DEBUG-NEXT:      #dbg_value(i1 [[TMP2]], [[META354:![0-9]+]], !DIExpression(), [[META356:![0-9]+]])
+; DEBUG-NEXT:    ret i1 [[TMP2]], !dbg [[DBG357:![0-9]+]]
 ;
   %s = sub i32 %y, %x
   %ov = icmp ule i32 %x, %y
@@ -1063,18 +1075,22 @@ define i1 @usubo_ule_i32_overflow_used(i32 %x, i32 %y, ptr %p) {
 
 define i1 @usubo_ne_zero_i16_overflow_used(i16 %x, ptr %p) {
 ; CHECK-LABEL: @usubo_ne_zero_i16_overflow_used(
-; CHECK-NEXT:    [[S:%.*]] = sub i16 [[X:%.*]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 1)
+; CHECK-NEXT:    [[S:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1
+; CHECK-NEXT:    [[OV:%.*]] = xor i1 [[OV1]], true
 ; CHECK-NEXT:    store i16 [[S]], ptr [[P:%.*]], align 2
-; CHECK-NEXT:    [[OV:%.*]] = icmp ne i16 [[X]], 0
 ; CHECK-NEXT:    ret i1 [[OV]]
 ;
 ; DEBUG-LABEL: @usubo_ne_zero_i16_overflow_used(
-; DEBUG-NEXT:    [[S:%.*]] = sub i16 [[X:%.*]], 1, !dbg [[DBG362:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i16 [[S]], [[META360:![0-9]+]], !DIExpression(), [[DBG362]])
-; DEBUG-NEXT:    store i16 [[S]], ptr [[P:%.*]], align 2, !dbg [[DBG363:![0-9]+]]
-; DEBUG-NEXT:    [[OV:%.*]] = icmp ne i16 [[X]], 0, !dbg [[DBG364:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META361:![0-9]+]], !DIExpression(), [[DBG364]])
-; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG365:![0-9]+]]
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 1), !dbg [[DBG362:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0, !dbg [[DBG362]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !dbg [[DBG362]]
+; DEBUG-NEXT:    [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG362]]
+; DEBUG-NEXT:      #dbg_value(i16 [[MATH]], [[META360:![0-9]+]], !DIExpression(), [[DBG362]])
+; DEBUG-NEXT:    store i16 [[MATH]], ptr [[P:%.*]], align 2, !dbg [[DBG363:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[TMP2]], [[META361:![0-9]+]], !DIExpression(), [[META364:![0-9]+]])
+; DEBUG-NEXT:    ret i1 [[TMP2]], !dbg [[DBG365:![0-9]+]]
 ;
   %s = sub i16 %x, 1
   store i16 %s, ptr %p
@@ -1084,18 +1100,22 @@ define i1 @usubo_ne_zero_i16_overflow_used(i16 %x, ptr %p) {
 
 define i1 @usubo_eq_zero_i8_overflow_used(i8 %x, ptr %p) {
 ; CHECK-LABEL: @usubo_eq_zero_i8_overflow_used(
-; CHECK-NEXT:    [[S:%.*]] = sub i8 0, [[X:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 0, i8 [[X:%.*]])
+; CHECK-NEXT:    [[S:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
+; CHECK-NEXT:    [[OV:%.*]] = xor i1 [[OV1]], true
 ; CHECK-NEXT:    store i8 [[S]], ptr [[P:%.*]], align 1
-; CHECK-NEXT:    [[OV:%.*]] = icmp eq i8 [[X]], 0
 ; CHECK-NEXT:    ret i1 [[OV]]
 ;
 ; DEBUG-LABEL: @usubo_eq_zero_i8_overflow_used(
-; DEBUG-NEXT:    [[S:%.*]] = sub i8 0, [[X:%.*]], !dbg [[DBG370:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i8 [[S]], [[META368:![0-9]+]], !DIExpression(), [[DBG370]])
-; DEBUG-NEXT:    store i8 [[S]], ptr [[P:%.*]], align 1, !dbg [[DBG371:![0-9]+]]
-; DEBUG-NEXT:    [[OV:%.*]] = icmp eq i8 [[X]], 0, !dbg [[DBG372:![0-9]+]]
-; DEBUG-NEXT:      #dbg_value(i1 [[OV]], [[META369:![0-9]+]], !DIExpression(), [[DBG372]])
-; DEBUG-NEXT:    ret i1 [[OV]], !dbg [[DBG373:![0-9]+]]
+; DEBUG-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 0, i8 [[X:%.*]]), !dbg [[DBG370:![0-9]+]]
+; DEBUG-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0, !dbg [[DBG370]]
+; DEBUG-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !dbg [[DBG370]]
+; DEBUG-NEXT:    [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG370]]
+; DEBUG-NEXT:      #dbg_value(i8 [[MATH]], [[META368:![0-9]+]], !DIExpression(), [[DBG370]])
+; DEBUG-NEXT:    store i8 [[MATH]], ptr [[P:%.*]], align 1, !dbg [[DBG371:![0-9]+]]
+; DEBUG-NEXT:      #dbg_value(i1 [[TMP2]], [[META369:![0-9]+]], !DIExpression(), [[META372:![0-9]+]])
+; DEBUG-NEXT:    ret i1 [[TMP2]], !dbg [[DBG373:![0-9]+]]
 ;
   %s = sub i8 0, %x
   store i8 %s, ptr %p



More information about the llvm-commits mailing list