From 6df863a8c44840615fbc582446b3b17a682df6e8 Mon Sep 17 00:00:00 2001 From: Rose Date: Sun, 6 Jul 2025 14:22:41 -0400 Subject: [PATCH 1/2] Catch inverse of uaddoverflow Basically where there are checks for overflow but the condition is inverted. Revert "Catch inverse of uaddoverflow" This reverts commit c5c8e2b4e01d07ff825385d98d1bee9f42654b61. Reapply "Catch inverse of uaddoverflow" This reverts commit bcee466cdc0cdd99ab075a041ba07205aefec175. s --- .../AArch64/overflow-intrinsics.ll | 331 +++++++++++++++++- 1 file changed, 325 insertions(+), 6 deletions(-) diff --git a/llvm/test/Transforms/CodeGenPrepare/AArch64/overflow-intrinsics.ll b/llvm/test/Transforms/CodeGenPrepare/AArch64/overflow-intrinsics.ll index f72679f55e114..f228f3da9c128 100644 --- a/llvm/test/Transforms/CodeGenPrepare/AArch64/overflow-intrinsics.ll +++ b/llvm/test/Transforms/CodeGenPrepare/AArch64/overflow-intrinsics.ll @@ -15,6 +15,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 @@ -28,8 +38,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 @@ -45,6 +66,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 @@ -58,8 +89,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 @@ -75,6 +117,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 @@ -88,8 +140,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 @@ -106,6 +169,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, [[META68:![0-9]+]], !DIExpression(), [[META71:![0-9]+]]) +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]), !dbg [[DBG72:![0-9]+]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG72]] +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META69:![0-9]+]], !DIExpression(), [[DBG72]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG73:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META70:![0-9]+]], !DIExpression(), [[DBG73]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG74:![0-9]+]] ; %x = xor i64 %a, -1 %cmp = icmp ult i64 %x, %b @@ -119,6 +191,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, [[META77:![0-9]+]], !DIExpression(), [[META80:![0-9]+]]) +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]), !dbg [[DBG81:![0-9]+]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG81]] +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META78:![0-9]+]], !DIExpression(), [[DBG81]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG82:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META79:![0-9]+]], !DIExpression(), [[DBG82]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG83:![0-9]+]] ; %x = xor i64 %a, -1 %cmp = icmp ugt i64 %b, %x @@ -135,6 +216,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 [[DBG89:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[X]], [[META86:![0-9]+]], !DIExpression(), [[DBG89]]) +; DEBUG-NEXT: [[CMP:%.*]] = icmp ult i64 [[X]], [[B:%.*]], !dbg [[DBG90:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META87:![0-9]+]], !DIExpression(), [[DBG90]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG91:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META88:![0-9]+]], !DIExpression(), [[DBG91]]) +; DEBUG-NEXT: call void @use(i64 [[X]]), !dbg [[DBG92:![0-9]+]] +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG93:![0-9]+]] ; %x = xor i64 -1, %a %cmp = icmp ult i64 %x, %b @@ -143,11 +234,231 @@ define i64 @uaddo6_xor_multi_use(i64 %a, i64 %b) { ret i64 %Q } -define i1 @usubo_ult_i64_overflow_used(i64 %x, i64 %y, ptr %p) { -; CHECK-LABEL: @usubo_ult_i64_overflow_used( + +define i64 @uaddo1_overflow_used_neg(i64 %a, i64 %b) nounwind ssp { +; CHECK-LABEL: @uaddo1_overflow_used_neg( +; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[A]] +; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo1_overflow_used_neg( +; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG99:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META96:![0-9]+]], !DIExpression(), [[DBG99]]) +; DEBUG-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[A]], !dbg [[DBG100:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META97:![0-9]+]], !DIExpression(), [[DBG100]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG101:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META98:![0-9]+]], !DIExpression(), [[DBG101]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG102:![0-9]+]] +; + %add = add i64 %b, %a + %cmp = icmp uge i64 %add, %a + %Q = select i1 %cmp, i64 %b, i64 42 + ret i64 %Q +} + +define i64 @uaddo1_math_overflow_used_neg(i64 %a, i64 %b, ptr %res) nounwind ssp { +; CHECK-LABEL: @uaddo1_math_overflow_used_neg( +; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[A]] +; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8 +; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo1_math_overflow_used_neg( +; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG108:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META105:![0-9]+]], !DIExpression(), [[DBG108]]) +; DEBUG-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[A]], !dbg [[DBG109:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META106:![0-9]+]], !DIExpression(), [[DBG109]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG110:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META107:![0-9]+]], !DIExpression(), [[DBG110]]) +; DEBUG-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8, !dbg [[DBG111:![0-9]+]] +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG112:![0-9]+]] +; + %add = add i64 %b, %a + %cmp = icmp uge i64 %add, %a + %Q = select i1 %cmp, i64 %b, i64 42 + store i64 %add, ptr %res + ret i64 %Q +} + +define i64 @uaddo2_overflow_used_neg(i64 %a, i64 %b) nounwind ssp { +; CHECK-LABEL: @uaddo2_overflow_used_neg( +; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[B]] +; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo2_overflow_used_neg( +; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG118:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META115:![0-9]+]], !DIExpression(), [[DBG118]]) +; DEBUG-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[B]], !dbg [[DBG119:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META116:![0-9]+]], !DIExpression(), [[DBG119]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG120:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META117:![0-9]+]], !DIExpression(), [[DBG120]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG121:![0-9]+]] +; + %add = add i64 %b, %a + %cmp = icmp uge i64 %add, %b + %Q = select i1 %cmp, i64 %b, i64 42 + ret i64 %Q +} + +define i64 @uaddo2_math_overflow_used_neg(i64 %a, i64 %b, ptr %res) nounwind ssp { +; CHECK-LABEL: @uaddo2_math_overflow_used_neg( +; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[B]] +; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8 +; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo2_math_overflow_used_neg( +; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG127:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META124:![0-9]+]], !DIExpression(), [[DBG127]]) +; DEBUG-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[B]], !dbg [[DBG128:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META125:![0-9]+]], !DIExpression(), [[DBG128]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG129:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META126:![0-9]+]], !DIExpression(), [[DBG129]]) +; DEBUG-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8, !dbg [[DBG130:![0-9]+]] +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG131:![0-9]+]] +; + %add = add i64 %b, %a + %cmp = icmp uge i64 %add, %b + %Q = select i1 %cmp, i64 %b, i64 42 + store i64 %add, ptr %res + ret i64 %Q +} + +define i64 @uaddo3_overflow_used_neg(i64 %a, i64 %b) nounwind ssp { +; CHECK-LABEL: @uaddo3_overflow_used_neg( +; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[B]], [[ADD]] +; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo3_overflow_used_neg( +; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG137:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META134:![0-9]+]], !DIExpression(), [[DBG137]]) +; DEBUG-NEXT: [[CMP:%.*]] = icmp ule i64 [[B]], [[ADD]], !dbg [[DBG138:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META135:![0-9]+]], !DIExpression(), [[DBG138]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG139:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META136:![0-9]+]], !DIExpression(), [[DBG139]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG140:![0-9]+]] +; + %add = add i64 %b, %a + %cmp = icmp ule i64 %b, %add + %Q = select i1 %cmp, i64 %b, i64 42 + ret i64 %Q +} + +define i64 @uaddo3_math_overflow_used_neg(i64 %a, i64 %b, ptr %res) nounwind ssp { +; CHECK-LABEL: @uaddo3_math_overflow_used_neg( +; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[B]], [[ADD]] +; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8 +; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo3_math_overflow_used_neg( +; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG146:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META143:![0-9]+]], !DIExpression(), [[DBG146]]) +; DEBUG-NEXT: [[CMP:%.*]] = icmp ule i64 [[B]], [[ADD]], !dbg [[DBG147:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META144:![0-9]+]], !DIExpression(), [[DBG147]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG148:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META145:![0-9]+]], !DIExpression(), [[DBG148]]) +; DEBUG-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8, !dbg [[DBG149:![0-9]+]] +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG150:![0-9]+]] +; + %add = add i64 %b, %a + %cmp = icmp ule i64 %b, %add + %Q = select i1 %cmp, i64 %b, i64 42 + store i64 %add, ptr %res + ret i64 %Q +} + +; Instcombine folds (a + b Date: Sun, 6 Jul 2025 15:55:23 -0400 Subject: [PATCH 2/2] Match the inverse of m_AddOverflow Basically where there are checks for overflow but the condition is inverted. This is also really cool because it allows us to also fold usubs with constants better. How? Well, if subtraction of a number underflows, addition of its negative overflows. This identity is baked into the silicon of ARM chips and single-add. I didn't even write code based on this property: I just negated the icmps and LLVM folding figured the rest out! --- llvm/include/llvm/IR/PatternMatch.h | 75 ++++ llvm/lib/CodeGen/CodeGenPrepare.cpp | 69 ++- .../InstCombine/InstCombineCompares.cpp | 21 +- llvm/test/CodeGen/AArch64/cgp-usubo.ll | 8 +- llvm/test/CodeGen/AArch64/cmpxchg-idioms.ll | 12 +- .../X86/lack-of-signed-truncation-check.ll | 12 +- llvm/test/CodeGen/X86/setcc-combine.ll | 13 +- .../AArch64/overflow-intrinsics.ll | 162 ++++--- .../CodeGenPrepare/X86/optimizeSelect-DT.ll | 5 +- .../CodeGenPrepare/X86/overflow-intrinsics.ll | 424 ++++++++++++++++-- 10 files changed, 670 insertions(+), 131 deletions(-) diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index ed9b83d5d4361..2faacbca607a7 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -2595,6 +2595,70 @@ struct UAddWithOverflow_match { } }; +//===----------------------------------------------------------------------===// +// Matchers for overflow check patterns: e.g. (a + b) u< a, (a ^ -1) +struct UAddWithOverflowInv_match { + LHS_t L; + RHS_t R; + Sum_t S; + + UAddWithOverflowInv_match(const LHS_t &L, const RHS_t &R, const Sum_t &S) + : L(L), R(R), S(S) {} + + template bool match(OpTy *V) const { + Value *ICmpLHS, *ICmpRHS; + CmpPredicate Pred; + if (!m_ICmp(Pred, m_Value(ICmpLHS), m_Value(ICmpRHS)).match(V)) + return false; + + Value *AddLHS, *AddRHS; + auto AddExpr = m_Add(m_Value(AddLHS), m_Value(AddRHS)); + + // (a + b) u>= a, (a + b) u>= b + if (Pred == ICmpInst::ICMP_UGE) + if (AddExpr.match(ICmpLHS) && (ICmpRHS == AddLHS || ICmpRHS == AddRHS)) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS); + + // a <=u (a + b), b <=u (a + b) + if (Pred == ICmpInst::ICMP_ULE) + if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS)) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS); + + Value *Op1; + auto XorExpr = m_OneUse(m_Not(m_Value(Op1))); + // (~a) >= u b + if (Pred == ICmpInst::ICMP_UGE) { + if (XorExpr.match(ICmpLHS)) + return L.match(Op1) && R.match(ICmpRHS) && S.match(ICmpLHS); + } + // b <= u (~a) + if (Pred == ICmpInst::ICMP_ULE) { + if (XorExpr.match(ICmpRHS)) + return L.match(Op1) && R.match(ICmpLHS) && S.match(ICmpRHS); + } + + // Match special-case for increment-by-1. + if (Pred == ICmpInst::ICMP_NE) { + // (a + 1) != 0 + // (1 + a) != 0 + if (AddExpr.match(ICmpLHS) && m_ZeroInt().match(ICmpRHS) && + (m_One().match(AddLHS) || m_One().match(AddRHS))) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS); + // 0 != (a + 1) + // 0 != (1 + a) + if (m_ZeroInt().match(ICmpLHS) && AddExpr.match(ICmpRHS) && + (m_One().match(AddLHS) || m_One().match(AddRHS))) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS); + } + + return false; + } +}; + /// Match an icmp instruction checking for unsigned overflow on addition. /// /// S is matched to the addition whose result is being checked for overflow, and @@ -2605,6 +2669,17 @@ m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S) { return UAddWithOverflow_match(L, R, S); } +/// Match an icmp instruction checking for unsigned overflow on addition, but +/// with the opposite check. +/// +/// S is matched to the addition whose result is being checked for overflow, and +/// L and R are matched to the LHS and RHS of S. +template +UAddWithOverflowInv_match +m_UAddWithOverflowInv(const LHS_t &L, const RHS_t &R, const Sum_t &S) { + return UAddWithOverflowInv_match(L, R, S); +} + template struct Argument_match { unsigned OpI; Opnd_t Val; diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 9bbb89e37865d..ce5570f4f9a1e 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -470,7 +470,8 @@ 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); @@ -1552,7 +1553,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 +1626,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.CreateNot(OV, "not"); replaceAllUsesWith(Cmp, OV, FreshBBs, IsHugeFunc); Cmp->eraseFromParent(); BO->eraseFromParent(); @@ -1660,6 +1664,38 @@ static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp, return false; } +/// Match special-case patterns that check for unsigned add overflow but inverts +/// the add check +static bool +matchUAddWithOverflowConstantEdgeCasesInverted(CmpInst *Cmp, + BinaryOperator *&Add) { + // Add = add A, 1; Cmp = icmp ne A,-1 (overflow if A is max val) + // Add = add A,-1; Cmp = icmp eq A, 0 (overflow if A is non-zero) + Value *A = Cmp->getOperand(0), *B = Cmp->getOperand(1); + + // We are not expecting non-canonical/degenerate code. Just bail out. + if (isa(A)) + return false; + + ICmpInst::Predicate Pred = Cmp->getPredicate(); + if (Pred == ICmpInst::ICMP_NE && match(B, m_AllOnes())) + B = ConstantInt::get(B->getType(), 1); + else if (Pred == ICmpInst::ICMP_EQ && match(B, m_ZeroInt())) + B = Constant::getAllOnesValue(B->getType()); + else + return false; + + // Check the users of the variable operand of the compare looking for an add + // with the adjusted constant. + for (User *U : A->users()) { + if (match(U, m_Add(m_Specific(A), m_Specific(B)))) { + Add = cast(U); + return true; + } + } + return false; +} + /// Try to combine the compare into a call to the llvm.uadd.with.overflow /// intrinsic. Return true if any changes were made. bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp, @@ -1667,13 +1703,24 @@ bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp, bool EdgeCase = false; Value *A, *B; BinaryOperator *Add; + bool Negate = false; if (!match(Cmp, m_UAddWithOverflow(m_Value(A), m_Value(B), m_BinOp(Add)))) { - if (!matchUAddWithOverflowConstantEdgeCases(Cmp, Add)) - return false; - // Set A and B in case we match matchUAddWithOverflowConstantEdgeCases. - A = Add->getOperand(0); - B = Add->getOperand(1); - EdgeCase = true; + if (matchUAddWithOverflowConstantEdgeCases(Cmp, Add)) { + // Set A and B in case we match matchUAddWithOverflowConstantEdgeCases. + A = Add->getOperand(0); + B = Add->getOperand(1); + EdgeCase = true; + } else { + Negate = true; + if (!match(Cmp, + m_UAddWithOverflowInv(m_Value(A), m_Value(B), m_BinOp(Add)))) { + if (!matchUAddWithOverflowConstantEdgeCasesInverted(Cmp, Add)) + return false; + A = Add->getOperand(0); + B = Add->getOperand(1); + EdgeCase = true; + } + } } if (!TLI->shouldFormOverflowOp(ISD::UADDO, @@ -1688,7 +1735,7 @@ bool CodeGenPrepare::combineToUAddWithOverflow(CmpInst *Cmp, return false; if (!replaceMathCmpWithIntrinsic(Add, A, B, Cmp, - Intrinsic::uadd_with_overflow)) + Intrinsic::uadd_with_overflow, Negate)) return false; // Reset callers - do not crash by iterating over a dead instruction. @@ -2218,10 +2265,10 @@ bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) { if (sinkCmpExpression(Cmp, *TLI)) return true; - if (combineToUAddWithOverflow(Cmp, ModifiedDT)) + if (combineToUSubWithOverflow(Cmp, ModifiedDT)) return true; - if (combineToUSubWithOverflow(Cmp, ModifiedDT)) + if (combineToUAddWithOverflow(Cmp, ModifiedDT)) return true; if (unfoldPowerOf2Test(Cmp)) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index c6f317a668cfe..694de16fd2d11 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -7821,7 +7821,7 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) { isa(X->getType())) { Value *Result; Constant *Overflow; - // m_UAddWithOverflow can match patterns that do not include an explicit + // m_UAddWithOverflow can match patterns that do not include an explicit // "add" instruction, so check the opcode of the matched op. if (AddI->getOpcode() == Instruction::Add && OptimizeOverflowCheck(Instruction::Add, /*Signed*/ false, X, Y, *AddI, @@ -7832,6 +7832,25 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) { } } + if (match(&I, m_UAddWithOverflowInv(m_Value(X), m_Value(Y), + m_Instruction(AddI))) && + isa(X->getType())) { + Value *Result; + Constant *Overflow; + // m_UAddWithOverflowInv can match patterns that do not include an + // explicit "add" instruction, so check the opcode of the matched op. + if (AddI->getOpcode() == Instruction::Add && + OptimizeOverflowCheck(Instruction::Add, /*Signed*/ false, X, Y, *AddI, + Result, Overflow)) { + Overflow = Overflow->isNullValue() + ? ConstantInt::getTrue(Overflow->getType()) + : ConstantInt::getFalse(Overflow->getType()); + replaceInstUsesWith(*AddI, Result); + eraseInstFromFunction(*AddI); + return replaceInstUsesWith(I, Overflow); + } + } + // (zext X) * (zext Y) --> llvm.umul.with.overflow. if (match(Op0, m_NUWMul(m_ZExt(m_Value(X)), m_ZExt(m_Value(Y)))) && match(Op1, m_APInt(C))) { diff --git a/llvm/test/CodeGen/AArch64/cgp-usubo.ll b/llvm/test/CodeGen/AArch64/cgp-usubo.ll index d307107fc07ee..e49e8e86561c7 100644 --- a/llvm/test/CodeGen/AArch64/cgp-usubo.ll +++ b/llvm/test/CodeGen/AArch64/cgp-usubo.ll @@ -108,11 +108,9 @@ define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) nounwind { define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) nounwind { ; CHECK-LABEL: usubo_eq_constant1_op1_i32: ; CHECK: // %bb.0: -; CHECK-NEXT: cmp w0, #0 -; CHECK-NEXT: sub w9, w0, #1 -; CHECK-NEXT: cset w8, eq -; CHECK-NEXT: str w9, [x1] -; CHECK-NEXT: mov w0, w8 +; CHECK-NEXT: subs w8, w0, #1 +; CHECK-NEXT: cset w0, lo +; CHECK-NEXT: str w8, [x1] ; CHECK-NEXT: ret %s = add i32 %x, -1 %ov = icmp eq i32 %x, 0 diff --git a/llvm/test/CodeGen/AArch64/cmpxchg-idioms.ll b/llvm/test/CodeGen/AArch64/cmpxchg-idioms.ll index b7817ebe59b9b..eb7c2151973ee 100644 --- a/llvm/test/CodeGen/AArch64/cmpxchg-idioms.ll +++ b/llvm/test/CodeGen/AArch64/cmpxchg-idioms.ll @@ -196,12 +196,12 @@ define i1 @test_conditional2(i32 %a, i32 %b, ptr %c) { ; CHECK-NEXT: mov w22, #2 ; =0x2 ; CHECK-NEXT: LBB3_6: ; %for.cond ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 -; CHECK-NEXT: cbz w22, LBB3_9 +; CHECK-NEXT: subs w22, w22, #1 +; CHECK-NEXT: b.lo LBB3_9 ; CHECK-NEXT: ; %bb.7: ; %for.body ; CHECK-NEXT: ; in Loop: Header=BB3_6 Depth=1 -; CHECK-NEXT: sub w22, w22, #1 -; CHECK-NEXT: orr w9, w21, w20 ; CHECK-NEXT: ldr w10, [x19, w22, sxtw #2] +; CHECK-NEXT: orr w9, w21, w20 ; CHECK-NEXT: cmp w9, w10 ; CHECK-NEXT: b.eq LBB3_6 ; CHECK-NEXT: ; %bb.8: ; %if.then @@ -238,12 +238,12 @@ define i1 @test_conditional2(i32 %a, i32 %b, ptr %c) { ; OUTLINE-ATOMICS-NEXT: cset w8, eq ; OUTLINE-ATOMICS-NEXT: LBB3_1: ; %for.cond ; OUTLINE-ATOMICS-NEXT: ; =>This Inner Loop Header: Depth=1 -; OUTLINE-ATOMICS-NEXT: cbz w22, LBB3_4 +; OUTLINE-ATOMICS-NEXT: subs w22, w22, #1 +; OUTLINE-ATOMICS-NEXT: b.lo LBB3_4 ; OUTLINE-ATOMICS-NEXT: ; %bb.2: ; %for.body ; OUTLINE-ATOMICS-NEXT: ; in Loop: Header=BB3_1 Depth=1 -; OUTLINE-ATOMICS-NEXT: sub w22, w22, #1 -; OUTLINE-ATOMICS-NEXT: orr w9, w21, w20 ; OUTLINE-ATOMICS-NEXT: ldr w10, [x19, w22, sxtw #2] +; OUTLINE-ATOMICS-NEXT: orr w9, w21, w20 ; OUTLINE-ATOMICS-NEXT: cmp w9, w10 ; OUTLINE-ATOMICS-NEXT: b.eq LBB3_1 ; OUTLINE-ATOMICS-NEXT: ; %bb.3: ; %if.then diff --git a/llvm/test/CodeGen/X86/lack-of-signed-truncation-check.ll b/llvm/test/CodeGen/X86/lack-of-signed-truncation-check.ll index 7bef94cca0d35..058e76f06c459 100644 --- a/llvm/test/CodeGen/X86/lack-of-signed-truncation-check.ll +++ b/llvm/test/CodeGen/X86/lack-of-signed-truncation-check.ll @@ -506,17 +506,15 @@ define i1 @add_ugecmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind { define i1 @add_ugecmp_bad_i8_i16(i16 %x) nounwind { ; X86-LABEL: add_ugecmp_bad_i8_i16: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: subl $-128, %eax -; X86-NEXT: cmpw $127, %ax -; X86-NEXT: seta %al +; X86-NEXT: movw $128, %ax +; X86-NEXT: addw {{[0-9]+}}(%esp), %ax +; X86-NEXT: setae %al ; X86-NEXT: retl ; ; X64-LABEL: add_ugecmp_bad_i8_i16: ; X64: # %bb.0: -; X64-NEXT: subl $-128, %edi -; X64-NEXT: cmpw $127, %di -; X64-NEXT: seta %al +; X64-NEXT: addw $128, %di +; X64-NEXT: setae %al ; X64-NEXT: retq %tmp0 = add i16 %x, 128 ; 1U << (8-1) %tmp1 = icmp uge i16 %tmp0, 128 ; 1U << (8-1) diff --git a/llvm/test/CodeGen/X86/setcc-combine.ll b/llvm/test/CodeGen/X86/setcc-combine.ll index f526db00df606..1f5f99b8d7075 100644 --- a/llvm/test/CodeGen/X86/setcc-combine.ll +++ b/llvm/test/CodeGen/X86/setcc-combine.ll @@ -664,8 +664,9 @@ define <4 x i32> @cmp_sge_not_with_vec(<4 x i32> %a, <4 x i32> %b) { define i64 @cmp_uge_not(i64 %a, i64 %b) { ; CHECK-LABEL: cmp_uge_not: ; CHECK: # %bb.0: +; CHECK-NEXT: notq %rsi ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpq %rdi, %rsi +; CHECK-NEXT: addq %rdi, %rsi ; CHECK-NEXT: adcq $-1, %rax ; CHECK-NEXT: retq %na = xor i64 %a, -1 @@ -679,8 +680,8 @@ define i64 @cmp_uge_not_with_constant(i64 %a) { ; CHECK-LABEL: cmp_uge_not_with_constant: ; CHECK: # %bb.0: ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpq $-42, %rdi -; CHECK-NEXT: sbbq %rax, %rax +; CHECK-NEXT: addq $42, %rdi +; CHECK-NEXT: adcq $-1, %rax ; CHECK-NEXT: retq %na = xor i64 %a, -1 %c = icmp uge i64 %na, 42 @@ -850,8 +851,9 @@ define <4 x i32> @cmp_ult_not_with_vec(<4 x i32> %a, <4 x i32> %b) { define i64 @cmp_ule_not(i64 %a, i64 %b) { ; CHECK-LABEL: cmp_ule_not: ; CHECK: # %bb.0: +; CHECK-NEXT: notq %rdi ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpq %rsi, %rdi +; CHECK-NEXT: addq %rsi, %rdi ; CHECK-NEXT: adcq $-1, %rax ; CHECK-NEXT: retq %na = xor i64 %a, -1 @@ -983,8 +985,9 @@ define <4 x i32> @cmp_ne_not_with_vec(<4 x i32> %a, <4 x i32> %b) { define i64 @cmp_uge_not_commute(i64 %b, i64 %a) { ; CHECK-LABEL: cmp_uge_not_commute: ; CHECK: # %bb.0: +; CHECK-NEXT: notq %rdi ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpq %rsi, %rdi +; CHECK-NEXT: addq %rsi, %rdi ; CHECK-NEXT: adcq $-1, %rax ; CHECK-NEXT: retq %na = xor i64 %a, -1 diff --git a/llvm/test/Transforms/CodeGenPrepare/AArch64/overflow-intrinsics.ll b/llvm/test/Transforms/CodeGenPrepare/AArch64/overflow-intrinsics.ll index f228f3da9c128..2b76df898a3aa 100644 --- a/llvm/test/Transforms/CodeGenPrepare/AArch64/overflow-intrinsics.ll +++ b/llvm/test/Transforms/CodeGenPrepare/AArch64/overflow-intrinsics.ll @@ -237,17 +237,21 @@ define i64 @uaddo6_xor_multi_use(i64 %a, i64 %b) { define i64 @uaddo1_overflow_used_neg(i64 %a, i64 %b) nounwind ssp { ; CHECK-LABEL: @uaddo1_overflow_used_neg( -; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[A]] -; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CMP]], true +; CHECK-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] ; ; DEBUG-LABEL: @uaddo1_overflow_used_neg( -; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG99:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META96:![0-9]+]], !DIExpression(), [[DBG99]]) -; DEBUG-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[A]], !dbg [[DBG100:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META97:![0-9]+]], !DIExpression(), [[DBG100]]) -; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG101:![0-9]+]] +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG99:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG99]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG99]] +; DEBUG-NEXT: [[NOT:%.*]] = xor i1 [[OV]], true, !dbg [[DBG99]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META96:![0-9]+]], !DIExpression(), [[DBG99]]) +; DEBUG-NEXT: #dbg_value(i1 [[NOT]], [[META97:![0-9]+]], !DIExpression(), [[META100:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42, !dbg [[DBG101:![0-9]+]] ; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META98:![0-9]+]], !DIExpression(), [[DBG101]]) ; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG102:![0-9]+]] ; @@ -259,20 +263,24 @@ define i64 @uaddo1_overflow_used_neg(i64 %a, i64 %b) nounwind ssp { define i64 @uaddo1_math_overflow_used_neg(i64 %a, i64 %b, ptr %res) nounwind ssp { ; CHECK-LABEL: @uaddo1_math_overflow_used_neg( -; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[A]] -; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) +; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CMP]], true +; CHECK-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42 ; CHECK-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8 ; CHECK-NEXT: ret i64 [[Q]] ; ; DEBUG-LABEL: @uaddo1_math_overflow_used_neg( -; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG108:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META105:![0-9]+]], !DIExpression(), [[DBG108]]) -; DEBUG-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[A]], !dbg [[DBG109:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META106:![0-9]+]], !DIExpression(), [[DBG109]]) -; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG110:![0-9]+]] +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG108:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG108]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG108]] +; DEBUG-NEXT: [[NOT:%.*]] = xor i1 [[OV]], true, !dbg [[DBG108]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META105:![0-9]+]], !DIExpression(), [[DBG108]]) +; DEBUG-NEXT: #dbg_value(i1 [[NOT]], [[META106:![0-9]+]], !DIExpression(), [[META109:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42, !dbg [[DBG110:![0-9]+]] ; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META107:![0-9]+]], !DIExpression(), [[DBG110]]) -; DEBUG-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8, !dbg [[DBG111:![0-9]+]] +; DEBUG-NEXT: store i64 [[MATH]], ptr [[RES:%.*]], align 8, !dbg [[DBG111:![0-9]+]] ; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG112:![0-9]+]] ; %add = add i64 %b, %a @@ -284,17 +292,21 @@ define i64 @uaddo1_math_overflow_used_neg(i64 %a, i64 %b, ptr %res) nounwind ssp define i64 @uaddo2_overflow_used_neg(i64 %a, i64 %b) nounwind ssp { ; CHECK-LABEL: @uaddo2_overflow_used_neg( -; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[B]] -; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CMP]], true +; CHECK-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] ; ; DEBUG-LABEL: @uaddo2_overflow_used_neg( -; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG118:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META115:![0-9]+]], !DIExpression(), [[DBG118]]) -; DEBUG-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[B]], !dbg [[DBG119:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META116:![0-9]+]], !DIExpression(), [[DBG119]]) -; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG120:![0-9]+]] +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG118:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG118]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG118]] +; DEBUG-NEXT: [[NOT:%.*]] = xor i1 [[OV]], true, !dbg [[DBG118]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META115:![0-9]+]], !DIExpression(), [[DBG118]]) +; DEBUG-NEXT: #dbg_value(i1 [[NOT]], [[META116:![0-9]+]], !DIExpression(), [[META119:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42, !dbg [[DBG120:![0-9]+]] ; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META117:![0-9]+]], !DIExpression(), [[DBG120]]) ; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG121:![0-9]+]] ; @@ -306,20 +318,24 @@ define i64 @uaddo2_overflow_used_neg(i64 %a, i64 %b) nounwind ssp { define i64 @uaddo2_math_overflow_used_neg(i64 %a, i64 %b, ptr %res) nounwind ssp { ; CHECK-LABEL: @uaddo2_math_overflow_used_neg( -; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[B]] -; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) +; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CMP]], true +; CHECK-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42 ; CHECK-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8 ; CHECK-NEXT: ret i64 [[Q]] ; ; DEBUG-LABEL: @uaddo2_math_overflow_used_neg( -; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG127:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META124:![0-9]+]], !DIExpression(), [[DBG127]]) -; DEBUG-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], [[B]], !dbg [[DBG128:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META125:![0-9]+]], !DIExpression(), [[DBG128]]) -; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG129:![0-9]+]] +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG127:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG127]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG127]] +; DEBUG-NEXT: [[NOT:%.*]] = xor i1 [[OV]], true, !dbg [[DBG127]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META124:![0-9]+]], !DIExpression(), [[DBG127]]) +; DEBUG-NEXT: #dbg_value(i1 [[NOT]], [[META125:![0-9]+]], !DIExpression(), [[META128:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42, !dbg [[DBG129:![0-9]+]] ; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META126:![0-9]+]], !DIExpression(), [[DBG129]]) -; DEBUG-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8, !dbg [[DBG130:![0-9]+]] +; DEBUG-NEXT: store i64 [[MATH]], ptr [[RES:%.*]], align 8, !dbg [[DBG130:![0-9]+]] ; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG131:![0-9]+]] ; %add = add i64 %b, %a @@ -331,17 +347,21 @@ define i64 @uaddo2_math_overflow_used_neg(i64 %a, i64 %b, ptr %res) nounwind ssp define i64 @uaddo3_overflow_used_neg(i64 %a, i64 %b) nounwind ssp { ; CHECK-LABEL: @uaddo3_overflow_used_neg( -; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[B]], [[ADD]] -; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CMP]], true +; CHECK-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] ; ; DEBUG-LABEL: @uaddo3_overflow_used_neg( -; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG137:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META134:![0-9]+]], !DIExpression(), [[DBG137]]) -; DEBUG-NEXT: [[CMP:%.*]] = icmp ule i64 [[B]], [[ADD]], !dbg [[DBG138:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META135:![0-9]+]], !DIExpression(), [[DBG138]]) -; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG139:![0-9]+]] +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG137:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG137]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG137]] +; DEBUG-NEXT: [[NOT:%.*]] = xor i1 [[OV]], true, !dbg [[DBG137]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META134:![0-9]+]], !DIExpression(), [[DBG137]]) +; DEBUG-NEXT: #dbg_value(i1 [[NOT]], [[META135:![0-9]+]], !DIExpression(), [[META138:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42, !dbg [[DBG139:![0-9]+]] ; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META136:![0-9]+]], !DIExpression(), [[DBG139]]) ; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG140:![0-9]+]] ; @@ -353,20 +373,24 @@ define i64 @uaddo3_overflow_used_neg(i64 %a, i64 %b) nounwind ssp { define i64 @uaddo3_math_overflow_used_neg(i64 %a, i64 %b, ptr %res) nounwind ssp { ; CHECK-LABEL: @uaddo3_math_overflow_used_neg( -; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[B]], [[ADD]] -; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]) +; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CMP]], true +; CHECK-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42 ; CHECK-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8 ; CHECK-NEXT: ret i64 [[Q]] ; ; DEBUG-LABEL: @uaddo3_math_overflow_used_neg( -; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG146:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META143:![0-9]+]], !DIExpression(), [[DBG146]]) -; DEBUG-NEXT: [[CMP:%.*]] = icmp ule i64 [[B]], [[ADD]], !dbg [[DBG147:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META144:![0-9]+]], !DIExpression(), [[DBG147]]) -; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG148:![0-9]+]] +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG146:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG146]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG146]] +; DEBUG-NEXT: [[NOT:%.*]] = xor i1 [[OV]], true, !dbg [[DBG146]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META143:![0-9]+]], !DIExpression(), [[DBG146]]) +; DEBUG-NEXT: #dbg_value(i1 [[NOT]], [[META144:![0-9]+]], !DIExpression(), [[META147:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42, !dbg [[DBG148:![0-9]+]] ; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META145:![0-9]+]], !DIExpression(), [[DBG148]]) -; DEBUG-NEXT: store i64 [[ADD]], ptr [[RES:%.*]], align 8, !dbg [[DBG149:![0-9]+]] +; DEBUG-NEXT: store i64 [[MATH]], ptr [[RES:%.*]], align 8, !dbg [[DBG149:![0-9]+]] ; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG150:![0-9]+]] ; %add = add i64 %b, %a @@ -380,17 +404,19 @@ define i64 @uaddo3_math_overflow_used_neg(i64 %a, i64 %b, ptr %res) nounwind ssp ; pattern as well. define i64 @uaddo6_xor_neg(i64 %a, i64 %b) { ; CHECK-LABEL: @uaddo6_xor_neg( -; CHECK-NEXT: [[X:%.*]] = xor i64 [[A:%.*]], -1 -; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[X]], [[B:%.*]] -; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CMP]], true +; CHECK-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] ; ; DEBUG-LABEL: @uaddo6_xor_neg( -; DEBUG-NEXT: [[X:%.*]] = xor i64 [[A:%.*]], -1, !dbg [[DBG156:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i64 [[X]], [[META153:![0-9]+]], !DIExpression(), [[DBG156]]) -; DEBUG-NEXT: [[CMP:%.*]] = icmp uge i64 [[X]], [[B:%.*]], !dbg [[DBG157:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META154:![0-9]+]], !DIExpression(), [[DBG157]]) -; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG158:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 poison, [[META153:![0-9]+]], !DIExpression(), [[META156:![0-9]+]]) +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]), !dbg [[DBG157:![0-9]+]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG157]] +; DEBUG-NEXT: [[NOT:%.*]] = xor i1 [[OV]], true, !dbg [[DBG157]] +; DEBUG-NEXT: #dbg_value(i1 [[NOT]], [[META154:![0-9]+]], !DIExpression(), [[DBG157]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42, !dbg [[DBG158:![0-9]+]] ; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META155:![0-9]+]], !DIExpression(), [[DBG158]]) ; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG159:![0-9]+]] ; @@ -402,17 +428,19 @@ define i64 @uaddo6_xor_neg(i64 %a, i64 %b) { define i64 @uaddo6_xor_commuted_neg(i64 %a, i64 %b) { ; CHECK-LABEL: @uaddo6_xor_commuted_neg( -; CHECK-NEXT: [[X:%.*]] = xor i64 [[A:%.*]], -1 -; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[B:%.*]], [[X]] -; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CMP]], true +; CHECK-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] ; ; DEBUG-LABEL: @uaddo6_xor_commuted_neg( -; DEBUG-NEXT: [[X:%.*]] = xor i64 [[A:%.*]], -1, !dbg [[DBG165:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i64 [[X]], [[META162:![0-9]+]], !DIExpression(), [[DBG165]]) -; DEBUG-NEXT: [[CMP:%.*]] = icmp ule i64 [[B:%.*]], [[X]], !dbg [[DBG166:![0-9]+]] -; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META163:![0-9]+]], !DIExpression(), [[DBG166]]) -; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG167:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 poison, [[META162:![0-9]+]], !DIExpression(), [[META165:![0-9]+]]) +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]), !dbg [[DBG166:![0-9]+]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG166]] +; DEBUG-NEXT: [[NOT:%.*]] = xor i1 [[OV]], true, !dbg [[DBG166]] +; DEBUG-NEXT: #dbg_value(i1 [[NOT]], [[META163:![0-9]+]], !DIExpression(), [[DBG166]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[NOT]], i64 [[B]], i64 42, !dbg [[DBG167:![0-9]+]] ; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META164:![0-9]+]], !DIExpression(), [[DBG167]]) ; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG168:![0-9]+]] ; diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll b/llvm/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll index aaf3df0934681..49f30b077954c 100644 --- a/llvm/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll +++ b/llvm/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll @@ -15,11 +15,12 @@ define i1 @PR41004(i32 %x, i32 %y, i32 %t1) { ; CHECK-NEXT: br label [[SELECT_END]] ; CHECK: select.end: ; CHECK-NEXT: [[MUL:%.*]] = phi i32 [ [[REM]], [[SELECT_TRUE_SINK]] ], [ 0, [[ENTRY:%.*]] ] -; CHECK-NEXT: [[USUB:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[T1:%.*]], i32 1) +; CHECK-NEXT: [[USUB:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1:%.*]], i32 -1) ; CHECK-NEXT: [[NEG:%.*]] = extractvalue { i32, i1 } [[USUB]], 0 ; CHECK-NEXT: [[TOBOOL:%.*]] = extractvalue { i32, i1 } [[USUB]], 1 +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TOBOOL]], true ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[NEG]], [[MUL]] -; CHECK-NEXT: ret i1 [[TOBOOL]] +; CHECK-NEXT: ret i1 [[NOT]] ; entry: %rem = srem i32 %x, 2 diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll b/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll index 653f346356488..db15bef7ed231 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 @@ -457,11 +730,22 @@ define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) { define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) { ; CHECK-LABEL: @usubo_eq_constant1_op1_i32( -; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 1) +; 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: ret i1 [[OV1]] +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[OV1]], true +; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4 +; CHECK-NEXT: ret i1 [[NOT]] +; +; DEBUG-LABEL: @usubo_eq_constant1_op1_i32( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.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: [[NOT:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG261]] +; DEBUG-NEXT: #dbg_value(i32 [[MATH]], [[META259:![0-9]+]], !DIExpression(), [[DBG261]]) +; DEBUG-NEXT: #dbg_value(i1 [[NOT]], [[META260:![0-9]+]], !DIExpression(), [[META262:![0-9]+]]) +; DEBUG-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4, !dbg [[DBG263:![0-9]+]] +; DEBUG-NEXT: ret i1 [[NOT]], !dbg [[DBG264:![0-9]+]] ; %s = add i32 %x, -1 %ov = icmp eq i32 %x, 0 @@ -476,8 +760,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 +788,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 +796,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 +841,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 +886,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 +904,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 +923,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 +937,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 +958,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