llvm.org GIT mirror llvm / 4bdf657
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350239 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 9 months ago
3 changed file(s) with 41 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
31603160 if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))
31613161 return DAG.getNode(ISD::UDIV, DL, N1.getValueType(), N0, N1);
31623162
3163 if (SDValue V = visitSDIVLike(N0, N1, N))
3163 if (SDValue V = visitSDIVLike(N0, N1, N)) {
3164 // If the corresponding remainder node exists, update its users with
3165 // (Dividend - (Quotient * Divisor).
3166 if (SDNode *RemNode = DAG.getNodeIfExists(ISD::SREM, N->getVTList(),
3167 { N0, N1 })) {
3168 SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, V, N1);
3169 SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
3170 AddToWorklist(Mul.getNode());
3171 AddToWorklist(Sub.getNode());
3172 CombineTo(RemNode, Sub);
3173 }
31643174 return V;
3175 }
31653176
31663177 // sdiv, srem -> sdivrem
31673178 // If the divisor is constant, then return DIVREM only if isIntDivCheap() is
32873298 if (SDValue NewSel = foldBinOpIntoSelect(N))
32883299 return NewSel;
32893300
3290 if (SDValue V = visitUDIVLike(N0, N1, N))
3301 if (SDValue V = visitUDIVLike(N0, N1, N)) {
3302 // If the corresponding remainder node exists, update its users with
3303 // (Dividend - (Quotient * Divisor).
3304 if (SDNode *RemNode = DAG.getNodeIfExists(ISD::UREM, N->getVTList(),
3305 { N0, N1 })) {
3306 SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, V, N1);
3307 SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
3308 AddToWorklist(Mul.getNode());
3309 AddToWorklist(Sub.getNode());
3310 CombineTo(RemNode, Sub);
3311 }
32913312 return V;
3313 }
32923314
32933315 // sdiv, srem -> sdivrem
32943316 // If the divisor is constant, then return DIVREM only if isIntDivCheap() is
34073429 SDValue OptimizedDiv =
34083430 isSigned ? visitSDIVLike(N0, N1, N) : visitUDIVLike(N0, N1, N);
34093431 if (OptimizedDiv.getNode()) {
3432 // If the equivalent Div node also exists, update its users.
3433 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
3434 if (SDNode *DivNode = DAG.getNodeIfExists(DivOpcode, N->getVTList(),
3435 { N0, N1 }))
3436 CombineTo(DivNode, OptimizedDiv);
34103437 SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, OptimizedDiv, N1);
34113438 SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
34123439 AddToWorklist(OptimizedDiv.getNode());
440440 ; X64-NEXT: movabsq $1237940039285380275, %rcx # imm = 0x112E0BE826D694B3
441441 ; X64-NEXT: movq %rdi, %rax
442442 ; X64-NEXT: imulq %rcx
443 ; X64-NEXT: movq %rdx, %rax
443444 ; X64-NEXT: movq %rdx, %rcx
444445 ; X64-NEXT: shrq $63, %rcx
445 ; X64-NEXT: sarq $28, %rdx
446 ; X64-NEXT: leaq (%rdx,%rcx), %rax
447 ; X64-NEXT: addl %ecx, %edx
448 ; X64-NEXT: imull $-294967296, %edx, %ecx # imm = 0xEE6B2800
446 ; X64-NEXT: sarq $28, %rax
447 ; X64-NEXT: addq %rcx, %rax
448 ; X64-NEXT: imull $-294967296, %eax, %ecx # imm = 0xEE6B2800
449449 ; X64-NEXT: subl %ecx, %edi
450450 ; X64-NEXT: movl %edi, %edx
451451 ; X64-NEXT: retq
1919 ; CHECK-NEXT: imulq $10000, %rdx, %rax # imm = 0x2710
2020 ; CHECK-NEXT: movq %r9, %rdi
2121 ; CHECK-NEXT: subq %rax, %rdi
22 ; CHECK-NEXT: imulq $1374389535, %rdi, %rcx # imm = 0x51EB851F
23 ; CHECK-NEXT: movq %rcx, %rax
22 ; CHECK-NEXT: imulq $1374389535, %rdi, %rax # imm = 0x51EB851F
2423 ; CHECK-NEXT: shrq $37, %rax
25 ; CHECK-NEXT: imull $100, %eax, %eax
26 ; CHECK-NEXT: subl %eax, %edi
27 ; CHECK-NEXT: shrq $36, %rcx
28 ; CHECK-NEXT: andl $510, %ecx # imm = 0x1FE
24 ; CHECK-NEXT: imull $100, %eax, %ecx
25 ; CHECK-NEXT: subl %ecx, %edi
2926 ; CHECK-NEXT: movl %r10d, %r11d
30 ; CHECK-NEXT: movq %rsi, %rax
31 ; CHECK-NEXT: subq %r11, %rax
27 ; CHECK-NEXT: movq %rsi, %rcx
28 ; CHECK-NEXT: subq %r11, %rcx
3229 ; CHECK-NEXT: movzwl _ZL11DIGIT_TABLE(%rdi,%rdi), %edi
33 ; CHECK-NEXT: movw %di, -1(%rax)
34 ; CHECK-NEXT: movzwl _ZL11DIGIT_TABLE(%rcx), %ecx
35 ; CHECK-NEXT: movw %cx, -3(%rax)
30 ; CHECK-NEXT: movw %di, -1(%rcx)
31 ; CHECK-NEXT: movzwl _ZL11DIGIT_TABLE(%rax,%rax), %eax
32 ; CHECK-NEXT: movw %ax, -3(%rcx)
3633 ; CHECK-NEXT: addl $4, %r10d
3734 ; CHECK-NEXT: cmpq $99999999, %r9 # imm = 0x5F5E0FF
3835 ; CHECK-NEXT: movq %rdx, %r9