[llvm] [DAGCombiner] Port custom DAG combine for `rem` from NVPTX (PR #210344)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 20 00:07:16 PDT 2026
https://github.com/def3r updated https://github.com/llvm/llvm-project/pull/210344
>From d43613a56b42f438ab07c6b6e8b771e76385e873 Mon Sep 17 00:00:00 2001
From: Ayaan Khan <ayaanandayaan2 at gmail.com>
Date: Fri, 17 Jul 2026 18:54:12 +0530
Subject: [PATCH 1/2] port div rem combine from NVPTX
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 36 +++++++++
llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp | 37 +--------
llvm/test/CodeGen/X86/divide-by-constant.ll | 59 ++++++--------
llvm/test/CodeGen/X86/divrem.ll | 76 +++++++++++--------
4 files changed, 105 insertions(+), 103 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 2f2d5cb709642..f5388a2982bde 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -444,6 +444,7 @@ namespace {
SDValue visitSSUBO_CARRY(SDNode *N);
SDValue visitMUL(SDNode *N);
SDValue visitMULFIX(SDNode *N);
+ SDValue performREMCombine(SDNode *N);
SDValue useDivRem(SDNode *N);
SDValue visitSDIV(SDNode *N);
SDValue visitSDIVLike(SDValue N0, SDValue N1, SDNode *N);
@@ -5093,6 +5094,38 @@ static bool isDivRemLibcallAvailable(SDNode *Node, bool isSigned,
return DAG.getLibcalls().getLibcallImpl(LC) != RTLIB::Unsupported;
}
+// Fold Num % Den -> Num - (Num / Den) * Den, if (Num / Den) is already
+// computed
+SDValue DAGCombiner::performREMCombine(SDNode *N) {
+ assert(N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM);
+
+ // Don't do anything at less than -O2.
+ if (OptLevel < CodeGenOptLevel::Default)
+ return SDValue();
+
+ SDLoc DL(N);
+ EVT VT = N->getValueType(0);
+ bool IsSigned = N->getOpcode() == ISD::SREM;
+ unsigned DivOpc = IsSigned ? ISD::SDIV : ISD::UDIV;
+ unsigned DivRemOpc = IsSigned ? ISD::SDIVREM : ISD::UDIVREM;
+
+ // If DIVREM is available, do not fold
+ if (TLI.isOperationLegalOrCustom(DivRemOpc, VT.getScalarType()))
+ return SDValue();
+
+ const SDValue &Num = N->getOperand(0);
+ const SDValue &Den = N->getOperand(1);
+ for (const SDNode *U : Num->users()) {
+ if (U->getOpcode() == DivOpc && U->getOperand(0) == Num &&
+ U->getOperand(1) == Den) {
+ SDValue Div = DAG.getNode(DivOpc, DL, VT, Num, Den);
+ SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, Div, Den);
+ return DAG.getNode(ISD::SUB, DL, VT, Num, Mul);
+ }
+ }
+ return SDValue();
+}
+
/// Issue divrem if both quotient and remainder are needed.
SDValue DAGCombiner::useDivRem(SDNode *Node) {
if (Node->use_empty())
@@ -5563,6 +5596,9 @@ SDValue DAGCombiner::visitREM(SDNode *N) {
}
}
+ if (SDValue V = performREMCombine(N))
+ return V;
+
// sdiv, srem -> sdivrem
if (SDValue DivRem = useDivRem(N))
return DivRem.getValue(1);
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
index 1c5caf124c17e..522620d88227f 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -687,6 +687,9 @@ NVPTXTargetLowering::NVPTXTargetLowering(const NVPTXTargetMachine &TM,
setOperationAction(ISD::BR_CC, VT, Expand);
}
+ setOperationAction(ISD::SDIVREM, {MVT::i32, MVT::i64}, Expand);
+ setOperationAction(ISD::UDIVREM, {MVT::i32, MVT::i64}, Expand);
+
// We don't want ops like FMINIMUM or UMAX to be lowered to SETCC+VSELECT.
setOperationAction(ISD::VSELECT, {MVT::v2f32, MVT::v2i32}, Expand);
@@ -6281,37 +6284,6 @@ static SDValue PerformFMinMaxCombine(SDNode *N,
return SDValue();
}
-static SDValue PerformREMCombine(SDNode *N,
- TargetLowering::DAGCombinerInfo &DCI,
- CodeGenOptLevel OptLevel) {
- assert(N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM);
-
- // Don't do anything at less than -O2.
- if (OptLevel < CodeGenOptLevel::Default)
- return SDValue();
-
- SelectionDAG &DAG = DCI.DAG;
- SDLoc DL(N);
- EVT VT = N->getValueType(0);
- bool IsSigned = N->getOpcode() == ISD::SREM;
- unsigned DivOpc = IsSigned ? ISD::SDIV : ISD::UDIV;
-
- const SDValue &Num = N->getOperand(0);
- const SDValue &Den = N->getOperand(1);
-
- for (const SDNode *U : Num->users()) {
- if (U->getOpcode() == DivOpc && U->getOperand(0) == Num &&
- U->getOperand(1) == Den) {
- // Num % Den -> Num - (Num / Den) * Den
- return DAG.getNode(ISD::SUB, DL, VT, Num,
- DAG.getNode(ISD::MUL, DL, VT,
- DAG.getNode(DivOpc, DL, VT, Num, Den),
- Den));
- }
- }
- return SDValue();
-}
-
// sext (mul.iN nsw x, y) => mul.wide.sN x, y
// zext (mul.iN nuw x, y) => mul.wide.uN x, y
// sext (shl.iN nsw x, const) => mul.wide.sN x, (1 << const)
@@ -7121,9 +7093,6 @@ SDValue NVPTXTargetLowering::PerformDAGCombine(SDNode *N,
return PerformSETCCCombine(N, DCI, STI.getSmVersion());
case ISD::SHL:
return PerformSHLCombine(N, DCI, OptLevel);
- case ISD::SREM:
- case ISD::UREM:
- return PerformREMCombine(N, DCI, OptLevel);
case ISD::STORE:
case NVPTXISD::StoreV2:
case NVPTXISD::StoreV4:
diff --git a/llvm/test/CodeGen/X86/divide-by-constant.ll b/llvm/test/CodeGen/X86/divide-by-constant.ll
index d9e19df39f6b6..4dee2fdc872c7 100644
--- a/llvm/test/CodeGen/X86/divide-by-constant.ll
+++ b/llvm/test/CodeGen/X86/divide-by-constant.ll
@@ -410,40 +410,40 @@ define { i64, i32 } @PR38622(i64) nounwind {
; X86-NEXT: pushl %esi
; X86-NEXT: pushl %eax
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
-; X86-NEXT: movl %ecx, %ebx
-; X86-NEXT: shrdl $11, %edi, %ebx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
+; X86-NEXT: movl %ecx, %edi
+; X86-NEXT: shrdl $11, %ebx, %edi
; X86-NEXT: movl $1125899, %edx # imm = 0x112E0B
-; X86-NEXT: movl %ebx, %eax
+; X86-NEXT: movl %edi, %eax
; X86-NEXT: mull %edx
; X86-NEXT: movl %eax, (%esp) # 4-byte Spill
; X86-NEXT: movl %edx, %esi
; X86-NEXT: movl $-400107883, %edx # imm = 0xE826D695
-; X86-NEXT: movl %ebx, %eax
+; X86-NEXT: movl %edi, %eax
; X86-NEXT: mull %edx
; X86-NEXT: movl %edx, %ebp
; X86-NEXT: addl (%esp), %ebp # 4-byte Folded Reload
; X86-NEXT: adcl $0, %esi
-; X86-NEXT: shrl $11, %edi
-; X86-NEXT: movl %edi, %eax
+; X86-NEXT: shrl $11, %ebx
+; X86-NEXT: movl %ebx, %eax
; X86-NEXT: movl $1125899, %edx # imm = 0x112E0B
; X86-NEXT: mull %edx
-; X86-NEXT: movl %edx, %ebx
+; X86-NEXT: movl %edx, %edi
; X86-NEXT: movl %eax, (%esp) # 4-byte Spill
-; X86-NEXT: movl %edi, %eax
+; X86-NEXT: movl %ebx, %eax
; X86-NEXT: movl $-400107883, %edx # imm = 0xE826D695
; X86-NEXT: mull %edx
; X86-NEXT: addl %ebp, %eax
; X86-NEXT: adcl %edx, %esi
-; X86-NEXT: adcl $0, %ebx
+; X86-NEXT: adcl $0, %edi
; X86-NEXT: addl (%esp), %esi # 4-byte Folded Reload
-; X86-NEXT: adcl $0, %ebx
-; X86-NEXT: shrdl $9, %ebx, %esi
+; X86-NEXT: adcl $0, %edi
+; X86-NEXT: shrdl $9, %edi, %esi
; X86-NEXT: imull $-294967296, %esi, %eax # imm = 0xEE6B2800
; X86-NEXT: subl %eax, %ecx
-; X86-NEXT: shrl $9, %ebx
+; X86-NEXT: shrl $9, %edi
; X86-NEXT: movl %esi, %eax
-; X86-NEXT: movl %ebx, %edx
+; X86-NEXT: movl %edi, %edx
; X86-NEXT: addl $4, %esp
; X86-NEXT: popl %esi
; X86-NEXT: popl %edi
@@ -474,35 +474,20 @@ define { i64, i32 } @PR38622(i64) nounwind {
define { i64, i32 } @PR38622_signed(i64) nounwind {
; X86-LABEL: PR38622_signed:
; X86: # %bb.0:
-; X86-NEXT: pushl %ebp
-; X86-NEXT: pushl %ebx
-; X86-NEXT: pushl %edi
; X86-NEXT: pushl %esi
-; X86-NEXT: subl $12, %esp
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp
+; X86-NEXT: subl $8, %esp
+; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
; X86-NEXT: pushl $0
; X86-NEXT: pushl $-294967296 # imm = 0xEE6B2800
-; X86-NEXT: pushl %ebp
-; X86-NEXT: pushl %ebx
+; X86-NEXT: pushl {{[0-9]+}}(%esp)
+; X86-NEXT: pushl %esi
; X86-NEXT: calll __divdi3
; X86-NEXT: addl $16, %esp
-; X86-NEXT: movl %eax, %esi
-; X86-NEXT: movl %edx, %edi
-; X86-NEXT: pushl $0
-; X86-NEXT: pushl $-294967296 # imm = 0xEE6B2800
-; X86-NEXT: pushl %ebp
-; X86-NEXT: pushl %ebx
-; X86-NEXT: calll __moddi3
-; X86-NEXT: addl $16, %esp
-; X86-NEXT: movl %eax, %ecx
-; X86-NEXT: movl %esi, %eax
-; X86-NEXT: movl %edi, %edx
-; X86-NEXT: addl $12, %esp
+; X86-NEXT: imull $-294967296, %eax, %ecx # imm = 0xEE6B2800
+; X86-NEXT: subl %ecx, %esi
+; X86-NEXT: movl %esi, %ecx
+; X86-NEXT: addl $8, %esp
; X86-NEXT: popl %esi
-; X86-NEXT: popl %edi
-; X86-NEXT: popl %ebx
-; X86-NEXT: popl %ebp
; X86-NEXT: retl
;
; X64-LABEL: PR38622_signed:
diff --git a/llvm/test/CodeGen/X86/divrem.ll b/llvm/test/CodeGen/X86/divrem.ll
index ba777b4954611..8e21e75b3f3d8 100644
--- a/llvm/test/CodeGen/X86/divrem.ll
+++ b/llvm/test/CodeGen/X86/divrem.ll
@@ -9,28 +9,34 @@ define void @si64(i64 %x, i64 %y, ptr %p, ptr %q) nounwind {
; X86-NEXT: pushl %ebx
; X86-NEXT: pushl %edi
; X86-NEXT: pushl %esi
+; X86-NEXT: pushl %eax
; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp
+; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
+; X86-NEXT: pushl %edi
+; X86-NEXT: pushl %esi
; X86-NEXT: pushl %ebp
; X86-NEXT: pushl %ebx
-; X86-NEXT: pushl {{[0-9]+}}(%esp)
-; X86-NEXT: pushl {{[0-9]+}}(%esp)
; X86-NEXT: calll __divdi3
; X86-NEXT: addl $16, %esp
-; X86-NEXT: movl %eax, %esi
-; X86-NEXT: movl %edx, %edi
-; X86-NEXT: pushl %ebp
-; X86-NEXT: pushl %ebx
-; X86-NEXT: pushl {{[0-9]+}}(%esp)
-; X86-NEXT: pushl {{[0-9]+}}(%esp)
-; X86-NEXT: calll __moddi3
-; X86-NEXT: addl $16, %esp
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl %edi, 4(%ecx)
-; X86-NEXT: movl %esi, (%ecx)
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl %edx, 4(%ecx)
-; X86-NEXT: movl %eax, (%ecx)
+; X86-NEXT: movl %eax, %ecx
+; X86-NEXT: movl %edx, (%esp) # 4-byte Spill
+; X86-NEXT: imull %eax, %edi
+; X86-NEXT: mull %esi
+; X86-NEXT: addl %edi, %edx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
+; X86-NEXT: movl %ecx, (%edi)
+; X86-NEXT: movl (%esp), %ecx # 4-byte Reload
+; X86-NEXT: movl %ecx, 4(%edi)
+; X86-NEXT: imull %ecx, %esi
+; X86-NEXT: addl %edx, %esi
+; X86-NEXT: subl %eax, %ebx
+; X86-NEXT: sbbl %esi, %ebp
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl %ebx, (%eax)
+; X86-NEXT: movl %ebp, 4(%eax)
+; X86-NEXT: addl $4, %esp
; X86-NEXT: popl %esi
; X86-NEXT: popl %edi
; X86-NEXT: popl %ebx
@@ -150,28 +156,34 @@ define void @ui64(i64 %x, i64 %y, ptr %p, ptr %q) nounwind {
; X86-NEXT: pushl %ebx
; X86-NEXT: pushl %edi
; X86-NEXT: pushl %esi
+; X86-NEXT: pushl %eax
; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp
+; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
+; X86-NEXT: pushl %edi
+; X86-NEXT: pushl %esi
; X86-NEXT: pushl %ebp
; X86-NEXT: pushl %ebx
-; X86-NEXT: pushl {{[0-9]+}}(%esp)
-; X86-NEXT: pushl {{[0-9]+}}(%esp)
; X86-NEXT: calll __udivdi3
; X86-NEXT: addl $16, %esp
-; X86-NEXT: movl %eax, %esi
-; X86-NEXT: movl %edx, %edi
-; X86-NEXT: pushl %ebp
-; X86-NEXT: pushl %ebx
-; X86-NEXT: pushl {{[0-9]+}}(%esp)
-; X86-NEXT: pushl {{[0-9]+}}(%esp)
-; X86-NEXT: calll __umoddi3
-; X86-NEXT: addl $16, %esp
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl %edi, 4(%ecx)
-; X86-NEXT: movl %esi, (%ecx)
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl %edx, 4(%ecx)
-; X86-NEXT: movl %eax, (%ecx)
+; X86-NEXT: movl %eax, %ecx
+; X86-NEXT: movl %edx, (%esp) # 4-byte Spill
+; X86-NEXT: imull %eax, %edi
+; X86-NEXT: mull %esi
+; X86-NEXT: addl %edi, %edx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
+; X86-NEXT: movl %ecx, (%edi)
+; X86-NEXT: movl (%esp), %ecx # 4-byte Reload
+; X86-NEXT: movl %ecx, 4(%edi)
+; X86-NEXT: imull %ecx, %esi
+; X86-NEXT: addl %edx, %esi
+; X86-NEXT: subl %eax, %ebx
+; X86-NEXT: sbbl %esi, %ebp
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl %ebx, (%eax)
+; X86-NEXT: movl %ebp, 4(%eax)
+; X86-NEXT: addl $4, %esp
; X86-NEXT: popl %esi
; X86-NEXT: popl %edi
; X86-NEXT: popl %ebx
>From c8f33aed03b0ec4bd0b54cb9eb65abe37811e0fc Mon Sep 17 00:00:00 2001
From: Ayaan Khan <ayaanandayaan2 at gmail.com>
Date: Sun, 19 Jul 2026 12:16:33 +0530
Subject: [PATCH 2/2] update tests + embed fold logic in visitREM
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 53 +--
llvm/test/CodeGen/ARM/divmod-eabi.ll | 18 +-
llvm/test/CodeGen/Mips/divrem.ll | 64 ++--
llvm/test/CodeGen/NVPTX/divrem-combine.ll | 7 +-
.../test/CodeGen/PowerPC/p10-vector-modulo.ll | 28 +-
llvm/test/CodeGen/PowerPC/ppc64-P9-mod.ll | 10 +-
llvm/test/CodeGen/PowerPC/srem-vector-lkk.ll | 341 ++++++++----------
llvm/test/CodeGen/PowerPC/urem-vector-lkk.ll | 211 +++++------
llvm/test/CodeGen/RISCV/srem-lkk.ll | 42 +--
llvm/test/CodeGen/RISCV/srem-vector-lkk.ll | 108 +++---
llvm/test/CodeGen/RISCV/urem-lkk.ll | 38 +-
llvm/test/CodeGen/RISCV/urem-vector-lkk.ll | 108 +++---
12 files changed, 473 insertions(+), 555 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index f5388a2982bde..ace22b74c592b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -444,7 +444,6 @@ namespace {
SDValue visitSSUBO_CARRY(SDNode *N);
SDValue visitMUL(SDNode *N);
SDValue visitMULFIX(SDNode *N);
- SDValue performREMCombine(SDNode *N);
SDValue useDivRem(SDNode *N);
SDValue visitSDIV(SDNode *N);
SDValue visitSDIVLike(SDValue N0, SDValue N1, SDNode *N);
@@ -5094,38 +5093,6 @@ static bool isDivRemLibcallAvailable(SDNode *Node, bool isSigned,
return DAG.getLibcalls().getLibcallImpl(LC) != RTLIB::Unsupported;
}
-// Fold Num % Den -> Num - (Num / Den) * Den, if (Num / Den) is already
-// computed
-SDValue DAGCombiner::performREMCombine(SDNode *N) {
- assert(N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM);
-
- // Don't do anything at less than -O2.
- if (OptLevel < CodeGenOptLevel::Default)
- return SDValue();
-
- SDLoc DL(N);
- EVT VT = N->getValueType(0);
- bool IsSigned = N->getOpcode() == ISD::SREM;
- unsigned DivOpc = IsSigned ? ISD::SDIV : ISD::UDIV;
- unsigned DivRemOpc = IsSigned ? ISD::SDIVREM : ISD::UDIVREM;
-
- // If DIVREM is available, do not fold
- if (TLI.isOperationLegalOrCustom(DivRemOpc, VT.getScalarType()))
- return SDValue();
-
- const SDValue &Num = N->getOperand(0);
- const SDValue &Den = N->getOperand(1);
- for (const SDNode *U : Num->users()) {
- if (U->getOpcode() == DivOpc && U->getOperand(0) == Num &&
- U->getOperand(1) == Den) {
- SDValue Div = DAG.getNode(DivOpc, DL, VT, Num, Den);
- SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, Div, Den);
- return DAG.getNode(ISD::SUB, DL, VT, Num, Mul);
- }
- }
- return SDValue();
-}
-
/// Issue divrem if both quotient and remainder are needed.
SDValue DAGCombiner::useDivRem(SDNode *Node) {
if (Node->use_empty())
@@ -5596,8 +5563,24 @@ SDValue DAGCombiner::visitREM(SDNode *N) {
}
}
- if (SDValue V = performREMCombine(N))
- return V;
+ // Fold Num % Den -> Num - (Num / Den) * Den, if (Num / Den) is already
+ // computed. Defer for types that will be promoted and do not fold if DIVREM
+ // is available
+ unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM;
+ if (TLI.getTypeAction(*DAG.getContext(), VT) !=
+ TargetLowering::TypePromoteInteger &&
+ !TLI.isOperationLegalOrCustom(DivRemOpc, VT.getScalarType()) &&
+ !isDivRemLibcallAvailable(N, isSigned, DAG)) {
+ unsigned DivOpc = isSigned ? ISD::SDIV : ISD::UDIV;
+ for (const SDNode *U : N0->users()) {
+ if (U->getOpcode() == DivOpc && U->getOperand(0) == N0 &&
+ U->getOperand(1) == N1) {
+ SDValue Div = DAG.getNode(DivOpc, DL, VT, N0, N1);
+ SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, Div, N1);
+ return DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
+ }
+ }
+ }
// sdiv, srem -> sdivrem
if (SDValue DivRem = useDivRem(N))
diff --git a/llvm/test/CodeGen/ARM/divmod-eabi.ll b/llvm/test/CodeGen/ARM/divmod-eabi.ll
index a7bfed7290e2a..e3fd66d4140db 100644
--- a/llvm/test/CodeGen/ARM/divmod-eabi.ll
+++ b/llvm/test/CodeGen/ARM/divmod-eabi.ll
@@ -133,15 +133,21 @@ entry:
; EABI-NEXT: adc r1
; EABI-NOT: __aeabi_ldivmod
; DARWIN: ___divdi3
-; DARWIN: mov [[div1:r[0-9]+]], r0
-; DARWIN: mov [[div2:r[0-9]+]], r1
-; DARWIN: __moddi3
+; DARWIN: umull
+; DARWIN: mla
+; DARWIN: subs
+; DARWIN: mla
+; DARWIN: sbc
; DARWIN-O0: __divdi3
-; DARWIN-O0: __moddi3
+; DARWIN-O0: umull
+; DARWIN-O0: mla
+; DARWIN-O0: mla
+; DARWIN-O0: subs
+; DARWIN-O0: sbc
; WINDOWS: __rt_sdiv64
%add = add nsw i64 %rem, %div
-; DARWIN: adds r0{{.*}}[[div1]]
-; DARWIN: adc r1{{.*}}[[div2]]
+; DARWIN: adds r0
+; DARWIN: adc r1
; WINDOWS: adds r0, r0, r2
; WINDOWS: adcs r1, r3
ret i64 %add
diff --git a/llvm/test/CodeGen/Mips/divrem.ll b/llvm/test/CodeGen/Mips/divrem.ll
index a29f2793c081f..a41e998e54cd7 100644
--- a/llvm/test/CodeGen/Mips/divrem.ll
+++ b/llvm/test/CodeGen/Mips/divrem.ll
@@ -152,20 +152,19 @@ entry:
; ACC64: mfhi $[[R0:[0-9]+]]
; ACC64: sw $[[R0]], 0(${{[0-9]+}})
-; GPR32-DAG: mod $[[R0:[0-9]+]], $4, $5
+; GPR32-DAG: div $[[R0:[0-9]+]], $4, $5
; GPR32-TRAP: teq $5, $zero, 7
+; GPR32-DAG: mul $[[R1:[0-9]+]], $[[R0]], $5
+; GPR32-DAG: subu $[[R2:[0-9]+]], $4, $[[R1]]
; NOCHECK-NOT: teq
-; GPR32: sw $[[R0]], 0(${{[0-9]+}})
-; GPR32-DAG: div $2, $4, $5
-; GPR32-TRAP: teq $5, $zero, 7
+; GPR32: sw $[[R2]], 0(${{[0-9]+}})
-; GPR64-DAG: mod $[[R0:[0-9]+]], $4, $5
-; GPR64-TRAP: teq $5, $zero, 7
-; NOCHECK-NOT: teq
-; GPR64: sw $[[R0]], 0(${{[0-9]+}})
-; GPR64-DAG: div $2, $4, $5
+; GPR64-DAG: div $[[R0:[0-9]+]], $4, $5
; GPR64-TRAP: teq $5, $zero, 7
+; GPR64-DAG: mul $[[R1:[0-9]+]], $[[R0]], $5
+; GPR64-DAG: subu $[[R2:[0-9]+]], $4, $[[R1]]
; NOCHECK-NOT: teq
+; GPR64: sw $[[R2]], 0(${{[0-9]+}})
; ALL: .end sdivrem1
@@ -193,21 +192,20 @@ entry:
; ACC64: mfhi $[[R0:[0-9]+]]
; ACC64: sw $[[R0]], 0(${{[0-9]+}})
-; GPR32-DAG: modu $[[R0:[0-9]+]], $4, $5
-; GPR32-TRAP: teq $5, $zero, 7
-; GPR32: sw $[[R0]], 0(${{[0-9]+}})
-; NOCHECK-NOT: teq
-; GPR32-DAG: divu $2, $4, $5
+; NOCHECK-NOT: mod
+; GPR32-DAG: divu $[[R0:[0-9]+]], $4, $5
; GPR32-TRAP: teq $5, $zero, 7
+; GPR32-DAG: mul $[[R1:[0-9]+]], $[[R0]], $5
+; GPR32-DAG: subu $[[R2:[0-9]+]], $4, $[[R1]]
+; GPR32: sw $[[R2]], 0(${{[0-9]+}})
; NOCHECK-NOT: teq
-; GPR64-DAG: modu $[[R0:[0-9]+]], $4, $5
-; GPR64-TRAP: teq $5, $zero, 7
-; NOCHECK-NOT: teq
-; GPR64: sw $[[R0]], 0(${{[0-9]+}})
-; GPR64-DAG: divu $2, $4, $5
+; GPR64-DAG: divu $[[R0:[0-9]+]], $4, $5
; GPR64-TRAP: teq $5, $zero, 7
+; GPR64-DAG: mul $[[R1:[0-9]+]], $[[R0]], $5
+; GPR64-DAG: subu $[[R2:[0-9]+]], $4, $[[R1]]
; NOCHECK-NOT: teq
+; GPR64: sw $[[R2]], 0(${{[0-9]+}})
; ALL: .end udivrem1
@@ -323,10 +321,10 @@ entry:
; sdivrem2 is too complex to effectively check. We can at least check for the
; calls though.
-; ACC32: lw $25, %call16(__moddi3)(
-; ACC32: jalr $25
; ACC32: lw $25, %call16(__divdi3)(
; ACC32: jalr $25
+; ACC32: mul
+; ACC32: subu
; ACC64: ddiv $zero, $4, $5
; ACC64-TRAP: teq $5, $zero, 7
@@ -335,14 +333,12 @@ entry:
; ACC64: mfhi $[[R0:[0-9]+]]
; ACC64: sd $[[R0]], 0(${{[0-9]+}})
-; GPR64-DAG: dmod $[[R0:[0-9]+]], $4, $5
-; GPR64-TRAP: teq $5, $zero, 7
-; NOCHECK-NOT: teq
-; GPR64: sd $[[R0]], 0(${{[0-9]+}})
-
-; GPR64-DAG: ddiv $2, $4, $5
+; GPR64-DAG: ddiv $[[R0:[0-9]+]], $4, $5
; GPR64-TRAP: teq $5, $zero, 7
; NOCHECK-NOT: teq
+; GPR64-DAG: dmul $[[R1:[0-9]+]], $[[R0]], $5
+; GPR64-DAG: dsubu $[[R2:[0-9]+]], $4, $[[R1]]
+; GPR64: sd $[[R2]], 0(${{[0-9]+}})
; ALL: .end sdivrem2
@@ -358,10 +354,10 @@ entry:
; udivrem2 is too complex to effectively check. We can at least check for the
; calls though.
-; ACC32: lw $25, %call16(__umoddi3)(
-; ACC32: jalr $25
; ACC32: lw $25, %call16(__udivdi3)(
; ACC32: jalr $25
+; ACC32: mul
+; ACC32: subu
; ACC64: ddivu $zero, $4, $5
; ACC64-TRAP: teq $5, $zero, 7
@@ -370,14 +366,12 @@ entry:
; ACC64: mfhi $[[R0:[0-9]+]]
; ACC64: sd $[[R0]], 0(${{[0-9]+}})
-; GPR64: dmodu $[[R0:[0-9]+]], $4, $5
-; GPR64-TRAP: teq $5, $zero, 7
-; NOCHECK-NOT: teq
-; GPR64: sd $[[R0]], 0(${{[0-9]+}})
-
-; GPR64-DAG: ddivu $2, $4, $5
+; GPR64: ddivu $[[R0:[0-9]+]], $4, $5
; GPR64-TRAP: teq $5, $zero, 7
; NOCHECK-NOT: teq
+; GPR64-DAG: dmul $[[R1:[0-9]+]], $[[R0]], $5
+; GPR64-DAG: dsubu $[[R2:[0-9]+]], $4, $[[R1]]
+; GPR64: sd $[[R2]], 0(${{[0-9]+}})
; ALL: .end udivrem2
diff --git a/llvm/test/CodeGen/NVPTX/divrem-combine.ll b/llvm/test/CodeGen/NVPTX/divrem-combine.ll
index f67533fa73dc5..01fad9053cf2d 100644
--- a/llvm/test/CodeGen/NVPTX/divrem-combine.ll
+++ b/llvm/test/CodeGen/NVPTX/divrem-combine.ll
@@ -1,7 +1,5 @@
; RUN: llc -O2 < %s -mtriple=nvptx64 -mcpu=sm_35 | FileCheck %s --check-prefix=O2 --check-prefix=CHECK
-; RUN: llc -O0 < %s -mtriple=nvptx64 -mcpu=sm_35 | FileCheck %s --check-prefix=O0 --check-prefix=CHECK
; RUN: %if ptxas %{ llc -O2 < %s -mtriple=nvptx64 -mcpu=sm_35 | %ptxas-verify %}
-; RUN: %if ptxas %{ llc -O0 < %s -mtriple=nvptx64 -mcpu=sm_35 | %ptxas-verify %}
; The following IR
;
@@ -13,14 +11,13 @@
; quot = n / d
; rem = n - (n / d) * d
;
-; during NVPTX isel, at -O2. At -O0, we should leave it alone.
+; during DAG combining (even at -O0)
; CHECK-LABEL: sdiv32(
define void @sdiv32(i32 %n, i32 %d, ptr %quot_ret, ptr %rem_ret) {
; CHECK: div.s32 [[quot:%r[0-9]+]], [[num:%r[0-9]+]], [[den:%r[0-9]+]];
%quot = sdiv i32 %n, %d
- ; O0: rem.s32
; (This is unfortunately order-sensitive, even though mul is commutative.)
; O2: mul.lo.s32 [[mul:%r[0-9]+]], [[quot]], [[den]];
; O2: sub.s32 [[rem:%r[0-9]+]], [[num]], [[mul]]
@@ -38,8 +35,6 @@ define void @udiv32(i32 %n, i32 %d, ptr %quot_ret, ptr %rem_ret) {
; CHECK: div.u32 [[quot:%r[0-9]+]], [[num:%r[0-9]+]], [[den:%r[0-9]+]];
%quot = udiv i32 %n, %d
- ; O0: rem.u32
-
; Selection DAG doesn't know whether this is signed or unsigned
; multiplication and subtraction, but it doesn't make a difference either
; way.
diff --git a/llvm/test/CodeGen/PowerPC/p10-vector-modulo.ll b/llvm/test/CodeGen/PowerPC/p10-vector-modulo.ll
index 14fcf2460ef3d..292d4ea16cbc1 100644
--- a/llvm/test/CodeGen/PowerPC/p10-vector-modulo.ll
+++ b/llvm/test/CodeGen/PowerPC/p10-vector-modulo.ll
@@ -78,9 +78,10 @@ entry:
define <2 x i64> @test_vmodud_with_div(<2 x i64> %a, <2 x i64> %b) {
; CHECK-LABEL: test_vmodud_with_div:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vmodud v4, v2, v3
-; CHECK-NEXT: vdivud v2, v2, v3
-; CHECK-NEXT: vaddudm v2, v4, v2
+; CHECK-NEXT: vdivud v4, v2, v3
+; CHECK-NEXT: vmulld v3, v4, v3
+; CHECK-NEXT: vsubudm v2, v2, v3
+; CHECK-NEXT: vaddudm v2, v2, v4
; CHECK-NEXT: blr
entry:
%rem = urem <2 x i64> %a, %b
@@ -92,9 +93,10 @@ entry:
define <2 x i64> @test_vmodsd_with_div(<2 x i64> %a, <2 x i64> %b) {
; CHECK-LABEL: test_vmodsd_with_div:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vmodsd v4, v2, v3
-; CHECK-NEXT: vdivsd v2, v2, v3
-; CHECK-NEXT: vaddudm v2, v4, v2
+; CHECK-NEXT: vdivsd v4, v2, v3
+; CHECK-NEXT: vmulld v3, v4, v3
+; CHECK-NEXT: vsubudm v2, v2, v3
+; CHECK-NEXT: vaddudm v2, v2, v4
; CHECK-NEXT: blr
entry:
%rem = srem <2 x i64> %a, %b
@@ -106,9 +108,10 @@ entry:
define <4 x i32> @test_vmoduw_with_div(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: test_vmoduw_with_div:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vmoduw v4, v2, v3
-; CHECK-NEXT: vdivuw v2, v2, v3
-; CHECK-NEXT: vadduwm v2, v4, v2
+; CHECK-NEXT: vdivuw v4, v2, v3
+; CHECK-NEXT: vmuluwm v3, v4, v3
+; CHECK-NEXT: vsubuwm v2, v2, v3
+; CHECK-NEXT: vadduwm v2, v2, v4
; CHECK-NEXT: blr
entry:
%rem = urem <4 x i32> %a, %b
@@ -120,9 +123,10 @@ entry:
define <4 x i32> @test_vmodsw_div(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: test_vmodsw_div:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vmodsw v4, v2, v3
-; CHECK-NEXT: vdivsw v2, v2, v3
-; CHECK-NEXT: vadduwm v2, v4, v2
+; CHECK-NEXT: vdivsw v4, v2, v3
+; CHECK-NEXT: vmuluwm v3, v4, v3
+; CHECK-NEXT: vsubuwm v2, v2, v3
+; CHECK-NEXT: vadduwm v2, v2, v4
; CHECK-NEXT: blr
entry:
%rem = srem <4 x i32> %a, %b
diff --git a/llvm/test/CodeGen/PowerPC/ppc64-P9-mod.ll b/llvm/test/CodeGen/PowerPC/ppc64-P9-mod.ll
index 21a7b214e89cc..6d2f65e187351 100644
--- a/llvm/test/CodeGen/PowerPC/ppc64-P9-mod.ll
+++ b/llvm/test/CodeGen/PowerPC/ppc64-P9-mod.ll
@@ -88,7 +88,10 @@ entry:
store i32 %div, ptr @div_resultsw, align 4
ret void
; CHECK-LABEL: modulo_div_sw
-; CHECK: modsw {{[0-9]+}}, 3, 4
+; CHECK-NOT: modsw
+; CHECK: divw {{[0-9]+}}, 3, 4
+; CHECK: mullw
+; CHECK: sub
; CHECK: blr
; CHECK-DRP-LABEL: modulo_div_sw
; CHECK-DRP-NOT: modsw
@@ -132,7 +135,10 @@ entry:
store i32 %div, ptr @div_resultuw, align 4
ret void
; CHECK-LABEL: modulo_div_uw
-; CHECK: moduw {{[0-9]+}}, 3, 4
+; CHECK-NOT: moduw
+; CHECK: divwu {{[0-9]+}}, 3, 4
+; CHECK: mullw
+; CHECK: sub
; CHECK: blr
; CHECK-DRP-LABEL: modulo_div_uw
; CHECK-DRP-NOT: moduw
diff --git a/llvm/test/CodeGen/PowerPC/srem-vector-lkk.ll b/llvm/test/CodeGen/PowerPC/srem-vector-lkk.ll
index df55b92997765..7243e9842e343 100644
--- a/llvm/test/CodeGen/PowerPC/srem-vector-lkk.ll
+++ b/llvm/test/CodeGen/PowerPC/srem-vector-lkk.ll
@@ -465,125 +465,105 @@ define <4 x i16> @combine_srem_sdiv(<4 x i16> %x) {
; P9LE: # %bb.0:
; P9LE-NEXT: li r3, 0
; P9LE-NEXT: lis r4, -21386
-; P9LE-NEXT: vextuhrx r3, r3, v2
+; P9LE-NEXT: xxspltib v3, 95
; P9LE-NEXT: ori r4, r4, 37253
+; P9LE-NEXT: vextuhrx r3, r3, v2
+; P9LE-NEXT: vxor v4, v4, v4
+; P9LE-NEXT: vupklsb v3, v3
; P9LE-NEXT: extsh r3, r3
; P9LE-NEXT: mulhw r5, r3, r4
-; P9LE-NEXT: add r5, r5, r3
-; P9LE-NEXT: srwi r6, r5, 31
-; P9LE-NEXT: srawi r5, r5, 6
-; P9LE-NEXT: add r5, r5, r6
-; P9LE-NEXT: mulli r6, r5, 95
-; P9LE-NEXT: sub r3, r3, r6
-; P9LE-NEXT: mtvsrd v3, r3
+; P9LE-NEXT: add r3, r5, r3
+; P9LE-NEXT: srwi r5, r3, 31
+; P9LE-NEXT: srawi r3, r3, 6
+; P9LE-NEXT: add r3, r3, r5
+; P9LE-NEXT: mtvsrd v5, r3
; P9LE-NEXT: li r3, 2
; P9LE-NEXT: vextuhrx r3, r3, v2
-; P9LE-NEXT: extsh r6, r3
-; P9LE-NEXT: mulhw r7, r6, r4
-; P9LE-NEXT: add r6, r7, r6
-; P9LE-NEXT: srwi r7, r6, 31
-; P9LE-NEXT: srawi r6, r6, 6
-; P9LE-NEXT: add r6, r6, r7
-; P9LE-NEXT: mulli r7, r6, 95
-; P9LE-NEXT: sub r3, r3, r7
-; P9LE-NEXT: mtvsrd v4, r3
+; P9LE-NEXT: extsh r3, r3
+; P9LE-NEXT: mulhw r5, r3, r4
+; P9LE-NEXT: add r3, r5, r3
+; P9LE-NEXT: srwi r5, r3, 31
+; P9LE-NEXT: srwi r3, r3, 6
+; P9LE-NEXT: add r3, r3, r5
+; P9LE-NEXT: mtvsrd v0, r3
; P9LE-NEXT: li r3, 4
; P9LE-NEXT: vextuhrx r3, r3, v2
-; P9LE-NEXT: vmrghh v3, v4, v3
-; P9LE-NEXT: extsh r7, r3
-; P9LE-NEXT: mulhw r8, r7, r4
-; P9LE-NEXT: add r7, r8, r7
-; P9LE-NEXT: srwi r8, r7, 31
-; P9LE-NEXT: srawi r7, r7, 6
-; P9LE-NEXT: add r7, r7, r8
-; P9LE-NEXT: mulli r8, r7, 95
-; P9LE-NEXT: sub r3, r3, r8
-; P9LE-NEXT: mtvsrd v4, r3
+; P9LE-NEXT: vmrghh v5, v0, v5
+; P9LE-NEXT: extsh r3, r3
+; P9LE-NEXT: mulhw r5, r3, r4
+; P9LE-NEXT: add r3, r5, r3
+; P9LE-NEXT: srwi r5, r3, 31
+; P9LE-NEXT: srwi r3, r3, 6
+; P9LE-NEXT: add r3, r3, r5
+; P9LE-NEXT: mtvsrd v0, r3
; P9LE-NEXT: li r3, 6
; P9LE-NEXT: vextuhrx r3, r3, v2
-; P9LE-NEXT: extsh r8, r3
-; P9LE-NEXT: mulhw r4, r8, r4
-; P9LE-NEXT: add r4, r4, r8
-; P9LE-NEXT: srwi r8, r4, 31
-; P9LE-NEXT: srawi r4, r4, 6
-; P9LE-NEXT: add r4, r4, r8
-; P9LE-NEXT: mulli r8, r4, 95
-; P9LE-NEXT: mtvsrd v5, r4
-; P9LE-NEXT: sub r3, r3, r8
-; P9LE-NEXT: mtvsrd v2, r3
-; P9LE-NEXT: vmrghh v2, v2, v4
-; P9LE-NEXT: mtvsrd v4, r6
-; P9LE-NEXT: xxmrglw v2, v2, v3
-; P9LE-NEXT: mtvsrd v3, r5
-; P9LE-NEXT: vmrghh v3, v4, v3
-; P9LE-NEXT: mtvsrd v4, r7
-; P9LE-NEXT: vmrghh v4, v5, v4
-; P9LE-NEXT: xxmrglw v3, v4, v3
-; P9LE-NEXT: vadduhm v2, v2, v3
+; P9LE-NEXT: extsh r3, r3
+; P9LE-NEXT: mulhw r4, r3, r4
+; P9LE-NEXT: add r3, r4, r3
+; P9LE-NEXT: srwi r4, r3, 31
+; P9LE-NEXT: srwi r3, r3, 6
+; P9LE-NEXT: add r3, r3, r4
+; P9LE-NEXT: mtvsrd v1, r3
+; P9LE-NEXT: vmrghh v0, v1, v0
+; P9LE-NEXT: xxmrglw v5, v0, v5
+; P9LE-NEXT: vmladduhm v3, v5, v3, v4
+; P9LE-NEXT: vsubuhm v2, v2, v3
+; P9LE-NEXT: vadduhm v2, v2, v5
; P9LE-NEXT: blr
;
; P9BE-LABEL: combine_srem_sdiv:
; P9BE: # %bb.0:
; P9BE-NEXT: li r3, 6
-; P9BE-NEXT: lis r5, -21386
+; P9BE-NEXT: lis r4, -21386
+; P9BE-NEXT: xxspltib v3, 95
+; P9BE-NEXT: ori r4, r4, 37253
; P9BE-NEXT: vextuhlx r3, r3, v2
-; P9BE-NEXT: ori r5, r5, 37253
-; P9BE-NEXT: extsh r4, r3
-; P9BE-NEXT: mulhw r6, r4, r5
-; P9BE-NEXT: add r4, r6, r4
-; P9BE-NEXT: srwi r6, r4, 31
-; P9BE-NEXT: srawi r4, r4, 6
-; P9BE-NEXT: add r4, r4, r6
-; P9BE-NEXT: mulli r6, r4, 95
-; P9BE-NEXT: sub r3, r3, r6
+; P9BE-NEXT: vxor v4, v4, v4
+; P9BE-NEXT: vupklsb v3, v3
+; P9BE-NEXT: extsh r3, r3
+; P9BE-NEXT: mulhw r5, r3, r4
+; P9BE-NEXT: add r3, r5, r3
+; P9BE-NEXT: srwi r5, r3, 31
+; P9BE-NEXT: srwi r3, r3, 6
+; P9BE-NEXT: add r3, r3, r5
; P9BE-NEXT: mtfprwz f0, r3
; P9BE-NEXT: li r3, 4
; P9BE-NEXT: vextuhlx r3, r3, v2
-; P9BE-NEXT: extsh r6, r3
-; P9BE-NEXT: mulhw r7, r6, r5
-; P9BE-NEXT: add r6, r7, r6
-; P9BE-NEXT: srwi r7, r6, 31
-; P9BE-NEXT: srawi r6, r6, 6
-; P9BE-NEXT: add r6, r6, r7
-; P9BE-NEXT: mulli r7, r6, 95
-; P9BE-NEXT: sub r3, r3, r7
+; P9BE-NEXT: extsh r3, r3
+; P9BE-NEXT: mulhw r5, r3, r4
+; P9BE-NEXT: add r3, r5, r3
+; P9BE-NEXT: srwi r5, r3, 31
+; P9BE-NEXT: srwi r3, r3, 6
+; P9BE-NEXT: add r3, r3, r5
; P9BE-NEXT: mtfprwz f1, r3
; P9BE-NEXT: addis r3, r2, .LCPI2_0 at toc@ha
; P9BE-NEXT: addi r3, r3, .LCPI2_0 at toc@l
; P9BE-NEXT: lxv vs2, 0(r3)
; P9BE-NEXT: li r3, 2
; P9BE-NEXT: vextuhlx r3, r3, v2
-; P9BE-NEXT: extsh r7, r3
+; P9BE-NEXT: extsh r3, r3
; P9BE-NEXT: xxperm vs0, vs1, vs2
-; P9BE-NEXT: mulhw r8, r7, r5
-; P9BE-NEXT: add r7, r8, r7
-; P9BE-NEXT: srwi r8, r7, 31
-; P9BE-NEXT: srawi r7, r7, 6
-; P9BE-NEXT: add r7, r7, r8
-; P9BE-NEXT: mulli r8, r7, 95
-; P9BE-NEXT: sub r3, r3, r8
+; P9BE-NEXT: mulhw r5, r3, r4
+; P9BE-NEXT: add r3, r5, r3
+; P9BE-NEXT: srwi r5, r3, 31
+; P9BE-NEXT: srwi r3, r3, 6
+; P9BE-NEXT: add r3, r3, r5
; P9BE-NEXT: mtfprwz f1, r3
; P9BE-NEXT: li r3, 0
; P9BE-NEXT: vextuhlx r3, r3, v2
; P9BE-NEXT: extsh r3, r3
-; P9BE-NEXT: mulhw r5, r3, r5
-; P9BE-NEXT: add r5, r5, r3
-; P9BE-NEXT: srwi r8, r5, 31
-; P9BE-NEXT: srawi r5, r5, 6
-; P9BE-NEXT: add r5, r5, r8
-; P9BE-NEXT: mulli r8, r5, 95
-; P9BE-NEXT: sub r3, r3, r8
+; P9BE-NEXT: mulhw r4, r3, r4
+; P9BE-NEXT: add r3, r4, r3
+; P9BE-NEXT: srwi r4, r3, 31
+; P9BE-NEXT: srawi r3, r3, 6
+; P9BE-NEXT: add r3, r3, r4
; P9BE-NEXT: mtfprwz f3, r3
; P9BE-NEXT: xxperm vs1, vs3, vs2
-; P9BE-NEXT: mtfprwz f3, r5
-; P9BE-NEXT: xxmrghw v2, vs1, vs0
-; P9BE-NEXT: mtfprwz f0, r4
-; P9BE-NEXT: mtfprwz f1, r6
-; P9BE-NEXT: xxperm vs0, vs1, vs2
-; P9BE-NEXT: mtfprwz f1, r7
-; P9BE-NEXT: xxperm vs1, vs3, vs2
-; P9BE-NEXT: xxmrghw v3, vs1, vs0
-; P9BE-NEXT: vadduhm v2, v2, v3
+; P9BE-NEXT: xxmrghw v5, vs1, vs0
+; P9BE-NEXT: vmladduhm v3, v5, v3, v4
+; P9BE-NEXT: vsubuhm v2, v2, v3
+; P9BE-NEXT: vadduhm v2, v2, v5
; P9BE-NEXT: blr
;
; P8LE-LABEL: combine_srem_sdiv:
@@ -592,118 +572,101 @@ define <4 x i16> @combine_srem_sdiv(<4 x i16> %x) {
; P8LE-NEXT: lis r4, -21386
; P8LE-NEXT: mffprd r3, f0
; P8LE-NEXT: ori r4, r4, 37253
+; P8LE-NEXT: clrldi r5, r3, 48
; P8LE-NEXT: rldicl r6, r3, 48, 48
; P8LE-NEXT: rldicl r7, r3, 32, 48
-; P8LE-NEXT: clrldi r5, r3, 48
; P8LE-NEXT: rldicl r3, r3, 16, 48
-; P8LE-NEXT: extsh r8, r6
-; P8LE-NEXT: extsh r9, r7
; P8LE-NEXT: extsh r5, r5
-; P8LE-NEXT: extsh r10, r3
-; P8LE-NEXT: mulhw r11, r8, r4
-; P8LE-NEXT: add r8, r11, r8
-; P8LE-NEXT: mulhw r11, r9, r4
-; P8LE-NEXT: add r9, r11, r9
-; P8LE-NEXT: mulhw r11, r5, r4
-; P8LE-NEXT: mulhw r4, r10, r4
-; P8LE-NEXT: add r11, r11, r5
-; P8LE-NEXT: add r4, r4, r10
-; P8LE-NEXT: srwi r10, r11, 31
-; P8LE-NEXT: srawi r11, r11, 6
-; P8LE-NEXT: add r10, r11, r10
-; P8LE-NEXT: srwi r11, r8, 31
-; P8LE-NEXT: srawi r8, r8, 6
-; P8LE-NEXT: add r8, r8, r11
-; P8LE-NEXT: srwi r11, r9, 31
-; P8LE-NEXT: srawi r9, r9, 6
-; P8LE-NEXT: mtvsrd v2, r10
-; P8LE-NEXT: add r9, r9, r11
-; P8LE-NEXT: srwi r11, r4, 31
-; P8LE-NEXT: srawi r4, r4, 6
-; P8LE-NEXT: mtvsrd v3, r8
-; P8LE-NEXT: add r4, r4, r11
-; P8LE-NEXT: mulli r11, r10, 95
-; P8LE-NEXT: sub r5, r5, r11
-; P8LE-NEXT: mulli r11, r8, 95
+; P8LE-NEXT: extsh r6, r6
+; P8LE-NEXT: extsh r7, r7
+; P8LE-NEXT: extsh r3, r3
+; P8LE-NEXT: mulhw r8, r5, r4
+; P8LE-NEXT: add r5, r8, r5
+; P8LE-NEXT: mulhw r8, r6, r4
+; P8LE-NEXT: add r6, r8, r6
+; P8LE-NEXT: mulhw r8, r7, r4
+; P8LE-NEXT: mulhw r4, r3, r4
+; P8LE-NEXT: add r3, r4, r3
+; P8LE-NEXT: srwi r4, r5, 31
+; P8LE-NEXT: srawi r5, r5, 6
+; P8LE-NEXT: add r7, r8, r7
+; P8LE-NEXT: add r4, r5, r4
+; P8LE-NEXT: srwi r5, r6, 31
+; P8LE-NEXT: srwi r6, r6, 6
+; P8LE-NEXT: add r5, r6, r5
+; P8LE-NEXT: mtvsrd v3, r4
+; P8LE-NEXT: srwi r4, r3, 31
+; P8LE-NEXT: srwi r3, r3, 6
+; P8LE-NEXT: srwi r6, r7, 31
+; P8LE-NEXT: srwi r7, r7, 6
; P8LE-NEXT: mtvsrd v4, r5
-; P8LE-NEXT: sub r6, r6, r11
-; P8LE-NEXT: mulli r11, r9, 95
+; P8LE-NEXT: add r3, r3, r4
+; P8LE-NEXT: add r6, r7, r6
; P8LE-NEXT: mtvsrd v5, r6
-; P8LE-NEXT: sub r7, r7, r11
-; P8LE-NEXT: mulli r11, r4, 95
-; P8LE-NEXT: mtvsrd v0, r7
-; P8LE-NEXT: sub r3, r3, r11
-; P8LE-NEXT: vmrghh v2, v3, v2
-; P8LE-NEXT: mtvsrd v3, r9
-; P8LE-NEXT: vmrghh v4, v5, v4
-; P8LE-NEXT: mtvsrd v5, r3
-; P8LE-NEXT: vmrghh v5, v5, v0
-; P8LE-NEXT: mtvsrd v0, r4
-; P8LE-NEXT: xxmrglw v4, v5, v4
-; P8LE-NEXT: vmrghh v3, v0, v3
-; P8LE-NEXT: xxmrglw v2, v3, v2
-; P8LE-NEXT: vadduhm v2, v4, v2
+; P8LE-NEXT: vmrghh v3, v4, v3
+; P8LE-NEXT: mtvsrd v4, r3
+; P8LE-NEXT: addis r3, r2, .LCPI2_0 at toc@ha
+; P8LE-NEXT: addi r3, r3, .LCPI2_0 at toc@l
+; P8LE-NEXT: lxvd2x vs0, 0, r3
+; P8LE-NEXT: vmrghh v4, v4, v5
+; P8LE-NEXT: xxmrglw v3, v4, v3
+; P8LE-NEXT: vxor v4, v4, v4
+; P8LE-NEXT: xxswapd v5, vs0
+; P8LE-NEXT: vmladduhm v4, v3, v5, v4
+; P8LE-NEXT: vsubuhm v2, v2, v4
+; P8LE-NEXT: vadduhm v2, v2, v3
; P8LE-NEXT: blr
;
; P8BE-LABEL: combine_srem_sdiv:
; P8BE: # %bb.0:
-; P8BE-NEXT: mfvsrd r4, v2
-; P8BE-NEXT: lis r5, -21386
-; P8BE-NEXT: ori r5, r5, 37253
-; P8BE-NEXT: clrldi r3, r4, 48
-; P8BE-NEXT: rldicl r6, r4, 48, 48
-; P8BE-NEXT: rldicl r7, r4, 32, 48
-; P8BE-NEXT: rldicl r4, r4, 16, 48
-; P8BE-NEXT: extsh r8, r3
-; P8BE-NEXT: extsh r9, r6
-; P8BE-NEXT: extsh r10, r7
-; P8BE-NEXT: extsh r4, r4
-; P8BE-NEXT: mulhw r11, r8, r5
-; P8BE-NEXT: add r8, r11, r8
-; P8BE-NEXT: mulhw r11, r9, r5
-; P8BE-NEXT: add r9, r11, r9
-; P8BE-NEXT: mulhw r11, r10, r5
-; P8BE-NEXT: mulhw r5, r4, r5
-; P8BE-NEXT: add r10, r11, r10
-; P8BE-NEXT: srwi r11, r8, 31
-; P8BE-NEXT: srawi r8, r8, 6
-; P8BE-NEXT: add r5, r5, r4
-; P8BE-NEXT: add r8, r8, r11
-; P8BE-NEXT: srwi r11, r9, 31
-; P8BE-NEXT: srawi r9, r9, 6
-; P8BE-NEXT: add r9, r9, r11
-; P8BE-NEXT: srwi r11, r10, 31
-; P8BE-NEXT: srawi r10, r10, 6
-; P8BE-NEXT: mtvsrwz v3, r8
-; P8BE-NEXT: add r10, r10, r11
-; P8BE-NEXT: srwi r11, r5, 31
-; P8BE-NEXT: srawi r5, r5, 6
-; P8BE-NEXT: mtvsrwz v4, r9
-; P8BE-NEXT: add r5, r5, r11
-; P8BE-NEXT: mulli r11, r8, 95
-; P8BE-NEXT: sub r3, r3, r11
-; P8BE-NEXT: mulli r11, r9, 95
-; P8BE-NEXT: mtvsrwz v5, r3
-; P8BE-NEXT: sub r6, r6, r11
-; P8BE-NEXT: mulli r11, r10, 95
+; P8BE-NEXT: mfvsrd r3, v2
+; P8BE-NEXT: lis r4, -21386
+; P8BE-NEXT: ori r4, r4, 37253
+; P8BE-NEXT: clrldi r5, r3, 48
+; P8BE-NEXT: rldicl r6, r3, 48, 48
+; P8BE-NEXT: rldicl r7, r3, 32, 48
+; P8BE-NEXT: rldicl r3, r3, 16, 48
+; P8BE-NEXT: extsh r5, r5
+; P8BE-NEXT: extsh r6, r6
+; P8BE-NEXT: extsh r7, r7
+; P8BE-NEXT: extsh r3, r3
+; P8BE-NEXT: mulhw r8, r5, r4
+; P8BE-NEXT: add r5, r8, r5
+; P8BE-NEXT: mulhw r8, r6, r4
+; P8BE-NEXT: add r6, r8, r6
+; P8BE-NEXT: mulhw r8, r7, r4
+; P8BE-NEXT: mulhw r4, r3, r4
+; P8BE-NEXT: add r3, r4, r3
+; P8BE-NEXT: addis r4, r2, .LCPI2_1 at toc@ha
+; P8BE-NEXT: add r7, r8, r7
+; P8BE-NEXT: addi r4, r4, .LCPI2_1 at toc@l
+; P8BE-NEXT: lxvw4x v3, 0, r4
+; P8BE-NEXT: srwi r4, r5, 31
+; P8BE-NEXT: srwi r5, r5, 6
+; P8BE-NEXT: add r4, r5, r4
+; P8BE-NEXT: srwi r5, r6, 31
+; P8BE-NEXT: srwi r6, r6, 6
+; P8BE-NEXT: add r5, r6, r5
+; P8BE-NEXT: mtvsrwz v4, r4
+; P8BE-NEXT: srwi r6, r7, 31
+; P8BE-NEXT: srwi r7, r7, 6
+; P8BE-NEXT: srwi r4, r3, 31
+; P8BE-NEXT: srawi r3, r3, 6
+; P8BE-NEXT: mtvsrwz v5, r5
+; P8BE-NEXT: add r6, r7, r6
+; P8BE-NEXT: add r3, r3, r4
; P8BE-NEXT: mtvsrwz v0, r6
-; P8BE-NEXT: sub r7, r7, r11
-; P8BE-NEXT: mulli r11, r5, 95
-; P8BE-NEXT: mtvsrwz v1, r7
-; P8BE-NEXT: sub r4, r4, r11
-; P8BE-NEXT: addis r11, r2, .LCPI2_0 at toc@ha
-; P8BE-NEXT: addi r11, r11, .LCPI2_0 at toc@l
-; P8BE-NEXT: lxvw4x v2, 0, r11
-; P8BE-NEXT: vperm v5, v0, v5, v2
-; P8BE-NEXT: mtvsrwz v0, r4
-; P8BE-NEXT: vperm v3, v4, v3, v2
-; P8BE-NEXT: mtvsrwz v4, r10
-; P8BE-NEXT: vperm v0, v0, v1, v2
-; P8BE-NEXT: mtvsrwz v1, r5
-; P8BE-NEXT: vperm v2, v1, v4, v2
-; P8BE-NEXT: xxmrghw v4, v0, v5
-; P8BE-NEXT: xxmrghw v2, v2, v3
-; P8BE-NEXT: vadduhm v2, v4, v2
+; P8BE-NEXT: vperm v4, v5, v4, v3
+; P8BE-NEXT: mtvsrwz v5, r3
+; P8BE-NEXT: addis r3, r2, .LCPI2_0 at toc@ha
+; P8BE-NEXT: addi r3, r3, .LCPI2_0 at toc@l
+; P8BE-NEXT: vperm v3, v5, v0, v3
+; P8BE-NEXT: vxor v5, v5, v5
+; P8BE-NEXT: xxmrghw v3, v3, v4
+; P8BE-NEXT: lxvw4x v4, 0, r3
+; P8BE-NEXT: vmladduhm v4, v3, v4, v5
+; P8BE-NEXT: vsubuhm v2, v2, v4
+; P8BE-NEXT: vadduhm v2, v2, v3
; P8BE-NEXT: blr
%1 = srem <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
%2 = sdiv <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
diff --git a/llvm/test/CodeGen/PowerPC/urem-vector-lkk.ll b/llvm/test/CodeGen/PowerPC/urem-vector-lkk.ll
index 98314a02c23fe..c07e500ec5a03 100644
--- a/llvm/test/CodeGen/PowerPC/urem-vector-lkk.ll
+++ b/llvm/test/CodeGen/PowerPC/urem-vector-lkk.ll
@@ -345,93 +345,73 @@ define <4 x i16> @combine_urem_udiv(<4 x i16> %x) {
; P9LE: # %bb.0:
; P9LE-NEXT: li r3, 0
; P9LE-NEXT: lis r4, 689
-; P9LE-NEXT: vextuhrx r3, r3, v2
+; P9LE-NEXT: xxspltib v3, 95
; P9LE-NEXT: ori r4, r4, 55879
+; P9LE-NEXT: vextuhrx r3, r3, v2
+; P9LE-NEXT: vxor v4, v4, v4
+; P9LE-NEXT: vupklsb v3, v3
; P9LE-NEXT: clrlwi r3, r3, 16
-; P9LE-NEXT: mulhwu r5, r3, r4
-; P9LE-NEXT: mulli r6, r5, 95
-; P9LE-NEXT: sub r3, r3, r6
-; P9LE-NEXT: mtvsrd v3, r3
+; P9LE-NEXT: mulhwu r3, r3, r4
+; P9LE-NEXT: mtvsrd v5, r3
; P9LE-NEXT: li r3, 2
; P9LE-NEXT: vextuhrx r3, r3, v2
-; P9LE-NEXT: clrlwi r6, r3, 16
-; P9LE-NEXT: mulhwu r6, r6, r4
-; P9LE-NEXT: mulli r7, r6, 95
-; P9LE-NEXT: sub r3, r3, r7
-; P9LE-NEXT: mtvsrd v4, r3
+; P9LE-NEXT: clrlwi r3, r3, 16
+; P9LE-NEXT: mulhwu r3, r3, r4
+; P9LE-NEXT: mtvsrd v0, r3
; P9LE-NEXT: li r3, 4
; P9LE-NEXT: vextuhrx r3, r3, v2
-; P9LE-NEXT: vmrghh v3, v4, v3
-; P9LE-NEXT: clrlwi r7, r3, 16
-; P9LE-NEXT: mulhwu r7, r7, r4
-; P9LE-NEXT: mulli r8, r7, 95
-; P9LE-NEXT: sub r3, r3, r8
-; P9LE-NEXT: mtvsrd v4, r3
+; P9LE-NEXT: vmrghh v5, v0, v5
+; P9LE-NEXT: clrlwi r3, r3, 16
+; P9LE-NEXT: mulhwu r3, r3, r4
+; P9LE-NEXT: mtvsrd v0, r3
; P9LE-NEXT: li r3, 6
; P9LE-NEXT: vextuhrx r3, r3, v2
-; P9LE-NEXT: clrlwi r8, r3, 16
-; P9LE-NEXT: mulhwu r4, r8, r4
-; P9LE-NEXT: mulli r8, r4, 95
-; P9LE-NEXT: mtvsrd v5, r4
-; P9LE-NEXT: sub r3, r3, r8
-; P9LE-NEXT: mtvsrd v2, r3
-; P9LE-NEXT: vmrghh v2, v2, v4
-; P9LE-NEXT: mtvsrd v4, r6
-; P9LE-NEXT: xxmrglw v2, v2, v3
-; P9LE-NEXT: mtvsrd v3, r5
-; P9LE-NEXT: vmrghh v3, v4, v3
-; P9LE-NEXT: mtvsrd v4, r7
-; P9LE-NEXT: vmrghh v4, v5, v4
-; P9LE-NEXT: xxmrglw v3, v4, v3
-; P9LE-NEXT: vadduhm v2, v2, v3
+; P9LE-NEXT: clrlwi r3, r3, 16
+; P9LE-NEXT: mulhwu r3, r3, r4
+; P9LE-NEXT: mtvsrd v1, r3
+; P9LE-NEXT: vmrghh v0, v1, v0
+; P9LE-NEXT: xxmrglw v5, v0, v5
+; P9LE-NEXT: vmladduhm v3, v5, v3, v4
+; P9LE-NEXT: vsubuhm v2, v2, v3
+; P9LE-NEXT: vadduhm v2, v2, v5
; P9LE-NEXT: blr
;
; P9BE-LABEL: combine_urem_udiv:
; P9BE: # %bb.0:
; P9BE-NEXT: li r3, 6
-; P9BE-NEXT: lis r5, 689
+; P9BE-NEXT: lis r4, 689
+; P9BE-NEXT: xxspltib v3, 95
+; P9BE-NEXT: ori r4, r4, 55879
; P9BE-NEXT: vextuhlx r3, r3, v2
-; P9BE-NEXT: ori r5, r5, 55879
-; P9BE-NEXT: clrlwi r4, r3, 16
-; P9BE-NEXT: mulhwu r4, r4, r5
-; P9BE-NEXT: mulli r6, r4, 95
-; P9BE-NEXT: sub r3, r3, r6
+; P9BE-NEXT: vxor v4, v4, v4
+; P9BE-NEXT: vupklsb v3, v3
+; P9BE-NEXT: clrlwi r3, r3, 16
+; P9BE-NEXT: mulhwu r3, r3, r4
; P9BE-NEXT: mtfprwz f0, r3
; P9BE-NEXT: li r3, 4
; P9BE-NEXT: vextuhlx r3, r3, v2
-; P9BE-NEXT: clrlwi r6, r3, 16
-; P9BE-NEXT: mulhwu r6, r6, r5
-; P9BE-NEXT: mulli r7, r6, 95
-; P9BE-NEXT: sub r3, r3, r7
+; P9BE-NEXT: clrlwi r3, r3, 16
+; P9BE-NEXT: mulhwu r3, r3, r4
; P9BE-NEXT: mtfprwz f1, r3
; P9BE-NEXT: addis r3, r2, .LCPI2_0 at toc@ha
; P9BE-NEXT: addi r3, r3, .LCPI2_0 at toc@l
; P9BE-NEXT: lxv vs2, 0(r3)
; P9BE-NEXT: li r3, 2
; P9BE-NEXT: vextuhlx r3, r3, v2
-; P9BE-NEXT: clrlwi r7, r3, 16
+; P9BE-NEXT: clrlwi r3, r3, 16
; P9BE-NEXT: xxperm vs0, vs1, vs2
-; P9BE-NEXT: mulhwu r7, r7, r5
-; P9BE-NEXT: mulli r8, r7, 95
-; P9BE-NEXT: sub r3, r3, r8
+; P9BE-NEXT: mulhwu r3, r3, r4
; P9BE-NEXT: mtfprwz f1, r3
; P9BE-NEXT: li r3, 0
; P9BE-NEXT: vextuhlx r3, r3, v2
; P9BE-NEXT: clrlwi r3, r3, 16
-; P9BE-NEXT: mulhwu r5, r3, r5
-; P9BE-NEXT: mulli r8, r5, 95
-; P9BE-NEXT: sub r3, r3, r8
+; P9BE-NEXT: mulhwu r3, r3, r4
; P9BE-NEXT: mtfprwz f3, r3
; P9BE-NEXT: xxperm vs1, vs3, vs2
-; P9BE-NEXT: mtfprwz f3, r5
-; P9BE-NEXT: xxmrghw v2, vs1, vs0
-; P9BE-NEXT: mtfprwz f0, r4
-; P9BE-NEXT: mtfprwz f1, r6
-; P9BE-NEXT: xxperm vs0, vs1, vs2
-; P9BE-NEXT: mtfprwz f1, r7
-; P9BE-NEXT: xxperm vs1, vs3, vs2
-; P9BE-NEXT: xxmrghw v3, vs1, vs0
-; P9BE-NEXT: vadduhm v2, v2, v3
+; P9BE-NEXT: xxmrghw v5, vs1, vs0
+; P9BE-NEXT: vmladduhm v3, v5, v3, v4
+; P9BE-NEXT: vsubuhm v2, v2, v3
+; P9BE-NEXT: vadduhm v2, v2, v5
; P9BE-NEXT: blr
;
; P8LE-LABEL: combine_urem_udiv:
@@ -441,85 +421,68 @@ define <4 x i16> @combine_urem_udiv(<4 x i16> %x) {
; P8LE-NEXT: mffprd r3, f0
; P8LE-NEXT: ori r4, r4, 55879
; P8LE-NEXT: clrldi r5, r3, 48
-; P8LE-NEXT: rldicl r6, r3, 48, 48
-; P8LE-NEXT: rldicl r7, r3, 32, 48
-; P8LE-NEXT: rldicl r3, r3, 16, 48
; P8LE-NEXT: clrlwi r5, r5, 16
-; P8LE-NEXT: clrlwi r8, r6, 16
-; P8LE-NEXT: clrlwi r9, r7, 16
-; P8LE-NEXT: clrlwi r10, r3, 16
-; P8LE-NEXT: mulhwu r11, r5, r4
-; P8LE-NEXT: mulhwu r8, r8, r4
-; P8LE-NEXT: mulhwu r9, r9, r4
-; P8LE-NEXT: mulhwu r4, r10, r4
-; P8LE-NEXT: mulli r10, r11, 95
-; P8LE-NEXT: mtvsrd v2, r11
-; P8LE-NEXT: mtvsrd v3, r8
-; P8LE-NEXT: sub r5, r5, r10
-; P8LE-NEXT: mulli r10, r8, 95
+; P8LE-NEXT: mulhwu r5, r5, r4
+; P8LE-NEXT: mtvsrd v3, r5
+; P8LE-NEXT: rldicl r5, r3, 48, 48
+; P8LE-NEXT: clrlwi r5, r5, 16
+; P8LE-NEXT: mulhwu r5, r5, r4
; P8LE-NEXT: mtvsrd v4, r5
-; P8LE-NEXT: sub r6, r6, r10
-; P8LE-NEXT: mulli r10, r9, 95
-; P8LE-NEXT: mtvsrd v5, r6
-; P8LE-NEXT: sub r7, r7, r10
-; P8LE-NEXT: mulli r10, r4, 95
-; P8LE-NEXT: mtvsrd v0, r7
-; P8LE-NEXT: sub r3, r3, r10
-; P8LE-NEXT: vmrghh v2, v3, v2
-; P8LE-NEXT: mtvsrd v3, r9
-; P8LE-NEXT: vmrghh v4, v5, v4
-; P8LE-NEXT: mtvsrd v5, r3
-; P8LE-NEXT: vmrghh v5, v5, v0
-; P8LE-NEXT: mtvsrd v0, r4
-; P8LE-NEXT: xxmrglw v4, v5, v4
-; P8LE-NEXT: vmrghh v3, v0, v3
-; P8LE-NEXT: xxmrglw v2, v3, v2
-; P8LE-NEXT: vadduhm v2, v4, v2
+; P8LE-NEXT: rldicl r5, r3, 32, 48
+; P8LE-NEXT: rldicl r3, r3, 16, 48
+; P8LE-NEXT: clrlwi r3, r3, 16
+; P8LE-NEXT: clrlwi r5, r5, 16
+; P8LE-NEXT: mulhwu r3, r3, r4
+; P8LE-NEXT: mulhwu r5, r5, r4
+; P8LE-NEXT: mtvsrd v5, r5
+; P8LE-NEXT: vmrghh v3, v4, v3
+; P8LE-NEXT: mtvsrd v4, r3
+; P8LE-NEXT: addis r3, r2, .LCPI2_0 at toc@ha
+; P8LE-NEXT: addi r3, r3, .LCPI2_0 at toc@l
+; P8LE-NEXT: lxvd2x vs0, 0, r3
+; P8LE-NEXT: vmrghh v4, v4, v5
+; P8LE-NEXT: xxmrglw v3, v4, v3
+; P8LE-NEXT: vxor v4, v4, v4
+; P8LE-NEXT: xxswapd v5, vs0
+; P8LE-NEXT: vmladduhm v4, v3, v5, v4
+; P8LE-NEXT: vsubuhm v2, v2, v4
+; P8LE-NEXT: vadduhm v2, v2, v3
; P8LE-NEXT: blr
;
; P8BE-LABEL: combine_urem_udiv:
; P8BE: # %bb.0:
; P8BE-NEXT: mfvsrd r3, v2
+; P8BE-NEXT: addis r5, r2, .LCPI2_1 at toc@ha
; P8BE-NEXT: lis r4, 689
+; P8BE-NEXT: addi r5, r5, .LCPI2_1 at toc@l
; P8BE-NEXT: ori r4, r4, 55879
+; P8BE-NEXT: lxvw4x v3, 0, r5
; P8BE-NEXT: clrldi r5, r3, 48
-; P8BE-NEXT: rldicl r6, r3, 48, 48
-; P8BE-NEXT: rldicl r7, r3, 32, 48
+; P8BE-NEXT: clrlwi r5, r5, 16
+; P8BE-NEXT: mulhwu r5, r5, r4
+; P8BE-NEXT: mtvsrwz v4, r5
+; P8BE-NEXT: rldicl r5, r3, 48, 48
+; P8BE-NEXT: clrlwi r5, r5, 16
+; P8BE-NEXT: mulhwu r5, r5, r4
+; P8BE-NEXT: mtvsrwz v5, r5
+; P8BE-NEXT: rldicl r5, r3, 32, 48
; P8BE-NEXT: rldicl r3, r3, 16, 48
-; P8BE-NEXT: clrlwi r8, r5, 16
-; P8BE-NEXT: clrlwi r9, r6, 16
-; P8BE-NEXT: clrlwi r10, r7, 16
+; P8BE-NEXT: clrlwi r5, r5, 16
; P8BE-NEXT: clrlwi r3, r3, 16
-; P8BE-NEXT: mulhwu r8, r8, r4
-; P8BE-NEXT: mulhwu r9, r9, r4
-; P8BE-NEXT: mulhwu r10, r10, r4
-; P8BE-NEXT: mulhwu r4, r3, r4
-; P8BE-NEXT: mulli r11, r8, 95
-; P8BE-NEXT: mtvsrwz v3, r8
-; P8BE-NEXT: mtvsrwz v4, r9
-; P8BE-NEXT: sub r5, r5, r11
-; P8BE-NEXT: mulli r11, r9, 95
-; P8BE-NEXT: mtvsrwz v5, r5
-; P8BE-NEXT: sub r6, r6, r11
-; P8BE-NEXT: mulli r11, r10, 95
-; P8BE-NEXT: mtvsrwz v0, r6
-; P8BE-NEXT: sub r7, r7, r11
-; P8BE-NEXT: mulli r11, r4, 95
-; P8BE-NEXT: mtvsrwz v1, r7
-; P8BE-NEXT: sub r3, r3, r11
-; P8BE-NEXT: addis r11, r2, .LCPI2_0 at toc@ha
-; P8BE-NEXT: addi r11, r11, .LCPI2_0 at toc@l
-; P8BE-NEXT: lxvw4x v2, 0, r11
-; P8BE-NEXT: vperm v5, v0, v5, v2
-; P8BE-NEXT: mtvsrwz v0, r3
-; P8BE-NEXT: vperm v3, v4, v3, v2
-; P8BE-NEXT: mtvsrwz v4, r10
-; P8BE-NEXT: vperm v0, v0, v1, v2
-; P8BE-NEXT: mtvsrwz v1, r4
-; P8BE-NEXT: vperm v2, v1, v4, v2
-; P8BE-NEXT: xxmrghw v4, v0, v5
-; P8BE-NEXT: xxmrghw v2, v2, v3
-; P8BE-NEXT: vadduhm v2, v4, v2
+; P8BE-NEXT: mulhwu r5, r5, r4
+; P8BE-NEXT: mulhwu r3, r3, r4
+; P8BE-NEXT: mtvsrwz v0, r5
+; P8BE-NEXT: vperm v4, v5, v4, v3
+; P8BE-NEXT: mtvsrwz v5, r3
+; P8BE-NEXT: addis r3, r2, .LCPI2_0 at toc@ha
+; P8BE-NEXT: addi r3, r3, .LCPI2_0 at toc@l
+; P8BE-NEXT: vperm v3, v5, v0, v3
+; P8BE-NEXT: vxor v5, v5, v5
+; P8BE-NEXT: xxmrghw v3, v3, v4
+; P8BE-NEXT: lxvw4x v4, 0, r3
+; P8BE-NEXT: vmladduhm v4, v3, v4, v5
+; P8BE-NEXT: vsubuhm v2, v2, v4
+; P8BE-NEXT: vadduhm v2, v2, v3
; P8BE-NEXT: blr
%1 = urem <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
%2 = udiv <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
diff --git a/llvm/test/CodeGen/RISCV/srem-lkk.ll b/llvm/test/CodeGen/RISCV/srem-lkk.ll
index b6e7684695aef..976f231cae36b 100644
--- a/llvm/test/CodeGen/RISCV/srem-lkk.ll
+++ b/llvm/test/CodeGen/RISCV/srem-lkk.ll
@@ -213,18 +213,17 @@ define i32 @combine_srem_sdiv(i32 %x) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
-; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: call __modsi3
-; RV32I-NEXT: mv s1, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: call __divsi3
-; RV32I-NEXT: add a0, s1, a0
+; RV32I-NEXT: slli a1, a0, 5
+; RV32I-NEXT: slli a2, a0, 7
+; RV32I-NEXT: add a1, a0, a1
+; RV32I-NEXT: sub s0, s0, a2
+; RV32I-NEXT: add a1, s0, a1
+; RV32I-NEXT: add a0, a1, a0
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
-; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
@@ -244,23 +243,22 @@ define i32 @combine_srem_sdiv(i32 %x) nounwind {
;
; RV64I-LABEL: combine_srem_sdiv:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -32
-; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
-; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
-; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: sext.w s0, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s0
-; RV64I-NEXT: call __moddi3
-; RV64I-NEXT: mv s1, a0
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
+; RV64I-NEXT: mv s0, a0
+; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: call __divdi3
-; RV64I-NEXT: addw a0, s1, a0
-; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
-; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
-; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 32
+; RV64I-NEXT: slli a1, a0, 5
+; RV64I-NEXT: slli a2, a0, 7
+; RV64I-NEXT: add a1, a0, a1
+; RV64I-NEXT: sub s0, s0, a2
+; RV64I-NEXT: add a1, s0, a1
+; RV64I-NEXT: addw a0, a1, a0
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IM-LABEL: combine_srem_sdiv:
diff --git a/llvm/test/CodeGen/RISCV/srem-vector-lkk.ll b/llvm/test/CodeGen/RISCV/srem-vector-lkk.ll
index 0cf8df1288e4b..907e31090d85d 100644
--- a/llvm/test/CodeGen/RISCV/srem-vector-lkk.ll
+++ b/llvm/test/CodeGen/RISCV/srem-vector-lkk.ll
@@ -375,7 +375,6 @@ define <4 x i16> @combine_srem_sdiv(<4 x i16> %x) nounwind {
; RV32I-NEXT: sw s5, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s6, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s7, 12(sp) # 4-byte Folded Spill
-; RV32I-NEXT: sw s8, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: lh s1, 0(a1)
; RV32I-NEXT: lh s2, 4(a1)
; RV32I-NEXT: lh s3, 8(a1)
@@ -383,43 +382,47 @@ define <4 x i16> @combine_srem_sdiv(<4 x i16> %x) nounwind {
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: li a1, 95
; RV32I-NEXT: mv a0, s4
-; RV32I-NEXT: call __modsi3
+; RV32I-NEXT: call __divsi3
; RV32I-NEXT: mv s5, a0
+; RV32I-NEXT: slli a0, a0, 5
+; RV32I-NEXT: slli a1, s5, 7
+; RV32I-NEXT: add a0, s5, a0
+; RV32I-NEXT: sub a1, s4, a1
+; RV32I-NEXT: add s6, a1, a0
; RV32I-NEXT: li a1, 95
; RV32I-NEXT: mv a0, s3
-; RV32I-NEXT: call __modsi3
-; RV32I-NEXT: mv s6, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s2
-; RV32I-NEXT: call __modsi3
-; RV32I-NEXT: mv s7, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s1
-; RV32I-NEXT: call __modsi3
-; RV32I-NEXT: mv s8, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s4
; RV32I-NEXT: call __divsi3
; RV32I-NEXT: mv s4, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s3
-; RV32I-NEXT: call __divsi3
-; RV32I-NEXT: mv s3, a0
+; RV32I-NEXT: slli a0, a0, 5
+; RV32I-NEXT: slli a1, s4, 7
+; RV32I-NEXT: add a0, s4, a0
+; RV32I-NEXT: sub a1, s3, a1
+; RV32I-NEXT: add s7, a1, a0
; RV32I-NEXT: li a1, 95
; RV32I-NEXT: mv a0, s2
; RV32I-NEXT: call __divsi3
-; RV32I-NEXT: mv s2, a0
+; RV32I-NEXT: mv s3, a0
+; RV32I-NEXT: slli a0, a0, 5
+; RV32I-NEXT: slli a1, s3, 7
+; RV32I-NEXT: add a0, s3, a0
+; RV32I-NEXT: sub a1, s2, a1
+; RV32I-NEXT: add s2, a1, a0
; RV32I-NEXT: li a1, 95
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: call __divsi3
-; RV32I-NEXT: add s2, s7, s2
-; RV32I-NEXT: add s3, s6, s3
-; RV32I-NEXT: add a0, s8, a0
-; RV32I-NEXT: add s4, s5, s4
+; RV32I-NEXT: add s2, s2, s3
+; RV32I-NEXT: slli a1, a0, 5
+; RV32I-NEXT: slli a2, a0, 7
+; RV32I-NEXT: add a1, a0, a1
+; RV32I-NEXT: sub s1, s1, a2
+; RV32I-NEXT: add s4, s7, s4
+; RV32I-NEXT: add a1, s1, a1
+; RV32I-NEXT: add s5, s6, s5
+; RV32I-NEXT: add a0, a1, a0
; RV32I-NEXT: sh a0, 0(s0)
; RV32I-NEXT: sh s2, 2(s0)
-; RV32I-NEXT: sh s3, 4(s0)
-; RV32I-NEXT: sh s4, 6(s0)
+; RV32I-NEXT: sh s4, 4(s0)
+; RV32I-NEXT: sh s5, 6(s0)
; RV32I-NEXT: lw ra, 44(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 40(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 36(sp) # 4-byte Folded Reload
@@ -429,7 +432,6 @@ define <4 x i16> @combine_srem_sdiv(<4 x i16> %x) nounwind {
; RV32I-NEXT: lw s5, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s6, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s7, 12(sp) # 4-byte Folded Reload
-; RV32I-NEXT: lw s8, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 48
; RV32I-NEXT: ret
;
@@ -488,7 +490,6 @@ define <4 x i16> @combine_srem_sdiv(<4 x i16> %x) nounwind {
; RV64I-NEXT: sd s5, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s6, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s7, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: sd s8, 0(sp) # 8-byte Folded Spill
; RV64I-NEXT: lh s1, 0(a1)
; RV64I-NEXT: lh s2, 8(a1)
; RV64I-NEXT: lh s3, 16(a1)
@@ -496,43 +497,47 @@ define <4 x i16> @combine_srem_sdiv(<4 x i16> %x) nounwind {
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: li a1, 95
; RV64I-NEXT: mv a0, s4
-; RV64I-NEXT: call __moddi3
+; RV64I-NEXT: call __divdi3
; RV64I-NEXT: mv s5, a0
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: slli a1, s5, 7
+; RV64I-NEXT: add a0, s5, a0
+; RV64I-NEXT: sub a1, s4, a1
+; RV64I-NEXT: add s6, a1, a0
; RV64I-NEXT: li a1, 95
; RV64I-NEXT: mv a0, s3
-; RV64I-NEXT: call __moddi3
-; RV64I-NEXT: mv s6, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s2
-; RV64I-NEXT: call __moddi3
-; RV64I-NEXT: mv s7, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s1
-; RV64I-NEXT: call __moddi3
-; RV64I-NEXT: mv s8, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s4
; RV64I-NEXT: call __divdi3
; RV64I-NEXT: mv s4, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s3
-; RV64I-NEXT: call __divdi3
-; RV64I-NEXT: mv s3, a0
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: slli a1, s4, 7
+; RV64I-NEXT: add a0, s4, a0
+; RV64I-NEXT: sub a1, s3, a1
+; RV64I-NEXT: add s7, a1, a0
; RV64I-NEXT: li a1, 95
; RV64I-NEXT: mv a0, s2
; RV64I-NEXT: call __divdi3
-; RV64I-NEXT: mv s2, a0
+; RV64I-NEXT: mv s3, a0
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: slli a1, s3, 7
+; RV64I-NEXT: add a0, s3, a0
+; RV64I-NEXT: sub a1, s2, a1
+; RV64I-NEXT: add s2, a1, a0
; RV64I-NEXT: li a1, 95
; RV64I-NEXT: mv a0, s1
; RV64I-NEXT: call __divdi3
-; RV64I-NEXT: add s2, s7, s2
-; RV64I-NEXT: add s3, s6, s3
-; RV64I-NEXT: add a0, s8, a0
-; RV64I-NEXT: add s4, s5, s4
+; RV64I-NEXT: add s2, s2, s3
+; RV64I-NEXT: slli a1, a0, 5
+; RV64I-NEXT: slli a2, a0, 7
+; RV64I-NEXT: add a1, a0, a1
+; RV64I-NEXT: sub s1, s1, a2
+; RV64I-NEXT: add s4, s7, s4
+; RV64I-NEXT: add a1, s1, a1
+; RV64I-NEXT: add s5, s6, s5
+; RV64I-NEXT: add a0, a1, a0
; RV64I-NEXT: sh a0, 0(s0)
; RV64I-NEXT: sh s2, 2(s0)
-; RV64I-NEXT: sh s3, 4(s0)
-; RV64I-NEXT: sh s4, 6(s0)
+; RV64I-NEXT: sh s4, 4(s0)
+; RV64I-NEXT: sh s5, 6(s0)
; RV64I-NEXT: ld ra, 72(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 64(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 56(sp) # 8-byte Folded Reload
@@ -542,7 +547,6 @@ define <4 x i16> @combine_srem_sdiv(<4 x i16> %x) nounwind {
; RV64I-NEXT: ld s5, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s6, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s7, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: ld s8, 0(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 80
; RV64I-NEXT: ret
;
diff --git a/llvm/test/CodeGen/RISCV/urem-lkk.ll b/llvm/test/CodeGen/RISCV/urem-lkk.ll
index 3d533db169c0d..32a267568b6de 100644
--- a/llvm/test/CodeGen/RISCV/urem-lkk.ll
+++ b/llvm/test/CodeGen/RISCV/urem-lkk.ll
@@ -109,18 +109,17 @@ define i32 @combine_urem_udiv(i32 %x) nounwind {
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
-; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: call __umodsi3
-; RV32I-NEXT: mv s1, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: call __udivsi3
-; RV32I-NEXT: add a0, s1, a0
+; RV32I-NEXT: slli a1, a0, 5
+; RV32I-NEXT: slli a2, a0, 7
+; RV32I-NEXT: add a1, a0, a1
+; RV32I-NEXT: sub s0, s0, a2
+; RV32I-NEXT: add a1, s0, a1
+; RV32I-NEXT: add a0, a1, a0
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
-; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
@@ -141,24 +140,23 @@ define i32 @combine_urem_udiv(i32 %x) nounwind {
;
; RV64I-LABEL: combine_urem_udiv:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -32
-; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
-; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
-; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: srli s0, a0, 32
; RV64I-NEXT: li a1, 95
; RV64I-NEXT: mv a0, s0
-; RV64I-NEXT: call __umoddi3
-; RV64I-NEXT: mv s1, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: call __udivdi3
-; RV64I-NEXT: add a0, s1, a0
-; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
-; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
-; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 32
+; RV64I-NEXT: slli a1, a0, 5
+; RV64I-NEXT: slli a2, a0, 7
+; RV64I-NEXT: add a1, a0, a1
+; RV64I-NEXT: sub s0, s0, a2
+; RV64I-NEXT: add a1, s0, a1
+; RV64I-NEXT: add a0, a1, a0
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IM-LABEL: combine_urem_udiv:
diff --git a/llvm/test/CodeGen/RISCV/urem-vector-lkk.ll b/llvm/test/CodeGen/RISCV/urem-vector-lkk.ll
index f8325770a766b..b1a095c0f3aea 100644
--- a/llvm/test/CodeGen/RISCV/urem-vector-lkk.ll
+++ b/llvm/test/CodeGen/RISCV/urem-vector-lkk.ll
@@ -328,7 +328,6 @@ define <4 x i16> @combine_urem_udiv(<4 x i16> %x) nounwind {
; RV32I-NEXT: sw s5, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s6, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s7, 12(sp) # 4-byte Folded Spill
-; RV32I-NEXT: sw s8, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: lhu s1, 0(a1)
; RV32I-NEXT: lhu s2, 4(a1)
; RV32I-NEXT: lhu s3, 8(a1)
@@ -336,43 +335,47 @@ define <4 x i16> @combine_urem_udiv(<4 x i16> %x) nounwind {
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: li a1, 95
; RV32I-NEXT: mv a0, s4
-; RV32I-NEXT: call __umodsi3
+; RV32I-NEXT: call __udivsi3
; RV32I-NEXT: mv s5, a0
+; RV32I-NEXT: slli a0, a0, 5
+; RV32I-NEXT: slli a1, s5, 7
+; RV32I-NEXT: add a0, s5, a0
+; RV32I-NEXT: sub a1, s4, a1
+; RV32I-NEXT: add s6, a1, a0
; RV32I-NEXT: li a1, 95
; RV32I-NEXT: mv a0, s3
-; RV32I-NEXT: call __umodsi3
-; RV32I-NEXT: mv s6, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s2
-; RV32I-NEXT: call __umodsi3
-; RV32I-NEXT: mv s7, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s1
-; RV32I-NEXT: call __umodsi3
-; RV32I-NEXT: mv s8, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s4
; RV32I-NEXT: call __udivsi3
; RV32I-NEXT: mv s4, a0
-; RV32I-NEXT: li a1, 95
-; RV32I-NEXT: mv a0, s3
-; RV32I-NEXT: call __udivsi3
-; RV32I-NEXT: mv s3, a0
+; RV32I-NEXT: slli a0, a0, 5
+; RV32I-NEXT: slli a1, s4, 7
+; RV32I-NEXT: add a0, s4, a0
+; RV32I-NEXT: sub a1, s3, a1
+; RV32I-NEXT: add s7, a1, a0
; RV32I-NEXT: li a1, 95
; RV32I-NEXT: mv a0, s2
; RV32I-NEXT: call __udivsi3
-; RV32I-NEXT: mv s2, a0
+; RV32I-NEXT: mv s3, a0
+; RV32I-NEXT: slli a0, a0, 5
+; RV32I-NEXT: slli a1, s3, 7
+; RV32I-NEXT: add a0, s3, a0
+; RV32I-NEXT: sub a1, s2, a1
+; RV32I-NEXT: add s2, a1, a0
; RV32I-NEXT: li a1, 95
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: call __udivsi3
-; RV32I-NEXT: add s2, s7, s2
-; RV32I-NEXT: add s3, s6, s3
-; RV32I-NEXT: add a0, s8, a0
-; RV32I-NEXT: add s4, s5, s4
+; RV32I-NEXT: add s2, s2, s3
+; RV32I-NEXT: slli a1, a0, 5
+; RV32I-NEXT: slli a2, a0, 7
+; RV32I-NEXT: add a1, a0, a1
+; RV32I-NEXT: sub s1, s1, a2
+; RV32I-NEXT: add s4, s7, s4
+; RV32I-NEXT: add a1, s1, a1
+; RV32I-NEXT: add s5, s6, s5
+; RV32I-NEXT: add a0, a1, a0
; RV32I-NEXT: sh a0, 0(s0)
; RV32I-NEXT: sh s2, 2(s0)
-; RV32I-NEXT: sh s3, 4(s0)
-; RV32I-NEXT: sh s4, 6(s0)
+; RV32I-NEXT: sh s4, 4(s0)
+; RV32I-NEXT: sh s5, 6(s0)
; RV32I-NEXT: lw ra, 44(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 40(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 36(sp) # 4-byte Folded Reload
@@ -382,7 +385,6 @@ define <4 x i16> @combine_urem_udiv(<4 x i16> %x) nounwind {
; RV32I-NEXT: lw s5, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s6, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s7, 12(sp) # 4-byte Folded Reload
-; RV32I-NEXT: lw s8, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 48
; RV32I-NEXT: ret
;
@@ -429,7 +431,6 @@ define <4 x i16> @combine_urem_udiv(<4 x i16> %x) nounwind {
; RV64I-NEXT: sd s5, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s6, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s7, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: sd s8, 0(sp) # 8-byte Folded Spill
; RV64I-NEXT: lhu s1, 0(a1)
; RV64I-NEXT: lhu s2, 8(a1)
; RV64I-NEXT: lhu s3, 16(a1)
@@ -437,43 +438,47 @@ define <4 x i16> @combine_urem_udiv(<4 x i16> %x) nounwind {
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: li a1, 95
; RV64I-NEXT: mv a0, s4
-; RV64I-NEXT: call __umoddi3
+; RV64I-NEXT: call __udivdi3
; RV64I-NEXT: mv s5, a0
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: slli a1, s5, 7
+; RV64I-NEXT: add a0, s5, a0
+; RV64I-NEXT: sub a1, s4, a1
+; RV64I-NEXT: add s6, a1, a0
; RV64I-NEXT: li a1, 95
; RV64I-NEXT: mv a0, s3
-; RV64I-NEXT: call __umoddi3
-; RV64I-NEXT: mv s6, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s2
-; RV64I-NEXT: call __umoddi3
-; RV64I-NEXT: mv s7, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s1
-; RV64I-NEXT: call __umoddi3
-; RV64I-NEXT: mv s8, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s4
; RV64I-NEXT: call __udivdi3
; RV64I-NEXT: mv s4, a0
-; RV64I-NEXT: li a1, 95
-; RV64I-NEXT: mv a0, s3
-; RV64I-NEXT: call __udivdi3
-; RV64I-NEXT: mv s3, a0
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: slli a1, s4, 7
+; RV64I-NEXT: add a0, s4, a0
+; RV64I-NEXT: sub a1, s3, a1
+; RV64I-NEXT: add s7, a1, a0
; RV64I-NEXT: li a1, 95
; RV64I-NEXT: mv a0, s2
; RV64I-NEXT: call __udivdi3
-; RV64I-NEXT: mv s2, a0
+; RV64I-NEXT: mv s3, a0
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: slli a1, s3, 7
+; RV64I-NEXT: add a0, s3, a0
+; RV64I-NEXT: sub a1, s2, a1
+; RV64I-NEXT: add s2, a1, a0
; RV64I-NEXT: li a1, 95
; RV64I-NEXT: mv a0, s1
; RV64I-NEXT: call __udivdi3
-; RV64I-NEXT: add s2, s7, s2
-; RV64I-NEXT: add s3, s6, s3
-; RV64I-NEXT: add a0, s8, a0
-; RV64I-NEXT: add s4, s5, s4
+; RV64I-NEXT: add s2, s2, s3
+; RV64I-NEXT: slli a1, a0, 5
+; RV64I-NEXT: slli a2, a0, 7
+; RV64I-NEXT: add a1, a0, a1
+; RV64I-NEXT: sub s1, s1, a2
+; RV64I-NEXT: add s4, s7, s4
+; RV64I-NEXT: add a1, s1, a1
+; RV64I-NEXT: add s5, s6, s5
+; RV64I-NEXT: add a0, a1, a0
; RV64I-NEXT: sh a0, 0(s0)
; RV64I-NEXT: sh s2, 2(s0)
-; RV64I-NEXT: sh s3, 4(s0)
-; RV64I-NEXT: sh s4, 6(s0)
+; RV64I-NEXT: sh s4, 4(s0)
+; RV64I-NEXT: sh s5, 6(s0)
; RV64I-NEXT: ld ra, 72(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 64(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 56(sp) # 8-byte Folded Reload
@@ -483,7 +488,6 @@ define <4 x i16> @combine_urem_udiv(<4 x i16> %x) nounwind {
; RV64I-NEXT: ld s5, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s6, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s7, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: ld s8, 0(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 80
; RV64I-NEXT: ret
;
More information about the llvm-commits
mailing list