[llvm] r362488 - [DAGCombine][X86][AArch64][MIPS][LANAI] (C - x) - y -> C - (x + y) fold (PR41952)

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 4 04:06:22 PDT 2019


Author: lebedevri
Date: Tue Jun  4 04:06:21 2019
New Revision: 362488

URL: http://llvm.org/viewvc/llvm-project?rev=362488&view=rev
Log:
[DAGCombine][X86][AArch64][MIPS][LANAI] (C - x) - y  ->  C - (x + y) fold (PR41952)

Summary:
This *might* be the last fold for `sink-addsub-of-const.ll`, but i'm not sure yet.

As far as i can tell, there are no regressions here (ignoring x86-32),
all changes are either good or neutral.

This, almost surprisingly to me, fixes the motivational tests (in `shift-amount-mod.ll`)
`@reg32_lshr_by_sub_from_negated` from [[ https://bugs.llvm.org/show_bug.cgi?id=41952 | PR41952 ]].

https://rise4fun.com/Alive/vMd3

Reviewers: RKSimon, t.p.northover, craig.topper, spatel, efriedma

Reviewed By: RKSimon

Subscribers: sdardis, javed.absar, arichardson, kristof.beyls, jrtc27, atanasyan, llvm-commits

Tags: #llvm

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

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/test/CodeGen/AArch64/shift-amount-mod.ll
    llvm/trunk/test/CodeGen/AArch64/sink-addsub-of-const.ll
    llvm/trunk/test/CodeGen/Lanai/constant_multiply.ll
    llvm/trunk/test/CodeGen/Mips/const-mult.ll
    llvm/trunk/test/CodeGen/Mips/madd-msub.ll
    llvm/trunk/test/CodeGen/X86/shift-amount-mod.ll
    llvm/trunk/test/CodeGen/X86/sink-addsub-of-const.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=362488&r1=362487&r2=362488&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Jun  4 04:06:21 2019
@@ -3033,6 +3033,12 @@ SDValue DAGCombiner::visitSUB(SDNode *N)
     SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), N1);
     return DAG.getNode(ISD::SUB, DL, VT, Sub, N0.getOperand(1));
   }
+  // (C - x) - y  ->  C - (x + y)
+  if (N0.hasOneUse() && N0.getOpcode() == ISD::SUB &&
+      isConstantOrConstantVector(N0.getOperand(0), /*NoOpaques=*/true)) {
+    SDValue Add = DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(1), N1);
+    return DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), Add);
+  }
 
   // If the target's bool is represented as 0/-1, prefer to make this 'add 0/-1'
   // rather than 'sub 0/1' (the sext should get folded).

