[llvm] Optimize ADC folding when flags are used (PR #218299)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 06:42:28 PDT 2026
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/218299
>From 15785d7ba6fb3fe2f5ca689405b0c54646e81d66 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 5647f04df571d68bfb5064a75fb055ecef015747 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 a0c92a22b7e2f..5749e6e5c60df 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -59704,14 +59704,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