Index: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3161,8 +3161,19 @@ 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 @@ 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 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()); Index: llvm/trunk/test/CodeGen/X86/divide-by-constant.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/divide-by-constant.ll +++ llvm/trunk/test/CodeGen/X86/divide-by-constant.ll @@ -441,12 +441,12 @@ ; 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 Index: llvm/trunk/test/CodeGen/X86/pr38217.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/pr38217.ll +++ llvm/trunk/test/CodeGen/X86/pr38217.ll @@ -20,20 +20,17 @@ ; 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