[llvm] [X86] Optimized ADD + ADC to ADC (PR #173543)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 11 05:29:56 PDT 2026


https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/173543

>From a0c98459b7022a6a3a0d8ab78485b863718fdc55 Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Thu, 25 Dec 2025 03:13:39 -0800
Subject: [PATCH 01/13] [X86] Optimized ADD + ADC to ADC

---
 llvm/lib/Target/X86/X86ISelLowering.cpp |  7 ++++++
 llvm/test/CodeGen/X86/combine-adc.ll    | 30 +++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 811ffb090d751..fd6e7da196d2f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58164,6 +58164,13 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
     }
   }
 
+  // Fold ADD(ADC(Y,0,CF), C) -> ADC(Y, C, CF)
+  if (!IsSub && LHS.getOpcode() == X86ISD::ADC &&
+      X86::isZeroNode(LHS.getOperand(1)) && isa<ConstantSDNode>(RHS)) {
+    return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0), RHS,
+                       LHS.getOperand(2));
+  }
+
   // TODO: Can we drop the ZeroSecondOpOnly limit? This is to guarantee that the
   // EFLAGS result doesn't change.
   return combineAddOrSubToADCOrSBB(IsSub, DL, VT, LHS, RHS, DAG,
diff --git a/llvm/test/CodeGen/X86/combine-adc.ll b/llvm/test/CodeGen/X86/combine-adc.ll
index a2aaea31aa6ff..03e60c10cec4b 100644
--- a/llvm/test/CodeGen/X86/combine-adc.ll
+++ b/llvm/test/CodeGen/X86/combine-adc.ll
@@ -136,5 +136,35 @@ define i32 @adc_merge_sub(i32 %a0) nounwind {
   ret i32 %result
 }
 
+define i32 @optimize_adc(i32 %0, i32 %1, i32 %2) {
+; X86-LABEL: optimize_adc:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    cmpl %eax, %ecx
+; X86-NEXT:    adcl $42, %edx
+; X86-NEXT:    js .LBB4_2
+; X86-NEXT:  # %bb.1:
+; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:  .LBB4_2:
+; X86-NEXT:    retl
+;
+; X64-LABEL: optimize_adc:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    cmpl %esi, %edi
+; X64-NEXT:    adcl $42, %edx
+; X64-NEXT:    cmovsl %esi, %eax
+; X64-NEXT:    retq
+  %4 = icmp ult i32 %0, %1
+  %5 = zext i1 %4 to i32
+  %6 = add i32 %2, 42
+  %7 = add i32 %6, %5
+  %8 = icmp slt i32 %7, 0
+  %9 = select i1 %8, i32 %1, i32 %0
+  ret i32 %9
+}
+
 declare { i8, i32 } @llvm.x86.addcarry.32(i8, i32, i32)
 declare void @use(i8)

>From 2a48efdf81c08e77d5c65e5c72bf3212549f073d Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Thu, 25 Dec 2025 06:10:04 -0800
Subject: [PATCH 02/13] Addressed the review comments

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index fd6e7da196d2f..861f1ee4d80b8 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58164,11 +58164,14 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
     }
   }
 
-  // Fold ADD(ADC(Y,0,CF), C) -> ADC(Y, C, CF)
+  // Fold ADD(ADC(Y, C1, CF), C2) -> ADC(Y, C1 + C2, CF)
   if (!IsSub && LHS.getOpcode() == X86ISD::ADC &&
-      X86::isZeroNode(LHS.getOperand(1)) && isa<ConstantSDNode>(RHS)) {
-    return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0), RHS,
-                       LHS.getOperand(2));
+      isa<ConstantSDNode>(LHS.getOperand(1)) && isa<ConstantSDNode>(RHS)) {
+    auto *C1 = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
+    auto *C2 = dyn_cast<ConstantSDNode>(RHS);
+    APInt Sum = C1->getAPIntValue() + C2->getAPIntValue();
+    return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0),
+                       DAG.getConstant(Sum, DL, VT), LHS.getOperand(2));
   }
 
   // TODO: Can we drop the ZeroSecondOpOnly limit? This is to guarantee that the

>From 63acd38d6a40c9f49636ca3ad6fe16e3d0869b4c Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Wed, 31 Dec 2025 10:39:13 -0800
Subject: [PATCH 03/13] Addressed the review comments1

