[llvm] [X86] Fold ADC(SHL(X, 1), 0, Carry) to ADC(X, X, Carry) (PR #219512)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 28 09:15:29 PDT 2026


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

During DAG optimization, expressions like `a + a` are canonicalized to `a << 1` (`ISD::SHL X, 1`).

We need to undo that if we can use adc x, x.

>From b0474e5f63353518dee7b7eaeb46a193414aada6 Mon Sep 17 00:00:00 2001
From: AZero13 <83477269+AZero13 at users.noreply.github.com>
Date: Fri, 28 Aug 2026 12:15:07 -0400
Subject: [PATCH] [X86] Fold ADC(SHL(X, 1), 0, Carry) to ADC(X, X, Carry)

During DAG optimization, expressions like `a + a` are canonicalized to `a << 1` (`ISD::SHL X, 1`).

We need to undo that if we can use adc x, x.
---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 8 ++++++++
 llvm/test/CodeGen/X86/combine-adc.ll    | 8 +++-----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a37012133e431..6ffc191dee259 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -59814,6 +59814,14 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
     return DAG.getNode(X86ISD::ADC, SDLoc(N), N->getVTList(), LHS.getOperand(0),
                        LHS.getOperand(1), CarryIn);
 
+  // Fold ADC(SHL(X,1),0,Carry) -> ADC(X,X,Carry)
+  // iff the flag result is dead.
+  if (LHS.getOpcode() == ISD::SHL && isOneConstant(LHS.getOperand(1)) &&
+      RHSC && RHSC->isZero() &&
+      !needCarryOrOverflowFlag(SDValue(N, 1)))
+    return DAG.getNode(X86ISD::ADC, SDLoc(N), N->getVTList(), LHS.getOperand(0),
+                       LHS.getOperand(0), CarryIn);
+
   return SDValue();
 }
 
diff --git a/llvm/test/CodeGen/X86/combine-adc.ll b/llvm/test/CodeGen/X86/combine-adc.ll
index 0487c4483f22d..fa6c9a0828ff3 100644
--- a/llvm/test/CodeGen/X86/combine-adc.ll
+++ b/llvm/test/CodeGen/X86/combine-adc.ll
@@ -254,17 +254,15 @@ define i32 @adc_shl(i32 %a, i32 %b) {
 ; X86-LABEL: adc_shl:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl %eax, %eax
 ; X86-NEXT:    cmpl $70, {{[0-9]+}}(%esp)
-; X86-NEXT:    adcl $0, %eax
+; X86-NEXT:    adcl %eax, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: adc_shl:
 ; X64:       # %bb.0:
-; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal (%rdi,%rdi), %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    cmpl $70, %esi
-; X64-NEXT:    adcl $0, %eax
+; X64-NEXT:    adcl %edi, %eax
 ; X64-NEXT:    retq
   %add = shl i32 %a, 1
   %cmp = icmp ult i32 %b, 70



More information about the llvm-commits mailing list