[llvm] 6697e33 - [X86] combineADC - fold ADC(C1,C2,Carry) -> ADC(0,C1+C2,Carry)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 30 01:13:21 PDT 2022


Author: Simon Pilgrim
Date: 2022-03-30T09:11:55+01:00
New Revision: 6697e3354fbe51242729888529d047c646acdab3

URL: https://github.com/llvm/llvm-project/commit/6697e3354fbe51242729888529d047c646acdab3
DIFF: https://github.com/llvm/llvm-project/commit/6697e3354fbe51242729888529d047c646acdab3.diff

LOG: [X86] combineADC - fold ADC(C1,C2,Carry) -> ADC(0,C1+C2,Carry)

If we're not relying on the flag result, we can fold the constants together into the RHS immediate operand and set the LHS operand to zero, simplifying for further folds.

We could do something similar if the flag result is in use and the constant fold doesn't affect it, but I don't have any real test cases for this yet.

As suggested by @davezarzycki on Issue #35256

Differential Revision: https://reviews.llvm.org/D122482

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/call-rv-marker.ll
    llvm/test/CodeGen/X86/combine-adc.ll
    llvm/test/CodeGen/X86/combine-add.ll
    llvm/test/CodeGen/X86/pr16031.ll
    llvm/test/CodeGen/X86/scheduler-backtracking.ll
    llvm/test/CodeGen/X86/setcc.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6c571c06a22f8..712ef61951278 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -52305,6 +52305,17 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
     return DCI.CombineTo(N, Res1, CarryOut);
   }
 
