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
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
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());
; 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
; 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