---
 llvm/lib/Target/X86/X86ISelLowering.cpp |  6 ++---
 llvm/test/CodeGen/X86/combine-adc.ll    | 36 ++++++++++++++++++++++---
 2 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 8a5a3cb16193b..841f39bb4d8b9 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58166,7 +58166,8 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
 
   // Fold ADD(ADC(Y, C1, CF), C2) -> ADC(Y, C1 + C2, CF)
   if (!IsSub && LHS.getOpcode() == X86ISD::ADC &&
-      isa<ConstantSDNode>(LHS.getOperand(1)) && isa<ConstantSDNode>(RHS)) {
+      isa<ConstantSDNode>(LHS.getOperand(1)) && isa<ConstantSDNode>(RHS) &&
+      !needCarryOrOverflowFlag(SDValue(N, 1))) {
     auto *C1 = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
     auto *C2 = dyn_cast<ConstantSDNode>(RHS);
     APInt Sum = C1->getAPIntValue() + C2->getAPIntValue();
@@ -58252,8 +58253,7 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
 
   // Fold ADC(ADD(X,Y),0,Carry) -> ADC(X,Y,Carry)
   // iff the flag result is dead.
-  if (LHS.getOpcode() == ISD::ADD && RHSC && RHSC->isZero() &&
-      !N->hasAnyUseOfValue(1))
+  if (LHS.getOpcode() == ISD::ADD && RHSC && RHSC->isZero())
     return DAG.getNode(X86ISD::ADC, SDLoc(N), N->getVTList(), LHS.getOperand(0),
                        LHS.getOperand(1), CarryIn);
 
diff --git a/llvm/test/CodeGen/X86/combine-adc.ll b/llvm/test/CodeGen/X86/combine-adc.ll
index 03e60c10cec4b..75023f1afeae9 100644
--- a/llvm/test/CodeGen/X86/combine-adc.ll
+++ b/llvm/test/CodeGen/X86/combine-adc.ll
@@ -136,8 +136,8 @@ define i32 @adc_merge_sub(i32 %a0) nounwind {
   ret i32 %result
 }
 
-define i32 @optimize_adc(i32 %0, i32 %1, i32 %2) {
-; X86-LABEL: optimize_adc:
+define i32 @optimize_adc_test1(i32 %0, i32 %1, i32 %2) {
+; X86-LABEL: optimize_adc_test1:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -150,7 +150,7 @@ define i32 @optimize_adc(i32 %0, i32 %1, i32 %2) {
 ; X86-NEXT:  .LBB4_2:
 ; X86-NEXT:    retl
 ;
-; X64-LABEL: optimize_adc:
+; X64-LABEL: optimize_adc_test1:
 ; X64:       # %bb.0:
 ; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    cmpl %esi, %edi
@@ -166,5 +166,35 @@ define i32 @optimize_adc(i32 %0, i32 %1, i32 %2) {
   ret i32 %9
 }
 
+define i32 @optimize_adc_test2(i32 %0, i32 %1, i32 %2) {
+; X86-LABEL: optimize_adc_test2:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    cmpl %eax, %ecx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT:    adcl %ecx, %edx
+; X86-NEXT:    js .LBB5_2
+; X86-NEXT:  # %bb.1:
+; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:  .LBB5_2:
+; X86-NEXT:    retl
+;
+; X64-LABEL: optimize_adc_test2:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    cmpl %esi, %edi
+; X64-NEXT:    adcl %edi, %edx
+; X64-NEXT:    cmovsl %esi, %eax
+; X64-NEXT:    retq
+  %4 = icmp ult i32 %0, %1
+  %5 = zext i1 %4 to i32
+  %6 = add i32 %2, %0
+  %7 = add i32 %6, %5
+  %8 = icmp slt i32 %7, 0
+  %9 = select i1 %8, i32 %1, i32 %0
+  ret i32 %9
+}
+
 declare { i8, i32 } @llvm.x86.addcarry.32(i8, i32, i32)
 declare void @use(i8)

>From 426e49924134e22ba1002d73cc3d1f650397a38f Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Thu, 1 Jan 2026 01:43:31 -0800
Subject: [PATCH 04/13] Updated dyn_cast to cast

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 841f39bb4d8b9..6dfd34245911d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58168,8 +58168,8 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
   if (!IsSub && LHS.getOpcode() == X86ISD::ADC &&
       isa<ConstantSDNode>(LHS.getOperand(1)) && isa<ConstantSDNode>(RHS) &&
       !needCarryOrOverflowFlag(SDValue(N, 1))) {
-    auto *C1 = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
-    auto *C2 = dyn_cast<ConstantSDNode>(RHS);
+    auto *C1 = cast<ConstantSDNode>(LHS.getOperand(1));
+    auto *C2 = cast<ConstantSDNode>(RHS);
     APInt Sum = C1->getAPIntValue() + C2->getAPIntValue();
     return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0),
                        DAG.getConstant(Sum, DL, VT), LHS.getOperand(2));

>From fc8e192b242f2b3a1ef57a6ade73689571086ab1 Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Fri, 2 Jan 2026 08:25:09 -0800
Subject: [PATCH 05/13] Addressed the review comments2

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  2 +-
 llvm/test/CodeGen/X86/add-sub-bool.ll         | 53 ++++++++++++-------
 llvm/test/CodeGen/X86/addcarry.ll             | 12 +++--
 llvm/test/CodeGen/X86/apx/adc.ll              | 52 ++++++++++++------
 .../X86/large-code-model-sext-small-symbol.ll |  3 +-
 5 files changed, 81 insertions(+), 41 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index f23b7f49fe668..a890d9a420925 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58252,7 +58252,7 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
 
   // Fold ADC(ADD(X,Y),0,Carry) -> ADC(X,Y,Carry)
   // iff the flag result is dead.
-  if (LHS.getOpcode() == ISD::ADD && RHSC && RHSC->isZero())
+  if (LHS.getOpcode() == ISD::ADD && RHSC && RHSC->isZero() && !needCarryOrOverflowFlag(SDValue(N, 1)))
     return DAG.getNode(X86ISD::ADC, SDLoc(N), N->getVTList(), LHS.getOperand(0),
                        LHS.getOperand(1), CarryIn);
 
diff --git a/llvm/test/CodeGen/X86/add-sub-bool.ll b/llvm/test/CodeGen/X86/add-sub-bool.ll
index 1df284fb9fe2c..e42c5fa42b95c 100644
--- a/llvm/test/CodeGen/X86/add-sub-bool.ll
+++ b/llvm/test/CodeGen/X86/add-sub-bool.ll
@@ -18,15 +18,18 @@ define i32 @test_i32_add_add_idx(i32 %x, i32 %y, i32 %z) nounwind {
 ; X86-LABEL: test_i32_add_add_idx:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl $30, {{[0-9]+}}(%esp)
-; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    adcl $0, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i32_add_add_idx:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    # kill: def $esi killed $esi def $rsi
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
+; X64-NEXT:    leal (%rdi,%rsi), %eax
 ; X64-NEXT:    btl $30, %edx
-; X64-NEXT:    adcl %esi, %eax
+; X64-NEXT:    adcl $0, %eax
 ; X64-NEXT:    retq
   %add = add i32 %y, %x
   %shift = lshr i32 %z, 30
@@ -39,15 +42,18 @@ define i32 @test_i32_add_add_commute_idx(i32 %x, i32 %y, i32 %z) nounwind {
 ; X86-LABEL: test_i32_add_add_commute_idx:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl $2, {{[0-9]+}}(%esp)
-; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    adcl $0, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i32_add_add_commute_idx:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    # kill: def $esi killed $esi def $rsi
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
+; X64-NEXT:    leal (%rdi,%rsi), %eax
 ; X64-NEXT:    btl $2, %edx
-; X64-NEXT:    adcl %esi, %eax
+; X64-NEXT:    adcl $0, %eax
 ; X64-NEXT:    retq
   %add = add i32 %y, %x
   %shift = lshr i32 %z, 2
@@ -84,15 +90,18 @@ define i24 @test_i24_add_add_idx(i24 %x, i24 %y, i24 %z) nounwind {
 ; X86-LABEL: test_i24_add_add_idx:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl $15, {{[0-9]+}}(%esp)
-; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    adcl $0, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i24_add_add_idx:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    # kill: def $esi killed $esi def $rsi
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
+; X64-NEXT:    leal (%rdi,%rsi), %eax
 ; X64-NEXT:    btl $15, %edx
-; X64-NEXT:    adcl %esi, %eax
+; X64-NEXT:    adcl $0, %eax
 ; X64-NEXT:    retq
   %add = add i24 %y, %x
   %shift = lshr i24 %z, 15
@@ -346,18 +355,21 @@ define i32 @test_i32_sub_sum_idx(i32 %x, i32 %y, i32 %z) nounwind {
 define i32 @test_i32_add_add_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwind {
 ; X86-LABEL: test_i32_add_add_var:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl %ecx, %edx
-; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    adcl $0, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i32_add_add_var:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    # kill: def $esi killed $esi def $rsi
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
+; X64-NEXT:    leal (%rdi,%rsi), %eax
 ; X64-NEXT:    btl %ecx, %edx
-; X64-NEXT:    adcl %esi, %eax
+; X64-NEXT:    adcl $0, %eax
 ; X64-NEXT:    retq
   %add = add i32 %y, %x
   %shift = lshr i32 %z, %w
@@ -369,18 +381,21 @@ define i32 @test_i32_add_add_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwind {
 define i32 @test_i32_add_add_commute_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwind {
 ; X86-LABEL: test_i32_add_add_commute_var:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl %ecx, %edx
-; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    adcl $0, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i32_add_add_commute_var:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    # kill: def $esi killed $esi def $rsi
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
+; X64-NEXT:    leal (%rdi,%rsi), %eax
 ; X64-NEXT:    btl %ecx, %edx
-; X64-NEXT:    adcl %esi, %eax
+; X64-NEXT:    adcl $0, %eax
 ; X64-NEXT:    retq
   %add = add i32 %y, %x
   %shift = lshr i32 %z, %w
@@ -420,9 +435,9 @@ define i64 @test_i64_add_add_var(i64 %x, i64 %y, i64 %z, i64 %w) nounwind {
 ;
 ; X64-LABEL: test_i64_add_add_var:
 ; X64:       # %bb.0:
-; X64-NEXT:    movq %rdi, %rax
+; X64-NEXT:    leaq (%rdi,%rsi), %rax
 ; X64-NEXT:    btq %rcx, %rdx
-; X64-NEXT:    adcq %rsi, %rax
+; X64-NEXT:    adcq $0, %rax
 ; X64-NEXT:    retq
   %add = add i64 %y, %x
   %shift = lshr i64 %z, %w
diff --git a/llvm/test/CodeGen/X86/addcarry.ll b/llvm/test/CodeGen/X86/addcarry.ll
index ee4482062df31..f44fd6a0ab553 100644
--- a/llvm/test/CodeGen/X86/addcarry.ll
+++ b/llvm/test/CodeGen/X86/addcarry.ll
@@ -1382,9 +1382,11 @@ define void @add_U256_without_i128_or_recursive(ptr sret(%uint256) %0, ptr %1, p
 define i32 @addcarry_ult(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: addcarry_ult:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
+; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
+; CHECK-NEXT:    leal (%rdi,%rsi), %eax
 ; CHECK-NEXT:    cmpl %ecx, %edx
-; CHECK-NEXT:    adcl %esi, %eax
+; CHECK-NEXT:    adcl $0, %eax
 ; CHECK-NEXT:    retq
   %s = add i32 %a, %b
   %k = icmp ult i32 %x, %y
@@ -1396,9 +1398,11 @@ define i32 @addcarry_ult(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 define i32 @addcarry_ugt(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: addcarry_ugt:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
+; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
+; CHECK-NEXT:    leal (%rdi,%rsi), %eax
 ; CHECK-NEXT:    cmpl %edx, %ecx
-; CHECK-NEXT:    adcl %esi, %eax
+; CHECK-NEXT:    adcl $0, %eax
 ; CHECK-NEXT:    retq
   %s = add i32 %a, %b
   %k = icmp ugt i32 %x, %y
diff --git a/llvm/test/CodeGen/X86/apx/adc.ll b/llvm/test/CodeGen/X86/apx/adc.ll
index ec9800ddc69ae..f40c4c0d7c601 100644
--- a/llvm/test/CodeGen/X86/apx/adc.ll
+++ b/llvm/test/CodeGen/X86/apx/adc.ll
@@ -4,8 +4,9 @@
 define i8 @adc8rr(i8 %a, i8 %b, i8 %x, i8 %y) nounwind {
 ; CHECK-LABEL: adc8rr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addb %sil, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x00,0xf7]
 ; CHECK-NEXT:    cmpb %dl, %cl # encoding: [0x38,0xd1]
-; CHECK-NEXT:    adcb %sil, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x10,0xf7]
+; CHECK-NEXT:    adcb $0, %al # EVEX TO LEGACY Compression encoding: [0x14,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %s = add i8 %a, %b
   %k = icmp ugt i8 %x, %y
@@ -17,8 +18,9 @@ define i8 @adc8rr(i8 %a, i8 %b, i8 %x, i8 %y) nounwind {
 define i16 @adc16rr(i16 %a, i16 %b, i16 %x, i16 %y) nounwind {
 ; CHECK-LABEL: adc16rr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addw %si, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x01,0xf7]
 ; CHECK-NEXT:    cmpw %dx, %cx # encoding: [0x66,0x39,0xd1]
-; CHECK-NEXT:    adcw %si, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x11,0xf7]
+; CHECK-NEXT:    adcw $0, %ax # EVEX TO LEGACY Compression encoding: [0x66,0x83,0xd0,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %s = add i16 %a, %b
   %k = icmp ugt i16 %x, %y
@@ -30,8 +32,9 @@ define i16 @adc16rr(i16 %a, i16 %b, i16 %x, i16 %y) nounwind {
 define i32 @adc32rr(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: adc32rr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    leal (%rdi,%rsi), %eax # encoding: [0x8d,0x04,0x37]
 ; CHECK-NEXT:    cmpl %edx, %ecx # encoding: [0x39,0xd1]
-; CHECK-NEXT:    adcl %esi, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x11,0xf7]
+; CHECK-NEXT:    adcl $0, %eax # EVEX TO LEGACY Compression encoding: [0x83,0xd0,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %s = add i32 %a, %b
   %k = icmp ugt i32 %x, %y
@@ -43,8 +46,9 @@ define i32 @adc32rr(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 define i64 @adc64rr(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: adc64rr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    leaq (%rdi,%rsi), %rax # encoding: [0x48,0x8d,0x04,0x37]
 ; CHECK-NEXT:    cmpq %rdx, %rcx # encoding: [0x48,0x39,0xd1]
-; CHECK-NEXT:    adcq %rsi, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x11,0xf7]
+; CHECK-NEXT:    adcq $0, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xd0,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %s = add i64 %a, %b
   %k = icmp ugt i64 %x, %y
@@ -56,8 +60,9 @@ define i64 @adc64rr(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
 define i8 @adc8rm(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 ; CHECK-LABEL: adc8rm:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x02,0x3e]
 ; CHECK-NEXT:    cmpb %dl, %cl # encoding: [0x38,0xd1]
-; CHECK-NEXT:    adcb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x12,0x3e]
+; CHECK-NEXT:    adcb $0, %al # EVEX TO LEGACY Compression encoding: [0x14,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i8, ptr %ptr
   %s = add i8 %a, %b
@@ -70,8 +75,9 @@ define i8 @adc8rm(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 define i16 @adc16rm(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 ; CHECK-LABEL: adc16rm:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpw %dx, %cx # encoding: [0x66,0x39,0xd1]
-; CHECK-NEXT:    adcw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x13,0x3e]
+; CHECK-NEXT:    adcw $0, %ax # EVEX TO LEGACY Compression encoding: [0x66,0x83,0xd0,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i16, ptr %ptr
   %s = add i16 %a, %b
@@ -84,8 +90,9 @@ define i16 @adc16rm(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 define i32 @adc32rm(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: adc32rm:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addl (%rsi), %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpl %edx, %ecx # encoding: [0x39,0xd1]
-; CHECK-NEXT:    adcl (%rsi), %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x13,0x3e]
+; CHECK-NEXT:    adcl $0, %eax # EVEX TO LEGACY Compression encoding: [0x83,0xd0,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i32, ptr %ptr
   %s = add i32 %a, %b
@@ -98,8 +105,9 @@ define i32 @adc32rm(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 define i64 @adc64rm(i64 %a, ptr %ptr, i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: adc64rm:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addq (%rsi), %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpq %rdx, %rcx # encoding: [0x48,0x39,0xd1]
-; CHECK-NEXT:    adcq (%rsi), %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x13,0x3e]
+; CHECK-NEXT:    adcq $0, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xd0,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i64, ptr %ptr
   %s = add i64 %a, %b
@@ -206,8 +214,9 @@ define i64 @adc64ri(i64 %a, i64 %x, i64 %y) nounwind {
 define i8 @adc8mr(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 ; CHECK-LABEL: adc8mr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x02,0x3e]
 ; CHECK-NEXT:    cmpb %dl, %cl # encoding: [0x38,0xd1]
-; CHECK-NEXT:    adcb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x12,0x3e]
+; CHECK-NEXT:    adcb $0, %al # EVEX TO LEGACY Compression encoding: [0x14,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i8, ptr %ptr
   %s = add i8 %b, %a
@@ -220,8 +229,9 @@ define i8 @adc8mr(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 define i16 @adc16mr(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 ; CHECK-LABEL: adc16mr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpw %dx, %cx # encoding: [0x66,0x39,0xd1]
-; CHECK-NEXT:    adcw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x13,0x3e]
+; CHECK-NEXT:    adcw $0, %ax # EVEX TO LEGACY Compression encoding: [0x66,0x83,0xd0,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i16, ptr %ptr
   %s = add i16 %b, %a
@@ -234,8 +244,9 @@ define i16 @adc16mr(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 define i32 @adc32mr(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: adc32mr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addl (%rsi), %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpl %edx, %ecx # encoding: [0x39,0xd1]
-; CHECK-NEXT:    adcl (%rsi), %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x13,0x3e]
+; CHECK-NEXT:    adcl $0, %eax # EVEX TO LEGACY Compression encoding: [0x83,0xd0,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i32, ptr %ptr
   %s = add i32 %b, %a
@@ -248,8 +259,9 @@ define i32 @adc32mr(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 define i64 @adc64mr(i64 %a, ptr %ptr, i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: adc64mr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addq (%rsi), %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpq %rdx, %rcx # encoding: [0x48,0x39,0xd1]
-; CHECK-NEXT:    adcq (%rsi), %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x13,0x3e]
+; CHECK-NEXT:    adcq $0, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xd0,0x00]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i64, ptr %ptr
   %s = add i64 %b, %a
@@ -363,8 +375,10 @@ define i64 @adc64mi(ptr %ptr, i64 %x, i64 %y) nounwind {
 define void @adc8mr_legacy(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 ; CHECK-LABEL: adc8mr_legacy:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x02,0x3e]
 ; CHECK-NEXT:    cmpb %dl, %cl # encoding: [0x38,0xd1]
-; CHECK-NEXT:    adcb %dil, (%rsi) # encoding: [0x40,0x10,0x3e]
+; CHECK-NEXT:    adcb $0, %al # EVEX TO LEGACY Compression encoding: [0x14,0x00]
+; CHECK-NEXT:    movb %al, (%rsi) # encoding: [0x88,0x06]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i8, ptr %ptr
   %s = add i8 %b, %a
@@ -378,8 +392,10 @@ define void @adc8mr_legacy(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 define void @adc16mr_legacy(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 ; CHECK-LABEL: adc16mr_legacy:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpw %dx, %cx # encoding: [0x66,0x39,0xd1]
-; CHECK-NEXT:    adcw %di, (%rsi) # encoding: [0x66,0x11,0x3e]
+; CHECK-NEXT:    adcw $0, %ax # EVEX TO LEGACY Compression encoding: [0x66,0x83,0xd0,0x00]
+; CHECK-NEXT:    movw %ax, (%rsi) # encoding: [0x66,0x89,0x06]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i16, ptr %ptr
   %s = add i16 %b, %a
@@ -393,8 +409,10 @@ define void @adc16mr_legacy(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 define void @adc32mr_legacy(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: adc32mr_legacy:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addl (%rsi), %edi # EVEX TO LEGACY Compression encoding: [0x03,0x3e]
 ; CHECK-NEXT:    cmpl %edx, %ecx # encoding: [0x39,0xd1]
-; CHECK-NEXT:    adcl %edi, (%rsi) # encoding: [0x11,0x3e]
+; CHECK-NEXT:    adcl $0, %edi # EVEX TO LEGACY Compression encoding: [0x83,0xd7,0x00]
+; CHECK-NEXT:    movl %edi, (%rsi) # encoding: [0x89,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i32, ptr %ptr
   %s = add i32 %b, %a
@@ -408,8 +426,10 @@ define void @adc32mr_legacy(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 define void @adc64mr_legacy(i64 %a, ptr %ptr, i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: adc64mr_legacy:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    addq (%rsi), %rdi # EVEX TO LEGACY Compression encoding: [0x48,0x03,0x3e]
 ; CHECK-NEXT:    cmpq %rdx, %rcx # encoding: [0x48,0x39,0xd1]
-; CHECK-NEXT:    adcq %rdi, (%rsi) # encoding: [0x48,0x11,0x3e]
+; CHECK-NEXT:    adcq $0, %rdi # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xd7,0x00]
+; CHECK-NEXT:    movq %rdi, (%rsi) # encoding: [0x48,0x89,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i64, ptr %ptr
   %s = add i64 %b, %a
diff --git a/llvm/test/CodeGen/X86/large-code-model-sext-small-symbol.ll b/llvm/test/CodeGen/X86/large-code-model-sext-small-symbol.ll
index 0a4b3d3cff903..d3d9737f24c86 100644
--- a/llvm/test/CodeGen/X86/large-code-model-sext-small-symbol.ll
+++ b/llvm/test/CodeGen/X86/large-code-model-sext-small-symbol.ll
@@ -17,8 +17,9 @@ define ptr @f(i64 %0) {
 ; CHECK-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L0$pb, %rcx
 ; CHECK-NEXT:    addq %rax, %rcx
 ; CHECK-NEXT:    movabsq $g at GOTOFF, %rax
+; CHECK-NEXT:    addq %rcx, %rax
 ; CHECK-NEXT:    cmpq $1, %rdi
-; CHECK-NEXT:    adcq %rcx, %rax
+; CHECK-NEXT:    adcq $0, %rax
 ; CHECK-NEXT:    retq
   %2 = icmp eq i64 %0, 0
   %3 = zext i1 %2 to i64

>From b459a1fee24f98817337a7bb523d4653ef76cace Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Fri, 2 Jan 2026 08:27:17 -0800
Subject: [PATCH 06/13] Fixed formatting issue

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a890d9a420925..fbbcea2756952 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58252,7 +58252,8 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
 
   // Fold ADC(ADD(X,Y),0,Carry) -> ADC(X,Y,Carry)
   // iff the flag result is dead.
-  if (LHS.getOpcode() == ISD::ADD && RHSC && RHSC->isZero() && !needCarryOrOverflowFlag(SDValue(N, 1)))
+  if (LHS.getOpcode() == ISD::ADD && RHSC && RHSC->isZero() &&
+      !needCarryOrOverflowFlag(SDValue(N, 1)))
     return DAG.getNode(X86ISD::ADC, SDLoc(N), N->getVTList(), LHS.getOperand(0),
                        LHS.getOperand(1), CarryIn);
 

>From e451e86f704a8f3240c7aec48c485078983d18f2 Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Sat, 3 Jan 2026 00:07:43 -0800
Subject: [PATCH 07/13] Addressed the review comments3

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  5 +-
 llvm/test/CodeGen/X86/add-sub-bool.ll         | 53 +++++++------------
 llvm/test/CodeGen/X86/addcarry.ll             | 12 ++---
 llvm/test/CodeGen/X86/apx/adc.ll              | 52 ++++++------------
 .../X86/large-code-model-sext-small-symbol.ll |  3 +-
 5 files changed, 44 insertions(+), 81 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index fbbcea2756952..986f70deee760 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -57898,7 +57898,10 @@ static SDValue combineFunnelShift(SDNode *N, SelectionDAG &DAG,
 static bool needCarryOrOverflowFlag(SDValue Flags) {
   assert(Flags.getValueType() == MVT::i32 && "Unexpected VT!");
 
-  for (const SDNode *User : Flags->users()) {
+  for (const SDUse &Use : Flags->uses()) {
+    if (Use != Flags)
+      continue;
+    const SDNode *User = Use.getUser();
     X86::CondCode CC;
     switch (User->getOpcode()) {
     default:
diff --git a/llvm/test/CodeGen/X86/add-sub-bool.ll b/llvm/test/CodeGen/X86/add-sub-bool.ll
index e42c5fa42b95c..1df284fb9fe2c 100644
--- a/llvm/test/CodeGen/X86/add-sub-bool.ll
+++ b/llvm/test/CodeGen/X86/add-sub-bool.ll
@@ -18,18 +18,15 @@ define i32 @test_i32_add_add_idx(i32 %x, i32 %y, i32 %z) nounwind {
 ; X86-LABEL: test_i32_add_add_idx:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl $30, {{[0-9]+}}(%esp)
-; X86-NEXT:    adcl $0, %eax
+; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i32_add_add_idx:
 ; X64:       # %bb.0:
-; X64-NEXT:    # kill: def $esi killed $esi def $rsi
-; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal (%rdi,%rsi), %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    btl $30, %edx
-; X64-NEXT:    adcl $0, %eax
+; X64-NEXT:    adcl %esi, %eax
 ; X64-NEXT:    retq
   %add = add i32 %y, %x
   %shift = lshr i32 %z, 30
@@ -42,18 +39,15 @@ define i32 @test_i32_add_add_commute_idx(i32 %x, i32 %y, i32 %z) nounwind {
 ; X86-LABEL: test_i32_add_add_commute_idx:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl $2, {{[0-9]+}}(%esp)
-; X86-NEXT:    adcl $0, %eax
+; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i32_add_add_commute_idx:
 ; X64:       # %bb.0:
-; X64-NEXT:    # kill: def $esi killed $esi def $rsi
-; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal (%rdi,%rsi), %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    btl $2, %edx
-; X64-NEXT:    adcl $0, %eax
+; X64-NEXT:    adcl %esi, %eax
 ; X64-NEXT:    retq
   %add = add i32 %y, %x
   %shift = lshr i32 %z, 2
@@ -90,18 +84,15 @@ define i24 @test_i24_add_add_idx(i24 %x, i24 %y, i24 %z) nounwind {
 ; X86-LABEL: test_i24_add_add_idx:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl $15, {{[0-9]+}}(%esp)
-; X86-NEXT:    adcl $0, %eax
+; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i24_add_add_idx:
 ; X64:       # %bb.0:
-; X64-NEXT:    # kill: def $esi killed $esi def $rsi
-; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal (%rdi,%rsi), %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    btl $15, %edx
-; X64-NEXT:    adcl $0, %eax
+; X64-NEXT:    adcl %esi, %eax
 ; X64-NEXT:    retq
   %add = add i24 %y, %x
   %shift = lshr i24 %z, 15
@@ -355,21 +346,18 @@ define i32 @test_i32_sub_sum_idx(i32 %x, i32 %y, i32 %z) nounwind {
 define i32 @test_i32_add_add_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwind {
 ; X86-LABEL: test_i32_add_add_var:
 ; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl %ecx, %edx
-; X86-NEXT:    adcl $0, %eax
+; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i32_add_add_var:
 ; X64:       # %bb.0:
-; X64-NEXT:    # kill: def $esi killed $esi def $rsi
-; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal (%rdi,%rsi), %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    btl %ecx, %edx
-; X64-NEXT:    adcl $0, %eax
+; X64-NEXT:    adcl %esi, %eax
 ; X64-NEXT:    retq
   %add = add i32 %y, %x
   %shift = lshr i32 %z, %w
@@ -381,21 +369,18 @@ define i32 @test_i32_add_add_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwind {
 define i32 @test_i32_add_add_commute_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwind {
 ; X86-LABEL: test_i32_add_add_commute_var:
 ; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    btl %ecx, %edx
-; X86-NEXT:    adcl $0, %eax
+; X86-NEXT:    adcl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_i32_add_add_commute_var:
 ; X64:       # %bb.0:
-; X64-NEXT:    # kill: def $esi killed $esi def $rsi
-; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal (%rdi,%rsi), %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    btl %ecx, %edx
-; X64-NEXT:    adcl $0, %eax
+; X64-NEXT:    adcl %esi, %eax
 ; X64-NEXT:    retq
   %add = add i32 %y, %x
   %shift = lshr i32 %z, %w
@@ -435,9 +420,9 @@ define i64 @test_i64_add_add_var(i64 %x, i64 %y, i64 %z, i64 %w) nounwind {
 ;
 ; X64-LABEL: test_i64_add_add_var:
 ; X64:       # %bb.0:
-; X64-NEXT:    leaq (%rdi,%rsi), %rax
+; X64-NEXT:    movq %rdi, %rax
 ; X64-NEXT:    btq %rcx, %rdx
-; X64-NEXT:    adcq $0, %rax
+; X64-NEXT:    adcq %rsi, %rax
 ; X64-NEXT:    retq
   %add = add i64 %y, %x
   %shift = lshr i64 %z, %w
diff --git a/llvm/test/CodeGen/X86/addcarry.ll b/llvm/test/CodeGen/X86/addcarry.ll
index f44fd6a0ab553..ee4482062df31 100644
--- a/llvm/test/CodeGen/X86/addcarry.ll
+++ b/llvm/test/CodeGen/X86/addcarry.ll
@@ -1382,11 +1382,9 @@ define void @add_U256_without_i128_or_recursive(ptr sret(%uint256) %0, ptr %1, p
 define i32 @addcarry_ult(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: addcarry_ult:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
-; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
-; CHECK-NEXT:    leal (%rdi,%rsi), %eax
+; CHECK-NEXT:    movl %edi, %eax
 ; CHECK-NEXT:    cmpl %ecx, %edx
-; CHECK-NEXT:    adcl $0, %eax
+; CHECK-NEXT:    adcl %esi, %eax
 ; CHECK-NEXT:    retq
   %s = add i32 %a, %b
   %k = icmp ult i32 %x, %y
@@ -1398,11 +1396,9 @@ define i32 @addcarry_ult(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 define i32 @addcarry_ugt(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: addcarry_ugt:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
-; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
-; CHECK-NEXT:    leal (%rdi,%rsi), %eax
+; CHECK-NEXT:    movl %edi, %eax
 ; CHECK-NEXT:    cmpl %edx, %ecx
-; CHECK-NEXT:    adcl $0, %eax
+; CHECK-NEXT:    adcl %esi, %eax
 ; CHECK-NEXT:    retq
   %s = add i32 %a, %b
   %k = icmp ugt i32 %x, %y
diff --git a/llvm/test/CodeGen/X86/apx/adc.ll b/llvm/test/CodeGen/X86/apx/adc.ll
index f40c4c0d7c601..ec9800ddc69ae 100644
--- a/llvm/test/CodeGen/X86/apx/adc.ll
+++ b/llvm/test/CodeGen/X86/apx/adc.ll
@@ -4,9 +4,8 @@
 define i8 @adc8rr(i8 %a, i8 %b, i8 %x, i8 %y) nounwind {
 ; CHECK-LABEL: adc8rr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addb %sil, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x00,0xf7]
 ; CHECK-NEXT:    cmpb %dl, %cl # encoding: [0x38,0xd1]
-; CHECK-NEXT:    adcb $0, %al # EVEX TO LEGACY Compression encoding: [0x14,0x00]
+; CHECK-NEXT:    adcb %sil, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x10,0xf7]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %s = add i8 %a, %b
   %k = icmp ugt i8 %x, %y
@@ -18,9 +17,8 @@ define i8 @adc8rr(i8 %a, i8 %b, i8 %x, i8 %y) nounwind {
 define i16 @adc16rr(i16 %a, i16 %b, i16 %x, i16 %y) nounwind {
 ; CHECK-LABEL: adc16rr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addw %si, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x01,0xf7]
 ; CHECK-NEXT:    cmpw %dx, %cx # encoding: [0x66,0x39,0xd1]
-; CHECK-NEXT:    adcw $0, %ax # EVEX TO LEGACY Compression encoding: [0x66,0x83,0xd0,0x00]
+; CHECK-NEXT:    adcw %si, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x11,0xf7]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %s = add i16 %a, %b
   %k = icmp ugt i16 %x, %y
@@ -32,9 +30,8 @@ define i16 @adc16rr(i16 %a, i16 %b, i16 %x, i16 %y) nounwind {
 define i32 @adc32rr(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: adc32rr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    leal (%rdi,%rsi), %eax # encoding: [0x8d,0x04,0x37]
 ; CHECK-NEXT:    cmpl %edx, %ecx # encoding: [0x39,0xd1]
-; CHECK-NEXT:    adcl $0, %eax # EVEX TO LEGACY Compression encoding: [0x83,0xd0,0x00]
+; CHECK-NEXT:    adcl %esi, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x11,0xf7]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %s = add i32 %a, %b
   %k = icmp ugt i32 %x, %y
@@ -46,9 +43,8 @@ define i32 @adc32rr(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
 define i64 @adc64rr(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: adc64rr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    leaq (%rdi,%rsi), %rax # encoding: [0x48,0x8d,0x04,0x37]
 ; CHECK-NEXT:    cmpq %rdx, %rcx # encoding: [0x48,0x39,0xd1]
-; CHECK-NEXT:    adcq $0, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xd0,0x00]
+; CHECK-NEXT:    adcq %rsi, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x11,0xf7]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %s = add i64 %a, %b
   %k = icmp ugt i64 %x, %y
@@ -60,9 +56,8 @@ define i64 @adc64rr(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
 define i8 @adc8rm(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 ; CHECK-LABEL: adc8rm:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x02,0x3e]
 ; CHECK-NEXT:    cmpb %dl, %cl # encoding: [0x38,0xd1]
-; CHECK-NEXT:    adcb $0, %al # EVEX TO LEGACY Compression encoding: [0x14,0x00]
+; CHECK-NEXT:    adcb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x12,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i8, ptr %ptr
   %s = add i8 %a, %b
@@ -75,9 +70,8 @@ define i8 @adc8rm(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 define i16 @adc16rm(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 ; CHECK-LABEL: adc16rm:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpw %dx, %cx # encoding: [0x66,0x39,0xd1]
-; CHECK-NEXT:    adcw $0, %ax # EVEX TO LEGACY Compression encoding: [0x66,0x83,0xd0,0x00]
+; CHECK-NEXT:    adcw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x13,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i16, ptr %ptr
   %s = add i16 %a, %b
@@ -90,9 +84,8 @@ define i16 @adc16rm(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 define i32 @adc32rm(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: adc32rm:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addl (%rsi), %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpl %edx, %ecx # encoding: [0x39,0xd1]
-; CHECK-NEXT:    adcl $0, %eax # EVEX TO LEGACY Compression encoding: [0x83,0xd0,0x00]
+; CHECK-NEXT:    adcl (%rsi), %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x13,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i32, ptr %ptr
   %s = add i32 %a, %b
@@ -105,9 +98,8 @@ define i32 @adc32rm(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 define i64 @adc64rm(i64 %a, ptr %ptr, i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: adc64rm:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addq (%rsi), %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpq %rdx, %rcx # encoding: [0x48,0x39,0xd1]
-; CHECK-NEXT:    adcq $0, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xd0,0x00]
+; CHECK-NEXT:    adcq (%rsi), %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x13,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i64, ptr %ptr
   %s = add i64 %a, %b
@@ -214,9 +206,8 @@ define i64 @adc64ri(i64 %a, i64 %x, i64 %y) nounwind {
 define i8 @adc8mr(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 ; CHECK-LABEL: adc8mr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x02,0x3e]
 ; CHECK-NEXT:    cmpb %dl, %cl # encoding: [0x38,0xd1]
-; CHECK-NEXT:    adcb $0, %al # EVEX TO LEGACY Compression encoding: [0x14,0x00]
+; CHECK-NEXT:    adcb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x12,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i8, ptr %ptr
   %s = add i8 %b, %a
@@ -229,9 +220,8 @@ define i8 @adc8mr(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 define i16 @adc16mr(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 ; CHECK-LABEL: adc16mr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpw %dx, %cx # encoding: [0x66,0x39,0xd1]
-; CHECK-NEXT:    adcw $0, %ax # EVEX TO LEGACY Compression encoding: [0x66,0x83,0xd0,0x00]
+; CHECK-NEXT:    adcw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x13,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i16, ptr %ptr
   %s = add i16 %b, %a
@@ -244,9 +234,8 @@ define i16 @adc16mr(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 define i32 @adc32mr(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: adc32mr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addl (%rsi), %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpl %edx, %ecx # encoding: [0x39,0xd1]
-; CHECK-NEXT:    adcl $0, %eax # EVEX TO LEGACY Compression encoding: [0x83,0xd0,0x00]
+; CHECK-NEXT:    adcl (%rsi), %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x13,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i32, ptr %ptr
   %s = add i32 %b, %a
@@ -259,9 +248,8 @@ define i32 @adc32mr(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 define i64 @adc64mr(i64 %a, ptr %ptr, i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: adc64mr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addq (%rsi), %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpq %rdx, %rcx # encoding: [0x48,0x39,0xd1]
-; CHECK-NEXT:    adcq $0, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xd0,0x00]
+; CHECK-NEXT:    adcq (%rsi), %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x13,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i64, ptr %ptr
   %s = add i64 %b, %a
@@ -375,10 +363,8 @@ define i64 @adc64mi(ptr %ptr, i64 %x, i64 %y) nounwind {
 define void @adc8mr_legacy(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 ; CHECK-LABEL: adc8mr_legacy:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addb (%rsi), %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x02,0x3e]
 ; CHECK-NEXT:    cmpb %dl, %cl # encoding: [0x38,0xd1]
-; CHECK-NEXT:    adcb $0, %al # EVEX TO LEGACY Compression encoding: [0x14,0x00]
-; CHECK-NEXT:    movb %al, (%rsi) # encoding: [0x88,0x06]
+; CHECK-NEXT:    adcb %dil, (%rsi) # encoding: [0x40,0x10,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i8, ptr %ptr
   %s = add i8 %b, %a
@@ -392,10 +378,8 @@ define void @adc8mr_legacy(i8 %a, ptr %ptr, i8 %x, i8 %y) nounwind {
 define void @adc16mr_legacy(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 ; CHECK-LABEL: adc16mr_legacy:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addw (%rsi), %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x03,0x3e]
 ; CHECK-NEXT:    cmpw %dx, %cx # encoding: [0x66,0x39,0xd1]
-; CHECK-NEXT:    adcw $0, %ax # EVEX TO LEGACY Compression encoding: [0x66,0x83,0xd0,0x00]
-; CHECK-NEXT:    movw %ax, (%rsi) # encoding: [0x66,0x89,0x06]
+; CHECK-NEXT:    adcw %di, (%rsi) # encoding: [0x66,0x11,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i16, ptr %ptr
   %s = add i16 %b, %a
@@ -409,10 +393,8 @@ define void @adc16mr_legacy(i16 %a, ptr %ptr, i16 %x, i16 %y) nounwind {
 define void @adc32mr_legacy(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: adc32mr_legacy:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addl (%rsi), %edi # EVEX TO LEGACY Compression encoding: [0x03,0x3e]
 ; CHECK-NEXT:    cmpl %edx, %ecx # encoding: [0x39,0xd1]
-; CHECK-NEXT:    adcl $0, %edi # EVEX TO LEGACY Compression encoding: [0x83,0xd7,0x00]
-; CHECK-NEXT:    movl %edi, (%rsi) # encoding: [0x89,0x3e]
+; CHECK-NEXT:    adcl %edi, (%rsi) # encoding: [0x11,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i32, ptr %ptr
   %s = add i32 %b, %a
@@ -426,10 +408,8 @@ define void @adc32mr_legacy(i32 %a, ptr %ptr, i32 %x, i32 %y) nounwind {
 define void @adc64mr_legacy(i64 %a, ptr %ptr, i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: adc64mr_legacy:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    addq (%rsi), %rdi # EVEX TO LEGACY Compression encoding: [0x48,0x03,0x3e]
 ; CHECK-NEXT:    cmpq %rdx, %rcx # encoding: [0x48,0x39,0xd1]
-; CHECK-NEXT:    adcq $0, %rdi # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xd7,0x00]
-; CHECK-NEXT:    movq %rdi, (%rsi) # encoding: [0x48,0x89,0x3e]
+; CHECK-NEXT:    adcq %rdi, (%rsi) # encoding: [0x48,0x11,0x3e]
 ; CHECK-NEXT:    retq # encoding: [0xc3]
   %b = load i64, ptr %ptr
   %s = add i64 %b, %a
diff --git a/llvm/test/CodeGen/X86/large-code-model-sext-small-symbol.ll b/llvm/test/CodeGen/X86/large-code-model-sext-small-symbol.ll
index d3d9737f24c86..0a4b3d3cff903 100644
--- a/llvm/test/CodeGen/X86/large-code-model-sext-small-symbol.ll
+++ b/llvm/test/CodeGen/X86/large-code-model-sext-small-symbol.ll
@@ -17,9 +17,8 @@ define ptr @f(i64 %0) {
 ; CHECK-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L0$pb, %rcx
 ; CHECK-NEXT:    addq %rax, %rcx
 ; CHECK-NEXT:    movabsq $g at GOTOFF, %rax
-; CHECK-NEXT:    addq %rcx, %rax
 ; CHECK-NEXT:    cmpq $1, %rdi
-; CHECK-NEXT:    adcq $0, %rax
+; CHECK-NEXT:    adcq %rcx, %rax
 ; CHECK-NEXT:    retq
   %2 = icmp eq i64 %0, 0
   %3 = zext i1 %2 to i64

>From c9215c3c7ae30d2b7e243e64eb8417c8868ac2ab Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Wed, 11 Feb 2026 06:48:44 -0800
Subject: [PATCH 08/13] Added combine and updated testcase

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 11 +++++++++++
 llvm/test/CodeGen/X86/combine-add.ll    |  3 +--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 9c6cc95cc5eac..ed840f649037d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58807,6 +58807,17 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
     }
   }
 
+  // Fold ADD(ADC(Y, C1, CF), C2) -> ADC(Y, C1 + C2, CF)
+  if (!IsSub && LHS.getOpcode() == X86ISD::ADC && LHS.hasOneUse() &&
+      isa<ConstantSDNode>(LHS.getOperand(1)) && isa<ConstantSDNode>(RHS) &&
+      !needCarryOrOverflowFlag(SDValue(N, 1))) {
+    auto *C1 = cast<ConstantSDNode>(LHS.getOperand(1));
+    auto *C2 = cast<ConstantSDNode>(RHS);
+    APInt Sum = C1->getAPIntValue() + C2->getAPIntValue();
+    return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0),
+                       DAG.getConstant(Sum, DL, VT), LHS.getOperand(2));
+  }
+
   // TODO: Can we drop the ZeroSecondOpOnly limit? This is to guarantee that the
   // EFLAGS result doesn't change.
   return combineAddOrSubToADCOrSBB(IsSub, DL, VT, LHS, RHS, DAG,
diff --git a/llvm/test/CodeGen/X86/combine-add.ll b/llvm/test/CodeGen/X86/combine-add.ll
index b9e7a54075677..80ee046d74c62 100644
--- a/llvm/test/CodeGen/X86/combine-add.ll
+++ b/llvm/test/CodeGen/X86/combine-add.ll
@@ -568,8 +568,7 @@ define i32 @add_adc_to_adc(i32 %0, i32 %1, i32 %2) {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
 ; CHECK-NEXT:    cmpl %esi, %edi
-; CHECK-NEXT:    adcl $0, %edx
-; CHECK-NEXT:    addl $42, %edx
+; CHECK-NEXT:    adcl $42, %edx
 ; CHECK-NEXT:    cmovsl %esi, %eax
 ; CHECK-NEXT:    retq
   %4 = icmp ult i32 %0, %1

>From 16de72bf820f9a7dcc4d779f97ebcd747a0cedee Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Fri, 13 Feb 2026 07:12:18 -0800
Subject: [PATCH 09/13] Addressed the review comments3

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 16 ++++++++++------
 llvm/test/CodeGen/X86/combine-adc.ll    |  8 ++++----
 llvm/test/CodeGen/X86/combine-add.ll    | 24 +++++++++++++++++++++---
 3 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 7c48b33fba84b..d818f03a6c852 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58809,15 +58809,19 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
     }
   }
 
-  // Fold ADD(ADC(Y, C1, CF), C2) -> ADC(Y, C1 + C2, CF)
+  // Fold ADD(ADC(Y, A, CF), B) -> ADC(Y, ADD(A, B), CF)
   if (!IsSub && LHS.getOpcode() == X86ISD::ADC && LHS.hasOneUse() &&
-      isa<ConstantSDNode>(LHS.getOperand(1)) && isa<ConstantSDNode>(RHS) &&
       !needCarryOrOverflowFlag(SDValue(N, 1))) {
-    auto *C1 = cast<ConstantSDNode>(LHS.getOperand(1));
-    auto *C2 = cast<ConstantSDNode>(RHS);
-    APInt Sum = C1->getAPIntValue() + C2->getAPIntValue();
+    SDValue A = LHS.getOperand(1);
+    SDValue B = RHS;
+    EVT VT = A.getValueType();
+
+    if (B.getValueType() != VT)
+      return SDValue();
+
+    SDValue NewAdd = DAG.getNode(ISD::ADD, DL, VT, A, B);
     return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0),
-                       DAG.getConstant(Sum, DL, VT), LHS.getOperand(2));
+                       NewAdd, LHS.getOperand(2));
   }
 
   // TODO: Can we drop the ZeroSecondOpOnly limit? This is to guarantee that the
diff --git a/llvm/test/CodeGen/X86/combine-adc.ll b/llvm/test/CodeGen/X86/combine-adc.ll
index cb934c8664e45..98996ec3b9930 100644
--- a/llvm/test/CodeGen/X86/combine-adc.ll
+++ b/llvm/test/CodeGen/X86/combine-adc.ll
@@ -213,10 +213,10 @@ define i32 @adc_add_multi_use(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, ptr %5) no
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
 ; X86-NEXT:    leal (%edi,%esi), %ebx
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    cmpl %ecx, %eax
 ; X86-NEXT:    movl %ebx, (%edx)
-; X86-NEXT:    adcl %esi, %edi
-; X86-NEXT:    addl {{[0-9]+}}(%esp), %edi
+; X86-NEXT:    adcl %edi, %esi
 ; X86-NEXT:    js .LBB6_2
 ; X86-NEXT:  # %bb.1:
 ; X86-NEXT:    movl %ecx, %eax
@@ -232,10 +232,10 @@ define i32 @adc_add_multi_use(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, ptr %5) no
 ; X64-NEXT:    # kill: def $edx killed $edx def $rdx
 ; X64-NEXT:    movl %esi, %eax
 ; X64-NEXT:    leal (%rcx,%rdx), %esi
+; X64-NEXT:    addl %edx, %r8d
 ; X64-NEXT:    cmpl %eax, %edi
 ; X64-NEXT:    movl %esi, (%r9)
-; X64-NEXT:    adcl %edx, %ecx
-; X64-NEXT:    addl %r8d, %ecx
+; X64-NEXT:    adcl %ecx, %r8d
 ; X64-NEXT:    cmovsl %edi, %eax
 ; X64-NEXT:    retq
   %7 = icmp ult i32 %0, %1
diff --git a/llvm/test/CodeGen/X86/combine-add.ll b/llvm/test/CodeGen/X86/combine-add.ll
index 80ee046d74c62..5efc8cd111d1f 100644
--- a/llvm/test/CodeGen/X86/combine-add.ll
+++ b/llvm/test/CodeGen/X86/combine-add.ll
@@ -563,7 +563,7 @@ define i64 @add_notx_x(i64 %v0) nounwind {
 }
 
 ; Basic positive test
-define i32 @add_adc_to_adc(i32 %0, i32 %1, i32 %2) {
+define i32 @add_adc_to_adc(i32 %0, i32 %1, i32 %2) nounwind {
 ; CHECK-LABEL: add_adc_to_adc:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
@@ -580,8 +580,26 @@ define i32 @add_adc_to_adc(i32 %0, i32 %1, i32 %2) {
   ret i32 %9
 }
 
+; positive test: nonconst
+define i32 @add_adc_to_adc_nonconst(i32 %0, i32 %1, i32 %2, i32 %extra) nounwind {
+; CHECK-LABEL: add_adc_to_adc_nonconst:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    cmpl %esi, %edi
+; CHECK-NEXT:    adcl %ecx, %edx
+; CHECK-NEXT:    cmovsl %esi, %eax
+; CHECK-NEXT:    retq
+  %c = icmp ult i32 %0, %1
+  %carry = zext i1 %c to i32
+  %adc = add i32 %2, %carry
+  %final = add i32 %adc, %extra
+  %neg = icmp slt i32 %final, 0
+  %sel = select i1 %neg, i32 %1, i32 %0
+  ret i32 %sel
+}
+
 ; Negative test: Carry or overflow flag is used
-define i32 @add_adc_wrong_flags(i32 %0, i32 %1, i32 %2) {
+define i32 @add_adc_wrong_flags(i32 %0, i32 %1, i32 %2) nounwind {
 ; CHECK-LABEL: add_adc_wrong_flags:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %esi, %eax
@@ -601,7 +619,7 @@ define i32 @add_adc_wrong_flags(i32 %0, i32 %1, i32 %2) {
 }
 
 ; Negative test: Multi-use
-define i32 @add_adc_multi_use(i32 %0, i32 %1, i32 %2) {
+define i32 @add_adc_multi_use(i32 %0, i32 %1, i32 %2) nounwind {
 ; CHECK-LABEL: add_adc_multi_use:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    # kill: def $edx killed $edx def $rdx

>From a7db36bc6f919102e12a9bf4df92298637c4ba1a Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Sat, 28 Feb 2026 00:44:05 -0800
Subject: [PATCH 10/13] Addressed the review comments4

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 31 ++++++++++++++++++-------
 llvm/test/CodeGen/X86/combine-adc.ll    |  8 +++----
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index c3adae4287840..75ab829816056 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58896,19 +58896,32 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
     }
   }
 
-  // Fold ADD(ADC(Y, A, CF), B) -> ADC(Y, ADD(A, B), CF)
+  // Fold ADD(ADC(Y, C1, CF), C2) -> ADC(Y, C1 + C2, CF) and
+  //      ADD(ADC(Y, 0, CF), X) -> ADC(Y, X, CF) and
+  //      ADD(ADC(Y, X, CF), 0) -> ADC(Y, X, CF)
   if (!IsSub && LHS.getOpcode() == X86ISD::ADC && LHS.hasOneUse() &&
       !needCarryOrOverflowFlag(SDValue(N, 1))) {
-    SDValue A = LHS.getOperand(1);
-    SDValue B = RHS;
-    EVT VT = A.getValueType();
 
-    if (B.getValueType() != VT)
-      return SDValue();
+    auto *C1 = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
+    auto *C2 = dyn_cast<ConstantSDNode>(RHS);
+
+    // Both are constants: fold C1 + C2
+    if (C1 && C2) {
+      APInt Sum = C1->getAPIntValue() + C2->getAPIntValue();
+      return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0),
+                         DAG.getConstant(Sum, DL, VT), LHS.getOperand(2));
+    }
 
-    SDValue NewAdd = DAG.getNode(ISD::ADD, DL, VT, A, B);
-    return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0),
-                       NewAdd, LHS.getOperand(2));
+    // Case: ADC(Y, 0, CF) + X -> ADC(Y, X, CF)
+    if (C1 && C1->isZero()) {
+      return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0),
+                         RHS, LHS.getOperand(2));
+    }
+
+    // Case: ADC(Y, X, CF) + 0 -> ADC(Y, X, CF)
+    if (C2 && C2->isZero()) {
+      return LHS;
+    }
   }
 
   // TODO: Can we drop the ZeroSecondOpOnly limit? This is to guarantee that the
diff --git a/llvm/test/CodeGen/X86/combine-adc.ll b/llvm/test/CodeGen/X86/combine-adc.ll
index 98996ec3b9930..cb934c8664e45 100644
--- a/llvm/test/CodeGen/X86/combine-adc.ll
+++ b/llvm/test/CodeGen/X86/combine-adc.ll
@@ -213,10 +213,10 @@ define i32 @adc_add_multi_use(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, ptr %5) no
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
 ; X86-NEXT:    leal (%edi,%esi), %ebx
-; X86-NEXT:    addl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    cmpl %ecx, %eax
 ; X86-NEXT:    movl %ebx, (%edx)
-; X86-NEXT:    adcl %edi, %esi
+; X86-NEXT:    adcl %esi, %edi
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %edi
 ; X86-NEXT:    js .LBB6_2
 ; X86-NEXT:  # %bb.1:
 ; X86-NEXT:    movl %ecx, %eax
@@ -232,10 +232,10 @@ define i32 @adc_add_multi_use(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, ptr %5) no
 ; X64-NEXT:    # kill: def $edx killed $edx def $rdx
 ; X64-NEXT:    movl %esi, %eax
 ; X64-NEXT:    leal (%rcx,%rdx), %esi
-; X64-NEXT:    addl %edx, %r8d
 ; X64-NEXT:    cmpl %eax, %edi
 ; X64-NEXT:    movl %esi, (%r9)
-; X64-NEXT:    adcl %ecx, %r8d
+; X64-NEXT:    adcl %edx, %ecx
+; X64-NEXT:    addl %r8d, %ecx
 ; X64-NEXT:    cmovsl %edi, %eax
 ; X64-NEXT:    retq
   %7 = icmp ult i32 %0, %1

>From 5d30f179154dbe6ef4617106f8857e900ca756c7 Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Sat, 28 Feb 2026 05:48:19 -0800
Subject: [PATCH 11/13] Addressed the review comments5

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 75ab829816056..f624c3a310736 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58917,11 +58917,6 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
       return DAG.getNode(X86ISD::ADC, DL, N->getVTList(), LHS.getOperand(0),
                          RHS, LHS.getOperand(2));
     }
-
-    // Case: ADC(Y, X, CF) + 0 -> ADC(Y, X, CF)
-    if (C2 && C2->isZero()) {
-      return LHS;
-    }
   }
 
   // TODO: Can we drop the ZeroSecondOpOnly limit? This is to guarantee that the

>From 85c825676eef9a957b5047c5860234c83c8e1917 Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Sat, 28 Feb 2026 05:51:55 -0800
Subject: [PATCH 12/13] Addressed the review comments6

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index f624c3a310736..14cec75bf8a47 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58898,7 +58898,6 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
 
   // Fold ADD(ADC(Y, C1, CF), C2) -> ADC(Y, C1 + C2, CF) and
   //      ADD(ADC(Y, 0, CF), X) -> ADC(Y, X, CF) and
-  //      ADD(ADC(Y, X, CF), 0) -> ADC(Y, X, CF)
   if (!IsSub && LHS.getOpcode() == X86ISD::ADC && LHS.hasOneUse() &&
       !needCarryOrOverflowFlag(SDValue(N, 1))) {
 

>From 187c4fdd960b72ddeec5ac89ca6e791376f9d29b Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Sat, 28 Feb 2026 05:55:24 -0800
Subject: [PATCH 13/13] Remove comment

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 14cec75bf8a47..569cf8c4f6665 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -58897,7 +58897,7 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
   }
 
   // Fold ADD(ADC(Y, C1, CF), C2) -> ADC(Y, C1 + C2, CF) and
-  //      ADD(ADC(Y, 0, CF), X) -> ADC(Y, X, CF) and
+  //      ADD(ADC(Y, 0, CF), X) -> ADC(Y, X, CF)
   if (!IsSub && LHS.getOpcode() == X86ISD::ADC && LHS.hasOneUse() &&
       !needCarryOrOverflowFlag(SDValue(N, 1))) {
 



More information about the llvm-commits mailing list