[llvm] r350239 - [DAGCombiner] After performing the division by constant optimization for a DIV or REM node, replace the users of the corresponding REM or DIV node if it exists.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 2 10:19:08 PST 2019


Author: ctopper
Date: Wed Jan  2 10:19:07 2019
New Revision: 350239

URL: http://llvm.org/viewvc/llvm-project?rev=350239&view=rev
Log:
[DAGCombiner] After performing the division by constant optimization for a DIV or REM node, replace the users of the corresponding REM or DIV node if it exists.

Currently we expand the two nodes separately. This gives DAG combiner an opportunity to optimize the expanded sequence taking into account only one set of users. When we expand the other node we'll create the expansion again, but might not be able to optimize it the same way. So the nodes won't CSE and we'll have two similarish sequences in the same basic block. By expanding both nodes at the same time we'll avoid prematurely optimizing the expansion until both the division and remainder have been replaced.

Improves the test case from PR38217. There may be additional opportunities after this.

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

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/test/CodeGen/X86/divide-by-constant.ll
    llvm/trunk/test/CodeGen/X86/pr38217.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=350239&r1=350238&r2=350239&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Jan  2 10:19:07 2019
@@ -3161,8 +3161,19 @@ SDValue DAGCombiner::visitSDIV(SDNode *N
   if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))
     return DAG.getNode(ISD::UDIV, DL, N1.getValueType(), N0, N1);
 
-  if (SDValue V = visitSDIVLike(N0, N1, N))
+  if (SDValue V = visitSDIVLike(N0, N1, N)) {
+    // If the corresponding remainder node exists, update its users with
+    // (Dividend - (Quotient * Divisor).
+    if (SDNode *RemNode = DAG.getNodeIfExists(ISD::SREM, N->getVTList(),
+                                              { N0, N1 })) {
+      SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, V, N1);
+      SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
+      AddToWorklist(Mul.getNode());
+      AddToWorklist(Sub.getNode());
+      CombineTo(RemNode, Sub);
+    }
     return V;
+  }
 
   // sdiv, srem -> sdivrem
   // If the divisor is constant, then return DIVREM only if isIntDivCheap() is
@@ -3288,8 +3299,19 @@ SDValue DAGCombiner::visitUDIV(SDNode *N
   if (SDValue NewSel = foldBinOpIntoSelect(N))
     return NewSel;
 
-  if (SDValue V = visitUDIVLike(N0, N1, N))
+  if (SDValue V = visitUDIVLike(N0, N1, N)) {
+    // If the corresponding remainder node exists, update its users with
+    // (Dividend - (Quotient * Divisor).
+    if (SDNode *RemNode = DAG.getNodeIfExists(ISD::UREM, N->getVTList(),
+                                              { N0, N1 })) {
+      SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, V, N1);
+      SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
+      AddToWorklist(Mul.getNode());
+      AddToWorklist(Sub.getNode());
+      CombineTo(RemNode, Sub);
+    }
     return V;
+  }
 
   // sdiv, srem -> sdivrem
   // If the divisor is constant, then return DIVREM only if isIntDivCheap() is
@@ -3408,6 +3430,11 @@ SDValue DAGCombiner::visitREM(SDNode *N)
     SDValue OptimizedDiv =
         isSigned ? visitSDIVLike(N0, N1, N) : visitUDIVLike(N0, N1, N);
     if (OptimizedDiv.getNode()) {
+      // If the equivalent Div node also exists, update its users.
+      unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
+      if (SDNode *DivNode = DAG.getNodeIfExists(DivOpcode, N->getVTList(),
+                                                { N0, N1 }))
+        CombineTo(DivNode, OptimizedDiv);
       SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, OptimizedDiv, N1);
       SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
       AddToWorklist(OptimizedDiv.getNode());

Modified: llvm/trunk/test/CodeGen/X86/divide-by-constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/divide-by-constant.ll?rev=350239&r1=350238&r2=350239&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/divide-by-constant.ll (original)
+++ llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Wed Jan  2 10:19:07 2019
@@ -441,12 +441,12 @@ define { i64, i32 } @PR38622_signed(i64)
 ; X64-NEXT:    movabsq $1237940039285380275, %rcx # imm = 0x112E0BE826D694B3
 ; X64-NEXT:    movq %rdi, %rax
 ; X64-NEXT:    imulq %rcx
+; X64-NEXT:    movq %rdx, %rax
 ; X64-NEXT:    movq %rdx, %rcx
 ; X64-NEXT:    shrq $63, %rcx
-; X64-NEXT:    sarq $28, %rdx
-; X64-NEXT:    leaq (%rdx,%rcx), %rax
-; X64-NEXT:    addl %ecx, %edx
-; X64-NEXT:    imull $-294967296, %edx, %ecx # imm = 0xEE6B2800
+; X64-NEXT:    sarq $28, %rax
+; X64-NEXT:    addq %rcx, %rax
+; X64-NEXT:    imull $-294967296, %eax, %ecx # imm = 0xEE6B2800
 ; X64-NEXT:    subl %ecx, %edi
 ; X64-NEXT:    movl %edi, %edx
 ; X64-NEXT:    retq

Modified: llvm/trunk/test/CodeGen/X86/pr38217.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr38217.ll?rev=350239&r1=350238&r2=350239&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/pr38217.ll (original)
+++ llvm/trunk/test/CodeGen/X86/pr38217.ll Wed Jan  2 10:19:07 2019
@@ -20,20 +20,17 @@ define void @_Z12d2s_bufferedmPc(i64, i8
 ; CHECK-NEXT:    imulq $10000, %rdx, %rax # imm = 0x2710
 ; CHECK-NEXT:    movq %r9, %rdi
 ; CHECK-NEXT:    subq %rax, %rdi
-; CHECK-NEXT:    imulq $1374389535, %rdi, %rcx # imm = 0x51EB851F
-; CHECK-NEXT:    movq %rcx, %rax
+; CHECK-NEXT:    imulq $1374389535, %rdi, %rax # imm = 0x51EB851F
 ; CHECK-NEXT:    shrq $37, %rax
-; CHECK-NEXT:    imull $100, %eax, %eax
-; CHECK-NEXT:    subl %eax, %edi
-; CHECK-NEXT:    shrq $36, %rcx
-; CHECK-NEXT:    andl $510, %ecx # imm = 0x1FE
+; CHECK-NEXT:    imull $100, %eax, %ecx
+; CHECK-NEXT:    subl %ecx, %edi
 ; CHECK-NEXT:    movl %r10d, %r11d
-; CHECK-NEXT:    movq %rsi, %rax
-; CHECK-NEXT:    subq %r11, %rax
+; CHECK-NEXT:    movq %rsi, %rcx
+; CHECK-NEXT:    subq %r11, %rcx
 ; CHECK-NEXT:    movzwl _ZL11DIGIT_TABLE(%rdi,%rdi), %edi
-; CHECK-NEXT:    movw %di, -1(%rax)
-; CHECK-NEXT:    movzwl _ZL11DIGIT_TABLE(%rcx), %ecx
-; CHECK-NEXT:    movw %cx, -3(%rax)
+; CHECK-NEXT:    movw %di, -1(%rcx)
+; CHECK-NEXT:    movzwl _ZL11DIGIT_TABLE(%rax,%rax), %eax
+; CHECK-NEXT:    movw %ax, -3(%rcx)
 ; CHECK-NEXT:    addl $4, %r10d
 ; CHECK-NEXT:    cmpq $99999999, %r9 # imm = 0x5F5E0FF
 ; CHECK-NEXT:    movq %rdx, %r9




More information about the llvm-commits mailing list