+  // 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);
+  }
+
   if (SDValue Flags = combineCarryThroughADD(CarryIn, DAG)) {
     MVT VT = N->getSimpleValueType(0);
     SDVTList VTs = DAG.getVTList(VT, MVT::i32);

diff  --git a/llvm/test/CodeGen/X86/call-rv-marker.ll b/llvm/test/CodeGen/X86/call-rv-marker.ll
index ea63873d811e2..0050a7d796ea7 100644
--- a/llvm/test/CodeGen/X86/call-rv-marker.ll
+++ b/llvm/test/CodeGen/X86/call-rv-marker.ll
@@ -55,17 +55,18 @@ entry:
 
 define void @rv_marker_2_select(i32 %c) {
 ; CHECK-LABEL: rv_marker_2_select:
-; CHECK:        pushq   %rax
-; CHECK-NEXT:   .cfi_def_cfa_offset 16
-; CHECK-NEXT:   cmpl    $1, %edi
-; CHECK-NEXT:   movl    $1, %edi
-; CHECK-NEXT:   adcl    $0, %edi
-; CHECK-NEXT:   callq   _foo0
-; CHECK-NEXT:   movq    %rax, %rdi
-; CHECK-NEXT:   callq   _objc_retainAutoreleasedReturnValue
-; CHECK-NEXT:   movq    %rax, %rdi
-; CHECK-NEXT:   popq    %rax
-; CHECK-NEXT:   jmp _foo2
+; CHECK:         pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpl $1, %edi
+; CHECK-NEXT:    adcl $1, %eax
+; CHECK-NEXT:    movl %eax, %edi
+; CHECK-NEXT:    callq _foo0
+; CHECK-NEXT:    movq %rax, %rdi
+; CHECK-NEXT:    callq _objc_retainAutoreleasedReturnValue
+; CHECK-NEXT:    movq %rax, %rdi
+; CHECK-NEXT:    popq %rax
+; CHECK-NEXT:    jmp _foo2
 ;
 entry:
   %tobool.not = icmp eq i32 %c, 0

diff  --git a/llvm/test/CodeGen/X86/combine-adc.ll b/llvm/test/CodeGen/X86/combine-adc.ll
index 3a6e26cbd8c49..37f4fe195d806 100644
--- a/llvm/test/CodeGen/X86/combine-adc.ll
+++ b/llvm/test/CodeGen/X86/combine-adc.ll
@@ -67,26 +67,25 @@ define i32 @PR40483_add2(i32*, i32) nounwind {
   ret i32 %10
 }
 
-; FIXME: Fail to add (non-overflowing) constants together
 ; FIXME: Fail to convert add+lshr+and to BT
 define i32 @adc_merge_constants(i32 %a0) nounwind {
 ; X86-LABEL: adc_merge_constants:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    shrl $11, %eax
-; X86-NEXT:    andb $1, %al
-; X86-NEXT:    addb $-1, %al
-; X86-NEXT:    movl $55, %eax
-; X86-NEXT:    adcl $-1, %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    shrl $11, %ecx
+; X86-NEXT:    andb $1, %cl
+; X86-NEXT:    xorl %eax, %eax
+; X86-NEXT:    addb $-1, %cl
+; X86-NEXT:    adcl $54, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: adc_merge_constants:
 ; X64:       # %bb.0:
 ; X64-NEXT:    shrl $11, %edi
 ; X64-NEXT:    andb $1, %dil
+; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    addb $-1, %dil
-; X64-NEXT:    movl $55, %eax
-; X64-NEXT:    adcl $-1, %eax
+; X64-NEXT:    adcl $54, %eax
 ; X64-NEXT:    retq
   %bit = lshr i32 %a0, 11
   %mask = and i32 %bit, 1

diff  --git a/llvm/test/CodeGen/X86/combine-add.ll b/llvm/test/CodeGen/X86/combine-add.ll
index 3d7fb1192083b..fb60bc8521896 100644
--- a/llvm/test/CodeGen/X86/combine-add.ll
+++ b/llvm/test/CodeGen/X86/combine-add.ll
@@ -438,9 +438,10 @@ define i1 @PR51238(i1 %b, i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: PR51238:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    notb %cl
+; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    addb %dl, %cl
-; CHECK-NEXT:    movb $1, %al
-; CHECK-NEXT:    adcb $0, %al
+; CHECK-NEXT:    adcb $1, %al
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-NEXT:    retq
    %ny = xor i8 %y, -1
    %nz = xor i8 %z, -1

diff  --git a/llvm/test/CodeGen/X86/pr16031.ll b/llvm/test/CodeGen/X86/pr16031.ll
index eb8f400969adc..3aeaec1b9ce77 100644
--- a/llvm/test/CodeGen/X86/pr16031.ll
+++ b/llvm/test/CodeGen/X86/pr16031.ll
@@ -4,18 +4,17 @@
 define i64 @main(i1 %tobool1) nounwind {
 ; CHECK-LABEL: main:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    pushl %esi
 ; CHECK-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; CHECK-NEXT:    movl $-12, %eax
-; CHECK-NEXT:    movl $-1, %ecx
-; CHECK-NEXT:    cmovel %ecx, %eax
+; CHECK-NEXT:    movl $-12, %ecx
+; CHECK-NEXT:    movl $-1, %eax
+; CHECK-NEXT:    cmovnel %ecx, %eax
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    movl %eax, %edx
+; CHECK-NEXT:    addl $-1, %edx
+; CHECK-NEXT:    movl $0, %edx
+; CHECK-NEXT:    adcl $-2, %edx
+; CHECK-NEXT:    cmovsl %ecx, %eax
 ; CHECK-NEXT:    xorl %edx, %edx
-; CHECK-NEXT:    movl %eax, %esi
-; CHECK-NEXT:    addl $-1, %esi
-; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    cmovsl %edx, %eax
-; CHECK-NEXT:    xorl %edx, %edx
-; CHECK-NEXT:    popl %esi
 ; CHECK-NEXT:    retl
 entry:
   %0 = zext i1 %tobool1 to i32

diff  --git a/llvm/test/CodeGen/X86/scheduler-backtracking.ll b/llvm/test/CodeGen/X86/scheduler-backtracking.ll
index 36f17a6628ac0..8c3d25fe565f3 100644
--- a/llvm/test/CodeGen/X86/scheduler-backtracking.ll
+++ b/llvm/test/CodeGen/X86/scheduler-backtracking.ll
@@ -690,77 +690,77 @@ declare i256 @llvm.ctlz.i256(i256, i1) nounwind readnone
 define i64 @test4(i64 %a, i64 %b) nounwind {
 ; ILP-LABEL: test4:
 ; ILP:       # %bb.0:
+; ILP-NEXT:    xorl %eax, %eax
 ; ILP-NEXT:    xorl %ecx, %ecx
-; ILP-NEXT:    xorl %edx, %edx
 ; ILP-NEXT:    incq %rsi
-; ILP-NEXT:    sete %dl
-; ILP-NEXT:    movl $2, %eax
+; ILP-NEXT:    sete %cl
 ; ILP-NEXT:    cmpq %rdi, %rsi
-; ILP-NEXT:    sbbq $0, %rdx
-; ILP-NEXT:    movl $0, %edx
-; ILP-NEXT:    sbbq %rdx, %rdx
+; ILP-NEXT:    sbbq $0, %rcx
+; ILP-NEXT:    movl $0, %ecx
 ; ILP-NEXT:    sbbq %rcx, %rcx
-; ILP-NEXT:    adcq $-1, %rax
+; ILP-NEXT:    movl $0, %ecx
+; ILP-NEXT:    sbbq %rcx, %rcx
+; ILP-NEXT:    adcq $1, %rax
 ; ILP-NEXT:    retq
 ;
 ; HYBRID-LABEL: test4:
 ; HYBRID:       # %bb.0:
+; HYBRID-NEXT:    xorl %eax, %eax
 ; HYBRID-NEXT:    xorl %ecx, %ecx
-; HYBRID-NEXT:    xorl %edx, %edx
 ; HYBRID-NEXT:    incq %rsi
-; HYBRID-NEXT:    sete %dl
-; HYBRID-NEXT:    movl $2, %eax
+; HYBRID-NEXT:    sete %cl
 ; HYBRID-NEXT:    cmpq %rdi, %rsi
-; HYBRID-NEXT:    sbbq $0, %rdx
-; HYBRID-NEXT:    movl $0, %edx
-; HYBRID-NEXT:    sbbq %rdx, %rdx
+; HYBRID-NEXT:    sbbq $0, %rcx
+; HYBRID-NEXT:    movl $0, %ecx
+; HYBRID-NEXT:    sbbq %rcx, %rcx
+; HYBRID-NEXT:    movl $0, %ecx
 ; HYBRID-NEXT:    sbbq %rcx, %rcx
-; HYBRID-NEXT:    adcq $-1, %rax
+; HYBRID-NEXT:    adcq $1, %rax
 ; HYBRID-NEXT:    retq
 ;
 ; BURR-LABEL: test4:
 ; BURR:       # %bb.0:
+; BURR-NEXT:    xorl %eax, %eax
 ; BURR-NEXT:    xorl %ecx, %ecx
-; BURR-NEXT:    xorl %edx, %edx
 ; BURR-NEXT:    incq %rsi
-; BURR-NEXT:    sete %dl
-; BURR-NEXT:    movl $2, %eax
+; BURR-NEXT:    sete %cl
 ; BURR-NEXT:    cmpq %rdi, %rsi
-; BURR-NEXT:    sbbq $0, %rdx
-; BURR-NEXT:    movl $0, %edx
-; BURR-NEXT:    sbbq %rdx, %rdx
+; BURR-NEXT:    sbbq $0, %rcx
+; BURR-NEXT:    movl $0, %ecx
+; BURR-NEXT:    sbbq %rcx, %rcx
+; BURR-NEXT:    movl $0, %ecx
 ; BURR-NEXT:    sbbq %rcx, %rcx
-; BURR-NEXT:    adcq $-1, %rax
+; BURR-NEXT:    adcq $1, %rax
 ; BURR-NEXT:    retq
 ;
 ; SRC-LABEL: test4:
 ; SRC:       # %bb.0:
-; SRC-NEXT:    xorl %eax, %eax
-; SRC-NEXT:    incq %rsi
-; SRC-NEXT:    sete %al
 ; SRC-NEXT:    xorl %ecx, %ecx
+; SRC-NEXT:    incq %rsi
+; SRC-NEXT:    sete %cl
+; SRC-NEXT:    xorl %eax, %eax
 ; SRC-NEXT:    cmpq %rdi, %rsi
-; SRC-NEXT:    sbbq $0, %rax
-; SRC-NEXT:    movl $0, %eax
-; SRC-NEXT:    sbbq %rax, %rax
+; SRC-NEXT:    sbbq $0, %rcx
+; SRC-NEXT:    movl $0, %ecx
+; SRC-NEXT:    sbbq %rcx, %rcx
+; SRC-NEXT:    movl $0, %ecx
 ; SRC-NEXT:    sbbq %rcx, %rcx
-; SRC-NEXT:    movl $2, %eax
-; SRC-NEXT:    adcq $-1, %rax
+; SRC-NEXT:    adcq $1, %rax
 ; SRC-NEXT:    retq
 ;
 ; LIN-LABEL: test4:
 ; LIN:       # %bb.0:
-; LIN-NEXT:    movl $2, %eax
+; LIN-NEXT:    xorl %eax, %eax
 ; LIN-NEXT:    xorl %ecx, %ecx
-; LIN-NEXT:    xorl %edx, %edx
 ; LIN-NEXT:    incq %rsi
-; LIN-NEXT:    sete %dl
+; LIN-NEXT:    sete %cl
 ; LIN-NEXT:    cmpq %rdi, %rsi
-; LIN-NEXT:    sbbq $0, %rdx
-; LIN-NEXT:    movl $0, %edx
-; LIN-NEXT:    sbbq %rdx, %rdx
+; LIN-NEXT:    sbbq $0, %rcx
+; LIN-NEXT:    movl $0, %ecx
+; LIN-NEXT:    sbbq %rcx, %rcx
+; LIN-NEXT:    movl $0, %ecx
 ; LIN-NEXT:    sbbq %rcx, %rcx
-; LIN-NEXT:    adcq $-1, %rax
+; LIN-NEXT:    adcq $1, %rax
 ; LIN-NEXT:    retq
   %r = zext i64 %b to i256
   %u = add i256 %r, 1

diff  --git a/llvm/test/CodeGen/X86/setcc.ll b/llvm/test/CodeGen/X86/setcc.ll
index 2bbc9ffe6168f..50f762de251bd 100644
--- a/llvm/test/CodeGen/X86/setcc.ll
+++ b/llvm/test/CodeGen/X86/setcc.ll
@@ -46,10 +46,10 @@ define i64 @t3(i64 %x) nounwind readnone ssp {
 define i32 @t4(i32 %a) {
 ; CHECK-LABEL: t4:
 ; CHECK:       ## %bb.0:
-; CHECK-NEXT:    movq _v4 at GOTPCREL(%rip), %rax
-; CHECK-NEXT:    cmpl $1, (%rax)
-; CHECK-NEXT:    movw $1, %ax
-; CHECK-NEXT:    adcw $0, %ax
+; CHECK-NEXT:    movq _v4 at GOTPCREL(%rip), %rcx
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpl $1, (%rcx)
+; CHECK-NEXT:    adcw $1, %ax
 ; CHECK-NEXT:    shll $16, %eax
 ; CHECK-NEXT:    retq
   %t0 = load i32, i32* @v4, align 4


        


More information about the llvm-commits mailing list