Modified: llvm/trunk/test/CodeGen/AArch64/shift-amount-mod.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/shift-amount-mod.ll?rev=362488&r1=362487&r2=362488&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/shift-amount-mod.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/shift-amount-mod.ll Tue Jun  4 04:06:21 2019
@@ -318,9 +318,8 @@ define void @modify64_ashr_by_negated(i6
 define i32 @reg32_lshr_by_sub_from_negated(i32 %val, i32 %a, i32 %b) nounwind {
 ; CHECK-LABEL: reg32_lshr_by_sub_from_negated:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mov w8, #32
-; CHECK-NEXT:    sub w8, w8, w1
-; CHECK-NEXT:    sub w8, w8, w2
+; CHECK-NEXT:    add w8, w1, w2
+; CHECK-NEXT:    neg w8, w8
 ; CHECK-NEXT:    lsr w0, w0, w8
 ; CHECK-NEXT:    ret
   %nega = sub i32 32, %a
@@ -331,9 +330,8 @@ define i32 @reg32_lshr_by_sub_from_negat
 define i64 @reg64_lshr_by_sub_from_negated(i64 %val, i64 %a, i64 %b) nounwind {
 ; CHECK-LABEL: reg64_lshr_by_sub_from_negated:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mov w8, #64
-; CHECK-NEXT:    sub x8, x8, x1
-; CHECK-NEXT:    sub x8, x8, x2
+; CHECK-NEXT:    add x8, x1, x2
+; CHECK-NEXT:    neg x8, x8
 ; CHECK-NEXT:    lsr x0, x0, x8
 ; CHECK-NEXT:    ret
   %nega = sub i64 64, %a
@@ -482,8 +480,8 @@ define i64 @reg64_lshr_by_negated_unfold
 define i32 @reg32_lshr_by_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
 ; CHECK-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    neg w8, w1
-; CHECK-NEXT:    sub w8, w8, w2
+; CHECK-NEXT:    add w8, w1, w2
+; CHECK-NEXT:    neg w8, w8
 ; CHECK-NEXT:    lsr w0, w0, w8
 ; CHECK-NEXT:    ret
   %nega = sub i32 0, %a
@@ -495,8 +493,8 @@ define i32 @reg32_lshr_by_negated_unfold
 define i64 @reg64_lshr_by_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
 ; CHECK-LABEL: reg64_lshr_by_negated_unfolded_sub_b:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    neg x8, x1
-; CHECK-NEXT:    sub x8, x8, x2
+; CHECK-NEXT:    add x8, x1, x2
+; CHECK-NEXT:    neg x8, x8
 ; CHECK-NEXT:    lsr x0, x0, x8
 ; CHECK-NEXT:    ret
   %nega = sub i64 0, %a

Modified: llvm/trunk/test/CodeGen/AArch64/sink-addsub-of-const.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/sink-addsub-of-const.ll?rev=362488&r1=362487&r2=362488&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/sink-addsub-of-const.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/sink-addsub-of-const.ll Tue Jun  4 04:06:21 2019
@@ -129,9 +129,9 @@ define i32 @sink_sub_of_const_to_sub2(i3
 define i32 @sink_sub_from_const_to_sub(i32 %a, i32 %b) {
 ; CHECK-LABEL: sink_sub_from_const_to_sub:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mov w8, #32
-; CHECK-NEXT:    sub w8, w8, w0
-; CHECK-NEXT:    sub w0, w8, w1
+; CHECK-NEXT:    add w8, w0, w1
+; CHECK-NEXT:    mov w9, #32
+; CHECK-NEXT:    sub w0, w9, w8
 ; CHECK-NEXT:    ret
   %t0 = sub i32 32, %a
   %r = sub i32 %t0, %b
@@ -300,8 +300,8 @@ define <4 x i32> @vec_sink_sub_from_cons
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    adrp x8, .LCPI22_0
 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI22_0]
+; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
 ; CHECK-NEXT:    sub v0.4s, v2.4s, v0.4s
-; CHECK-NEXT:    sub v0.4s, v0.4s, v1.4s
 ; CHECK-NEXT:    ret
   %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a
   %r = sub <4 x i32> %t0, %b

Modified: llvm/trunk/test/CodeGen/Lanai/constant_multiply.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Lanai/constant_multiply.ll?rev=362488&r1=362487&r2=362488&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Lanai/constant_multiply.ll (original)
+++ llvm/trunk/test/CodeGen/Lanai/constant_multiply.ll Tue Jun  4 04:06:21 2019
@@ -150,9 +150,9 @@ define i32 @fm9(i32 inreg %a) #0 {
 ; CHECK-NEXT:    st %fp, [--%sp]
 ; CHECK-NEXT:    add %sp, 0x8, %fp
 ; CHECK-NEXT:    sub %sp, 0x8, %sp
-; CHECK-NEXT:    sub %r0, %r6, %r3
-; CHECK-NEXT:    sh %r6, 0x3, %r9
-; CHECK-NEXT:    sub %r3, %r9, %rv
+; CHECK-NEXT:    sh %r6, 0x3, %r3
+; CHECK-NEXT:    add %r6, %r3, %r3
+; CHECK-NEXT:    sub %r0, %r3, %rv
 ; CHECK-NEXT:    ld -4[%fp], %pc ! return
 ; CHECK-NEXT:    add %fp, 0x0, %sp
 ; CHECK-NEXT:    ld -8[%fp], %fp
@@ -166,10 +166,10 @@ define i32 @fm10(i32 inreg %a) #0 {
 ; CHECK-NEXT:    st %fp, [--%sp]
 ; CHECK-NEXT:    add %sp, 0x8, %fp
 ; CHECK-NEXT:    sub %sp, 0x8, %sp
-; CHECK-NEXT:    sh %r6, 0x1, %r3
-; CHECK-NEXT:    sub %r0, %r3, %r3
-; CHECK-NEXT:    sh %r6, 0x3, %r9
-; CHECK-NEXT:    sub %r3, %r9, %rv
+; CHECK-NEXT:    sh %r6, 0x3, %r3
+; CHECK-NEXT:    sh %r6, 0x1, %r9
+; CHECK-NEXT:    add %r9, %r3, %r3
+; CHECK-NEXT:    sub %r0, %r3, %rv
 ; CHECK-NEXT:    ld -4[%fp], %pc ! return
 ; CHECK-NEXT:    add %fp, 0x0, %sp
 ; CHECK-NEXT:    ld -8[%fp], %fp

Modified: llvm/trunk/test/CodeGen/Mips/const-mult.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/const-mult.ll?rev=362488&r1=362487&r2=362488&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/const-mult.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/const-mult.ll Tue Jun  4 04:06:21 2019
@@ -179,8 +179,8 @@ define i128 @mul170141183460469231731687
 ; MIPS32-NEXT:    subu $1, $1, $3
 ; MIPS32-NEXT:    subu $5, $1, $12
 ; MIPS32-NEXT:    subu $4, $9, $10
-; MIPS32-NEXT:    negu $1, $8
-; MIPS32-NEXT:    subu $3, $1, $11
+; MIPS32-NEXT:    addu $1, $8, $11
+; MIPS32-NEXT:    negu $3, $1
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    negu $2, $2
 ;

Modified: llvm/trunk/test/CodeGen/Mips/madd-msub.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/madd-msub.ll?rev=362488&r1=362487&r2=362488&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/madd-msub.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/madd-msub.ll Tue Jun  4 04:06:21 2019
@@ -342,13 +342,13 @@ define i64 @msub2(i32 zeroext %a, i32 ze
 ;
 ; 32R6-LABEL: msub2:
 ; 32R6:       # %bb.0: # %entry
-; 32R6-NEXT:    mul $1, $5, $4
-; 32R6-NEXT:    sltu $2, $6, $1
-; 32R6-NEXT:    muhu $3, $5, $4
-; 32R6-NEXT:    negu $3, $3
-; 32R6-NEXT:    subu $2, $3, $2
+; 32R6-NEXT:    muhu $1, $5, $4
+; 32R6-NEXT:    mul $3, $5, $4
+; 32R6-NEXT:    sltu $2, $6, $3
+; 32R6-NEXT:    addu $1, $1, $2
+; 32R6-NEXT:    negu $2, $1
 ; 32R6-NEXT:    jr $ra
-; 32R6-NEXT:    subu $3, $6, $1
+; 32R6-NEXT:    subu $3, $6, $3
 ;
 ; DSP-LABEL: msub2:
 ; DSP:       # %bb.0: # %entry
@@ -377,12 +377,12 @@ define i64 @msub2(i32 zeroext %a, i32 ze
 ; 16:       # %bb.0: # %entry
 ; 16-NEXT:    multu $5, $4
 ; 16-NEXT:    mflo $2
-; 16-NEXT:    mfhi $4
-; 16-NEXT:    subu $3, $6, $2
+; 16-NEXT:    mfhi $3
 ; 16-NEXT:    sltu $6, $2
-; 16-NEXT:    move $2, $24
-; 16-NEXT:    neg $4, $4
-; 16-NEXT:    subu $2, $4, $2
+; 16-NEXT:    move $4, $24
+; 16-NEXT:    addu $4, $3, $4
+; 16-NEXT:    subu $3, $6, $2
+; 16-NEXT:    neg $2, $4
 ; 16-NEXT:    jrc $ra
 entry:
   %conv = zext i32 %c to i64

Modified: llvm/trunk/test/CodeGen/X86/shift-amount-mod.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shift-amount-mod.ll?rev=362488&r1=362487&r2=362488&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/shift-amount-mod.ll (original)
+++ llvm/trunk/test/CodeGen/X86/shift-amount-mod.ll Tue Jun  4 04:06:21 2019
@@ -735,19 +735,20 @@ define i32 @reg32_lshr_by_sub_from_negat
 ; X32-LABEL: reg32_lshr_by_sub_from_negated:
 ; X32:       # %bb.0:
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X32-NEXT:    movl $32, %ecx
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    negb %cl
 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; X32-NEXT:    shrl %cl, %eax
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: reg32_lshr_by_sub_from_negated:
 ; X64:       # %bb.0:
+; X64-NEXT:    # kill: def $edx killed $edx def $rdx
+; X64-NEXT:    # kill: def $esi killed $esi def $rsi
 ; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    movl $32, %ecx
-; X64-NEXT:    subl %esi, %ecx
-; X64-NEXT:    subl %edx, %ecx
+; X64-NEXT:    leal (%rsi,%rdx), %ecx
+; X64-NEXT:    negb %cl
 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; X64-NEXT:    shrl %cl, %eax
 ; X64-NEXT:    retq
@@ -762,9 +763,10 @@ define i64 @reg64_lshr_by_sub_from_negat
 ; X32-NEXT:    pushl %esi
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; X32-NEXT:    movl $64, %ecx
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
+; X32-NEXT:    movb $64, %cl
+; X32-NEXT:    subb %dl, %cl
 ; X32-NEXT:    movl %esi, %edx
 ; X32-NEXT:    shrl %cl, %edx
 ; X32-NEXT:    shrdl %cl, %esi, %eax
@@ -780,9 +782,8 @@ define i64 @reg64_lshr_by_sub_from_negat
 ; X64-LABEL: reg64_lshr_by_sub_from_negated:
 ; X64:       # %bb.0:
 ; X64-NEXT:    movq %rdi, %rax
-; X64-NEXT:    movl $64, %ecx
-; X64-NEXT:    subl %esi, %ecx
-; X64-NEXT:    subl %edx, %ecx
+; X64-NEXT:    leal (%rdx,%rsi), %ecx
+; X64-NEXT:    negb %cl
 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; X64-NEXT:    shrq %cl, %rax
 ; X64-NEXT:    retq
@@ -1108,19 +1109,20 @@ define i32 @reg32_lshr_by_negated_unfold
 ; X32-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
 ; X32:       # %bb.0:
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X32-NEXT:    xorl %ecx, %ecx
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    negb %cl
 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; X32-NEXT:    shrl %cl, %eax
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %esi, %ecx
+; X64-NEXT:    # kill: def $edx killed $edx def $rdx
+; X64-NEXT:    # kill: def $esi killed $esi def $rsi
 ; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    negl %ecx
-; X64-NEXT:    subl %edx, %ecx
+; X64-NEXT:    leal (%rsi,%rdx), %ecx
+; X64-NEXT:    negb %cl
 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; X64-NEXT:    shrl %cl, %eax
 ; X64-NEXT:    retq
@@ -1136,10 +1138,10 @@ define i64 @reg64_lshr_by_negated_unfold
 ; X32-NEXT:    pushl %esi
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; X32-NEXT:    xorl %ecx, %ecx
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
-; X32-NEXT:    addb $64, %cl
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
+; X32-NEXT:    movb $64, %cl
+; X32-NEXT:    subb %dl, %cl
 ; X32-NEXT:    movl %esi, %edx
 ; X32-NEXT:    shrl %cl, %edx
 ; X32-NEXT:    shrdl %cl, %esi, %eax
@@ -1155,9 +1157,8 @@ define i64 @reg64_lshr_by_negated_unfold
 ; X64-LABEL: reg64_lshr_by_negated_unfolded_sub_b:
 ; X64:       # %bb.0:
 ; X64-NEXT:    movq %rdi, %rax
-; X64-NEXT:    movl $64, %ecx
-; X64-NEXT:    subl %esi, %ecx
-; X64-NEXT:    subl %edx, %ecx
+; X64-NEXT:    leal (%rdx,%rsi), %ecx
+; X64-NEXT:    negb %cl
 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; X64-NEXT:    shrq %cl, %rax
 ; X64-NEXT:    retq

Modified: llvm/trunk/test/CodeGen/X86/sink-addsub-of-const.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sink-addsub-of-const.ll?rev=362488&r1=362487&r2=362488&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/sink-addsub-of-const.ll (original)
+++ llvm/trunk/test/CodeGen/X86/sink-addsub-of-const.ll Tue Jun  4 04:06:21 2019
@@ -214,16 +214,17 @@ define i32 @sink_sub_of_const_to_sub2(i3
 define i32 @sink_sub_from_const_to_sub(i32 %a, i32 %b) {
 ; X32-LABEL: sink_sub_from_const_to_sub:
 ; X32:       # %bb.0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl $32, %eax
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
-; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    subl %ecx, %eax
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: sink_sub_from_const_to_sub:
 ; X64:       # %bb.0:
+; X64-NEXT:    addl %esi, %edi
 ; X64-NEXT:    movl $32, %eax
 ; X64-NEXT:    subl %edi, %eax
-; X64-NEXT:    subl %esi, %eax
 ; X64-NEXT:    retq
   %t0 = sub i32 32, %a
   %r = sub i32 %t0, %b
@@ -448,8 +449,8 @@ define <4 x i32> @vec_sink_sub_from_cons
 ; ALL-LABEL: vec_sink_sub_from_const_to_sub:
 ; ALL:       # %bb.0:
 ; ALL-NEXT:    movdqa {{.*#+}} xmm2 = <42,24,u,46>
+; ALL-NEXT:    paddd %xmm1, %xmm0
 ; ALL-NEXT:    psubd %xmm0, %xmm2
-; ALL-NEXT:    psubd %xmm1, %xmm2
 ; ALL-NEXT:    movdqa %xmm2, %xmm0
 ; ALL-NEXT:    ret{{[l|q]}}
   %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a




More information about the llvm-commits mailing list