[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:33:05 PDT 2025


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

We check the overflow condition before codegenprepare makes it into the intrinsic, but not the opposite.

Also need help in fixing the regression for 64 bit overflow on 32 bits

>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 3b7b23554f3c17b519fdf9e172d50b5c42db3b01 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           | 75 ++++++++++++++-
 llvm/test/CodeGen/X86/sub-with-overflow.ll    | 31 +++---
 .../CodeGenPrepare/X86/overflow-intrinsics.ll | 96 +++++++++++--------
 3 files changed, 148 insertions(+), 54 deletions(-)

diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 9bbb89e37865d..303fb8d08a0b7 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -470,10 +470,11 @@ 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 +1553,7 @@ 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 +1625,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 +1762,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 +2292,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