[llvm] Optimize ADC folding when flags are used (PR #218299)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 23 16:44:50 PDT 2026
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/218299
>From 584d6ca4a44773d2538dd994934f0c817611579b Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sun, 23 Aug 2026 19:35:42 -0400
Subject: [PATCH 1/2] Precommit test for ADC folding
---
llvm/test/CodeGen/X86/combine-adc.ll | 38 ++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/llvm/test/CodeGen/X86/combine-adc.ll b/llvm/test/CodeGen/X86/combine-adc.ll
index cb934c8664e45..7922a6b2d2a6e 100644
--- a/llvm/test/CodeGen/X86/combine-adc.ll
+++ b/llvm/test/CodeGen/X86/combine-adc.ll
@@ -251,3 +251,41 @@ define i32 @adc_add_multi_use(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, ptr %5) no
declare { i8, i32 } @llvm.x86.addcarry.32(i8, i32, i32)
declare void @use(i8)
+
+define i32 @adc_fold_with_used_flag(i32 %a0) nounwind {
+; X86-LABEL: adc_fold_with_used_flag:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: btl $11, {{[0-9]+}}(%esp)
+; X86-NEXT: movl $55, %esi
+; X86-NEXT: adcl $45, %esi
+; X86-NEXT: setb %al
+; X86-NEXT: movzbl %al, %eax
+; X86-NEXT: pushl %eax
+; X86-NEXT: calll use at PLT
+; X86-NEXT: addl $4, %esp
+; X86-NEXT: movl %esi, %eax
+; X86-NEXT: popl %esi
+; X86-NEXT: retl
+;
+; X64-LABEL: adc_fold_with_used_flag:
+; X64: # %bb.0:
+; X64-NEXT: pushq %rbx
+; X64-NEXT: btl $11, %edi
+; X64-NEXT: movl $55, %ebx
+; X64-NEXT: adcl $45, %ebx
+; X64-NEXT: setb %al
+; X64-NEXT: movzbl %al, %edi
+; X64-NEXT: callq use at PLT
+; X64-NEXT: movl %ebx, %eax
+; X64-NEXT: popq %rbx
+; X64-NEXT: retq
+ %bit = lshr i32 %a0, 11
+ %mask = and i32 %bit, 1
+ %isz = trunc i32 %mask to i8
+ %adc = tail call { i8, i32 } @llvm.x86.addcarry.32(i8 %isz, i32 55, i32 45)
+ %carry = extractvalue { i8, i32 } %adc, 0
+ call void @use(i8 %carry)
+ %sum = extractvalue { i8, i32 } %adc, 1
+ ret i32 %sum
+}
>From e799d691497440d40a468dae47326b764c81a59e Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sun, 23 Aug 2026 19:37:00 -0400
Subject: [PATCH 2/2] Optimize ADC folding when flags are used
This PR improves the constant folding of the ADC (Add with Carry) node in the X86 backend.
Specifically, it extends the ADC(C1, C2, Carry) -> ADC(0, C1+C2, Carry) fold. Previously, this optimization only fired if the resulting flags from the ADC were strictly dead (i.e., not used by any subsequent node).
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 24 ++++++++++++++++--------
llvm/test/CodeGen/X86/combine-adc.ll | 8 ++++----
2 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index bf435b0c2f849..f4d5c22d14114 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -59692,14 +59692,22 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
}
// Fold ADC(C1,C2,Carry) -> ADC(0,C1+C2,Carry)
- // iff the flag result is dead.
- // TODO: Allow flag result if C1+C2 doesn't signed/unsigned overflow.
- if (LHSC && RHSC && !LHSC->isZero() && !N->hasAnyUseOfValue(1)) {
- SDLoc DL(N);
- APInt Sum = LHSC->getAPIntValue() + RHSC->getAPIntValue();
- return DAG.getNode(X86ISD::ADC, DL, N->getVTList(),
- DAG.getConstant(0, DL, LHS.getValueType()),
- DAG.getConstant(Sum, DL, LHS.getValueType()), CarryIn);
+ // iff the flag result is dead or C1+C2 doesn't signed/unsigned overflow.
+ if (LHSC && RHSC && !LHSC->isZero()) {
+ bool UOF;
+ APInt Sum = LHSC->getAPIntValue().uadd_ov(RHSC->getAPIntValue(), UOF);
+
+ if (!N->hasAnyUseOfValue(1) || !UOF) {
+ bool SOF;
+ (void)LHSC->getAPIntValue().sadd_ov(RHSC->getAPIntValue(), SOF);
+ if (!SOF) {
+ SDLoc DL(N);
+ return DAG.getNode(X86ISD::ADC, DL, N->getVTList(),
+ DAG.getConstant(0, DL, LHS.getValueType()),
+ DAG.getConstant(Sum, DL, LHS.getValueType()),
+ CarryIn);
+ }
+ }
}
if (SDValue Flags = combineCarryThroughADD(CarryIn, DAG)) {
diff --git a/llvm/test/CodeGen/X86/combine-adc.ll b/llvm/test/CodeGen/X86/combine-adc.ll
index 7922a6b2d2a6e..f3aa3cb2d79db 100644
--- a/llvm/test/CodeGen/X86/combine-adc.ll
+++ b/llvm/test/CodeGen/X86/combine-adc.ll
@@ -256,9 +256,9 @@ define i32 @adc_fold_with_used_flag(i32 %a0) nounwind {
; X86-LABEL: adc_fold_with_used_flag:
; X86: # %bb.0:
; X86-NEXT: pushl %esi
+; X86-NEXT: xorl %esi, %esi
; X86-NEXT: btl $11, {{[0-9]+}}(%esp)
-; X86-NEXT: movl $55, %esi
-; X86-NEXT: adcl $45, %esi
+; X86-NEXT: adcl $100, %esi
; X86-NEXT: setb %al
; X86-NEXT: movzbl %al, %eax
; X86-NEXT: pushl %eax
@@ -271,9 +271,9 @@ define i32 @adc_fold_with_used_flag(i32 %a0) nounwind {
; X64-LABEL: adc_fold_with_used_flag:
; X64: # %bb.0:
; X64-NEXT: pushq %rbx
+; X64-NEXT: xorl %ebx, %ebx
; X64-NEXT: btl $11, %edi
-; X64-NEXT: movl $55, %ebx
-; X64-NEXT: adcl $45, %ebx
+; X64-NEXT: adcl $100, %ebx
; X64-NEXT: setb %al
; X64-NEXT: movzbl %al, %edi
; X64-NEXT: callq use at PLT
More information about the llvm-commits
mailing list