[llvm] b5c106e - [RISCV][GlobalISel] Legalize division and remainder

Nitin John Raj via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 17 14:42:03 PDT 2023


Author: Nitin John Raj
Date: 2023-08-17T14:41:40-07:00
New Revision: b5c106e873f780b2f54fec9817acfd252724bcb3

URL: https://github.com/llvm/llvm-project/commit/b5c106e873f780b2f54fec9817acfd252724bcb3
DIFF: https://github.com/llvm/llvm-project/commit/b5c106e873f780b2f54fec9817acfd252724bcb3.diff

LOG: [RISCV][GlobalISel] Legalize division and remainder

Legalize division and remainder. We test for (s7, s8, s16, s32, s48, s64) on rv64 and (s8, s15, s16, s32, s64, s72, s128) on rv64, with and without the +m, +zmmul extensions. We do not handle types with size > 2 x XLen -- these ought to be handled in the IR pass.

Reviewed By: craig.topper

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

Added: 
    llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-div.mir
    llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-rem.mir
    llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-div.mir
    llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-rem.mir

Modified: 
    llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index b382ae750b8b12..68473fd73b71c5 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -113,5 +113,18 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
     getActionDefinitionsBuilder({G_SMULH, G_UMULH}).lowerFor({XLenLLT});
   }
 
+  if (ST.hasStdExtM()) {
+    getActionDefinitionsBuilder({G_UDIV, G_SDIV, G_UREM, G_SREM})
+        .legalFor({XLenLLT})
+        .libcallFor({DoubleXLenLLT})
+        .clampScalar(0, XLenLLT, DoubleXLenLLT)
+        .widenScalarToNextPow2(0);
+  } else {
+    getActionDefinitionsBuilder({G_UDIV, G_SDIV, G_UREM, G_SREM})
+        .libcallFor({XLenLLT, DoubleXLenLLT})
+        .clampScalar(0, XLenLLT, DoubleXLenLLT)
+        .widenScalarToNextPow2(0);
+  }
+
   getLegacyLegalizerInfo().computeTables();
 }

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-div.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-div.mir
new file mode 100644
index 00000000000000..bc2ced0bc1c466
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-div.mir
@@ -0,0 +1,493 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s -check-prefix=CHECK-I
+# RUN: llc -mattr=+m -mtriple=riscv32 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s -check-prefix=CHECK-M
+---
+name:            sdiv_i7
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i7
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 7
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 7
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i7
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 7
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 7
+    ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SDIV]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s7) = G_TRUNC %0(s32)
+    %3:_(s7) = G_TRUNC %1(s32)
+    %4:_(s7) = G_SDIV %2, %3
+    %5:_(s32) = G_ANYEXT %4(s7)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            sdiv_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i8
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 8
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 8
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i8
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 8
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 8
+    ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SDIV]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s8) = G_TRUNC %0(s32)
+    %3:_(s8) = G_TRUNC %1(s32)
+    %4:_(s8) = G_SDIV %2, %3
+    %5:_(s32) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            sdiv_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i16
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 16
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 16
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i16
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 16
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 16
+    ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SDIV]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s16) = G_TRUNC %0(s32)
+    %3:_(s16) = G_TRUNC %1(s32)
+    %4:_(s16) = G_SDIV %2, %3
+    %5:_(s32) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            sdiv_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i32
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i32
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[COPY]], [[COPY1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SDIV]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s32) = G_SDIV %0, %1
+    $x10 = COPY %2(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            sdiv_i48
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i48
+    ; CHECK-I: %xhi:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: %xlo:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: %yhi:_(s32) = COPY $x12
+    ; CHECK-I-NEXT: %ylo:_(s32) = COPY $x13
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG %xlo, 16
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG %ylo, 16
+    ; CHECK-I-NEXT: $x10 = COPY %xhi(s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-I-NEXT: $x12 = COPY %yhi(s32)
+    ; CHECK-I-NEXT: $x13 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i48
+    ; CHECK-M: %xhi:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: %xlo:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: %yhi:_(s32) = COPY $x12
+    ; CHECK-M-NEXT: %ylo:_(s32) = COPY $x13
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG %xlo, 16
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG %ylo, 16
+    ; CHECK-M-NEXT: $x10 = COPY %xhi(s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-M-NEXT: $x12 = COPY %yhi(s32)
+    ; CHECK-M-NEXT: $x13 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %xhi:_(s32) = COPY $x10
+    %xlo:_(s32) = COPY $x11
+    %yhi:_(s32) = COPY $x12
+    %ylo:_(s32) = COPY $x13
+    %x0:_(s64) = G_MERGE_VALUES %xhi(s32), %xlo(s32)
+    %y0:_(s64) = G_MERGE_VALUES %yhi(s32), %ylo(s32)
+    %x:_(s48) = G_TRUNC %x0
+    %y:_(s48) = G_TRUNC %y0
+    %z:_(s48) = G_SDIV %x, %y
+    %z0:_(s64) = G_ANYEXT %z
+    %zhi:_(s32), %zlo:_(s32) = G_UNMERGE_VALUES %z0(s64)
+    $x10 = COPY %zhi(s32)
+    $x11 = COPY %zlo(s32)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            sdiv_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i64
+    ; CHECK-I: %hi1:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-I-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-I-NEXT: $x10 = COPY %hi1(s32)
+    ; CHECK-I-NEXT: $x11 = COPY %lo1(s32)
+    ; CHECK-I-NEXT: $x12 = COPY %hi2(s32)
+    ; CHECK-I-NEXT: $x13 = COPY %lo2(s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i64
+    ; CHECK-M: %hi1:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-M-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-M-NEXT: $x10 = COPY %hi1(s32)
+    ; CHECK-M-NEXT: $x11 = COPY %lo1(s32)
+    ; CHECK-M-NEXT: $x12 = COPY %hi2(s32)
+    ; CHECK-M-NEXT: $x13 = COPY %lo2(s32)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %hi1:_(s32) = COPY $x10
+    %lo1:_(s32) = COPY $x11
+    %hi2:_(s32) = COPY $x12
+    %lo2:_(s32) = COPY $x13
+    %x1:_(s64) = G_MERGE_VALUES %hi1(s32), %lo1(s32)
+    %x2:_(s64) = G_MERGE_VALUES %hi2(s32), %lo2(s32)
+    %y:_(s64) = G_SDIV %x1, %x2
+    %hiy:_(s32), %loy:_(s32) = G_UNMERGE_VALUES %y(s64)
+    $x10 = COPY %hiy(s32)
+    $x11 = COPY %loy(s32)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            udiv_i7
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i7
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: udiv_i7
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UDIV]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s7) = G_TRUNC %0(s32)
+    %3:_(s7) = G_TRUNC %1(s32)
+    %4:_(s7) = G_UDIV %2, %3
+    %5:_(s32) = G_ANYEXT %4(s7)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            udiv_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i8
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: udiv_i8
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UDIV]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s8) = G_TRUNC %0(s32)
+    %3:_(s8) = G_TRUNC %1(s32)
+    %4:_(s8) = G_UDIV %2, %3
+    %5:_(s32) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            udiv_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i16
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: udiv_i16
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UDIV]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s16) = G_TRUNC %0(s32)
+    %3:_(s16) = G_TRUNC %1(s32)
+    %4:_(s16) = G_UDIV %2, %3
+    %5:_(s32) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            udiv_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i32
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: udiv_i32
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[COPY]], [[COPY1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UDIV]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s32) = G_UDIV %0, %1
+    $x10 = COPY %2(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            udiv_i48
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i48
+    ; CHECK-I: %xhi:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: %xlo:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: %yhi:_(s32) = COPY $x12
+    ; CHECK-I-NEXT: %ylo:_(s32) = COPY $x13
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND %xhi, [[C]]
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND %xlo, [[C1]]
+    ; CHECK-I-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-I-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-I-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND %yhi, [[C2]]
+    ; CHECK-I-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND %ylo, [[C3]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-I-NEXT: $x12 = COPY [[AND2]](s32)
+    ; CHECK-I-NEXT: $x13 = COPY [[AND3]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: udiv_i48
+    ; CHECK-M: %xhi:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: %xlo:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: %yhi:_(s32) = COPY $x12
+    ; CHECK-M-NEXT: %ylo:_(s32) = COPY $x13
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND %xhi, [[C]]
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND %xlo, [[C1]]
+    ; CHECK-M-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-M-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-M-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND %yhi, [[C2]]
+    ; CHECK-M-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND %ylo, [[C3]]
+    ; CHECK-M-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-M-NEXT: $x12 = COPY [[AND2]](s32)
+    ; CHECK-M-NEXT: $x13 = COPY [[AND3]](s32)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %xhi:_(s32) = COPY $x10
+    %xlo:_(s32) = COPY $x11
+    %yhi:_(s32) = COPY $x12
+    %ylo:_(s32) = COPY $x13
+    %x0:_(s64) = G_MERGE_VALUES %xhi(s32), %xlo(s32)
+    %y0:_(s64) = G_MERGE_VALUES %yhi(s32), %ylo(s32)
+    %x:_(s48) = G_TRUNC %x0
+    %y:_(s48) = G_TRUNC %y0
+    %z:_(s48) = G_UDIV %x, %y
+    %z0:_(s64) = G_ANYEXT %z
+    %zhi:_(s32), %zlo:_(s32) = G_UNMERGE_VALUES %z0(s64)
+    $x10 = COPY %zhi(s32)
+    $x11 = COPY %zlo(s32)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            udiv_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i64
+    ; CHECK-I: %hi1:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-I-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-I-NEXT: $x10 = COPY %hi1(s32)
+    ; CHECK-I-NEXT: $x11 = COPY %lo1(s32)
+    ; CHECK-I-NEXT: $x12 = COPY %hi2(s32)
+    ; CHECK-I-NEXT: $x13 = COPY %lo2(s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: udiv_i64
+    ; CHECK-M: %hi1:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-M-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-M-NEXT: $x10 = COPY %hi1(s32)
+    ; CHECK-M-NEXT: $x11 = COPY %lo1(s32)
+    ; CHECK-M-NEXT: $x12 = COPY %hi2(s32)
+    ; CHECK-M-NEXT: $x13 = COPY %lo2(s32)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %hi1:_(s32) = COPY $x10
+    %lo1:_(s32) = COPY $x11
+    %hi2:_(s32) = COPY $x12
+    %lo2:_(s32) = COPY $x13
+    %x1:_(s64) = G_MERGE_VALUES %hi1(s32), %lo1(s32)
+    %x2:_(s64) = G_MERGE_VALUES %hi2(s32), %lo2(s32)
+    %y:_(s64) = G_UDIV %x1, %x2
+    %hiy:_(s32), %loy:_(s32) = G_UNMERGE_VALUES %y(s64)
+    $x10 = COPY %hiy(s32)
+    $x11 = COPY %loy(s32)
+    PseudoRET implicit $x10, implicit $x11
+
+...

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-rem.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-rem.mir
new file mode 100644
index 00000000000000..20a9c3daf4598d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-rem.mir
@@ -0,0 +1,493 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s -check-prefix=CHECK-I
+# RUN: llc -mattr=+m -mtriple=riscv32 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s -check-prefix=CHECK-M
+---
+name:            srem_i7
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i7
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 7
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 7
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__modsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: srem_i7
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 7
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 7
+    ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s7) = G_TRUNC %0(s32)
+    %3:_(s7) = G_TRUNC %1(s32)
+    %4:_(s7) = G_SREM %2, %3
+    %5:_(s32) = G_ANYEXT %4(s7)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            srem_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i8
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 8
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 8
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__modsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: srem_i8
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 8
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 8
+    ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s8) = G_TRUNC %0(s32)
+    %3:_(s8) = G_TRUNC %1(s32)
+    %4:_(s8) = G_SREM %2, %3
+    %5:_(s32) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            srem_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i16
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 16
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 16
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__modsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: srem_i16
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 16
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY1]], 16
+    ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s16) = G_TRUNC %0(s32)
+    %3:_(s16) = G_TRUNC %1(s32)
+    %4:_(s16) = G_SREM %2, %3
+    %5:_(s32) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            srem_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i32
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__modsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: srem_i32
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[COPY]], [[COPY1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s32) = G_SREM %0, %1
+    $x10 = COPY %2(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            srem_i48
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i48
+    ; CHECK-I: %xhi:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: %xlo:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: %yhi:_(s32) = COPY $x12
+    ; CHECK-I-NEXT: %ylo:_(s32) = COPY $x13
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG %xlo, 16
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG %ylo, 16
+    ; CHECK-I-NEXT: $x10 = COPY %xhi(s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-I-NEXT: $x12 = COPY %yhi(s32)
+    ; CHECK-I-NEXT: $x13 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: srem_i48
+    ; CHECK-M: %xhi:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: %xlo:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: %yhi:_(s32) = COPY $x12
+    ; CHECK-M-NEXT: %ylo:_(s32) = COPY $x13
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG %xlo, 16
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG %ylo, 16
+    ; CHECK-M-NEXT: $x10 = COPY %xhi(s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[SEXT_INREG]](s32)
+    ; CHECK-M-NEXT: $x12 = COPY %yhi(s32)
+    ; CHECK-M-NEXT: $x13 = COPY [[SEXT_INREG1]](s32)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %xhi:_(s32) = COPY $x10
+    %xlo:_(s32) = COPY $x11
+    %yhi:_(s32) = COPY $x12
+    %ylo:_(s32) = COPY $x13
+    %x0:_(s64) = G_MERGE_VALUES %xhi(s32), %xlo(s32)
+    %y0:_(s64) = G_MERGE_VALUES %yhi(s32), %ylo(s32)
+    %x:_(s48) = G_TRUNC %x0
+    %y:_(s48) = G_TRUNC %y0
+    %z:_(s48) = G_SREM %x, %y
+    %z0:_(s64) = G_ANYEXT %z
+    %zhi:_(s32), %zlo:_(s32) = G_UNMERGE_VALUES %z0(s64)
+    $x10 = COPY %zhi(s32)
+    $x11 = COPY %zlo(s32)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            srem_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i64
+    ; CHECK-I: %hi1:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-I-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-I-NEXT: $x10 = COPY %hi1(s32)
+    ; CHECK-I-NEXT: $x11 = COPY %lo1(s32)
+    ; CHECK-I-NEXT: $x12 = COPY %hi2(s32)
+    ; CHECK-I-NEXT: $x13 = COPY %lo2(s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: srem_i64
+    ; CHECK-M: %hi1:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-M-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-M-NEXT: $x10 = COPY %hi1(s32)
+    ; CHECK-M-NEXT: $x11 = COPY %lo1(s32)
+    ; CHECK-M-NEXT: $x12 = COPY %hi2(s32)
+    ; CHECK-M-NEXT: $x13 = COPY %lo2(s32)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %hi1:_(s32) = COPY $x10
+    %lo1:_(s32) = COPY $x11
+    %hi2:_(s32) = COPY $x12
+    %lo2:_(s32) = COPY $x13
+    %x1:_(s64) = G_MERGE_VALUES %hi1(s32), %lo1(s32)
+    %x2:_(s64) = G_MERGE_VALUES %hi2(s32), %lo2(s32)
+    %y:_(s64) = G_SREM %x1, %x2
+    %hiy:_(s32), %loy:_(s32) = G_UNMERGE_VALUES %y(s64)
+    $x10 = COPY %hiy(s32)
+    $x11 = COPY %loy(s32)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            urem_i7
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i7
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umodsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: urem_i7
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s32) = G_UREM [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UREM]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s7) = G_TRUNC %0(s32)
+    %3:_(s7) = G_TRUNC %1(s32)
+    %4:_(s7) = G_UREM %2, %3
+    %5:_(s32) = G_ANYEXT %4(s7)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            urem_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i8
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umodsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: urem_i8
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s32) = G_UREM [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UREM]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s8) = G_TRUNC %0(s32)
+    %3:_(s8) = G_TRUNC %1(s32)
+    %4:_(s8) = G_UREM %2, %3
+    %5:_(s32) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            urem_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i16
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umodsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: urem_i16
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s32) = G_UREM [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UREM]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s16) = G_TRUNC %0(s32)
+    %3:_(s16) = G_TRUNC %1(s32)
+    %4:_(s16) = G_UREM %2, %3
+    %5:_(s32) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            urem_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i32
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umodsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: urem_i32
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s32) = G_UREM [[COPY]], [[COPY1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UREM]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s32) = G_UREM %0, %1
+    $x10 = COPY %2(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            urem_i48
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i48
+    ; CHECK-I: %xhi:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: %xlo:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: %yhi:_(s32) = COPY $x12
+    ; CHECK-I-NEXT: %ylo:_(s32) = COPY $x13
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND %xhi, [[C]]
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND %xlo, [[C1]]
+    ; CHECK-I-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-I-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-I-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND %yhi, [[C2]]
+    ; CHECK-I-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND %ylo, [[C3]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-I-NEXT: $x12 = COPY [[AND2]](s32)
+    ; CHECK-I-NEXT: $x13 = COPY [[AND3]](s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: urem_i48
+    ; CHECK-M: %xhi:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: %xlo:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: %yhi:_(s32) = COPY $x12
+    ; CHECK-M-NEXT: %ylo:_(s32) = COPY $x13
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND %xhi, [[C]]
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND %xlo, [[C1]]
+    ; CHECK-M-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-M-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK-M-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND %yhi, [[C2]]
+    ; CHECK-M-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND %ylo, [[C3]]
+    ; CHECK-M-NEXT: $x10 = COPY [[AND]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[AND1]](s32)
+    ; CHECK-M-NEXT: $x12 = COPY [[AND2]](s32)
+    ; CHECK-M-NEXT: $x13 = COPY [[AND3]](s32)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %xhi:_(s32) = COPY $x10
+    %xlo:_(s32) = COPY $x11
+    %yhi:_(s32) = COPY $x12
+    %ylo:_(s32) = COPY $x13
+    %x0:_(s64) = G_MERGE_VALUES %xhi(s32), %xlo(s32)
+    %y0:_(s64) = G_MERGE_VALUES %yhi(s32), %ylo(s32)
+    %x:_(s48) = G_TRUNC %x0
+    %y:_(s48) = G_TRUNC %y0
+    %z:_(s48) = G_UREM %x, %y
+    %z0:_(s64) = G_ANYEXT %z
+    %zhi:_(s32), %zlo:_(s32) = G_UNMERGE_VALUES %z0(s64)
+    $x10 = COPY %zhi(s32)
+    $x11 = COPY %zlo(s32)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            urem_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i64
+    ; CHECK-I: %hi1:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-I-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-I-NEXT: $x10 = COPY %hi1(s32)
+    ; CHECK-I-NEXT: $x11 = COPY %lo1(s32)
+    ; CHECK-I-NEXT: $x12 = COPY %hi2(s32)
+    ; CHECK-I-NEXT: $x13 = COPY %lo2(s32)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: urem_i64
+    ; CHECK-M: %hi1:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-M-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-M-NEXT: $x10 = COPY %hi1(s32)
+    ; CHECK-M-NEXT: $x11 = COPY %lo1(s32)
+    ; CHECK-M-NEXT: $x12 = COPY %hi2(s32)
+    ; CHECK-M-NEXT: $x13 = COPY %lo2(s32)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %hi1:_(s32) = COPY $x10
+    %lo1:_(s32) = COPY $x11
+    %hi2:_(s32) = COPY $x12
+    %lo2:_(s32) = COPY $x13
+    %x1:_(s64) = G_MERGE_VALUES %hi1(s32), %lo1(s32)
+    %x2:_(s64) = G_MERGE_VALUES %hi2(s32), %lo2(s32)
+    %y:_(s64) = G_UREM %x1, %x2
+    %hiy:_(s32), %loy:_(s32) = G_UNMERGE_VALUES %y(s64)
+    $x10 = COPY %hiy(s32)
+    $x11 = COPY %loy(s32)
+    PseudoRET implicit $x10, implicit $x11
+
+...

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-div.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-div.mir
new file mode 100644
index 00000000000000..e4b75586310d78
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-div.mir
@@ -0,0 +1,565 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s -check-prefix=CHECK-I
+# RUN: llc -mattr=+m -mtriple=riscv64 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s -check-prefix=CHECK-M
+---
+name:            sdiv_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i8
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 8
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 8
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i8
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 8
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 8
+    ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s8) = G_TRUNC %0(s64)
+    %3:_(s8) = G_TRUNC %1(s64)
+    %4:_(s8) = G_SDIV %2, %3
+    %5:_(s64) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            sdiv_i15
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i15
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 15
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 15
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i15
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 15
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 15
+    ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s15) = G_TRUNC %0(s64)
+    %3:_(s15) = G_TRUNC %1(s64)
+    %4:_(s15) = G_SDIV %2, %3
+    %5:_(s64) = G_ANYEXT %4(s15)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            sdiv_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i16
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 16
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 16
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i16
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 16
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 16
+    ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s16) = G_TRUNC %0(s64)
+    %3:_(s16) = G_TRUNC %1(s64)
+    %4:_(s16) = G_SDIV %2, %3
+    %5:_(s64) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            sdiv_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i32
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i32
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32
+    ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s32) = G_TRUNC %0(s64)
+    %3:_(s32) = G_TRUNC %1(s64)
+    %4:_(s32) = G_SDIV %2, %3
+    %5:_(s64) = G_ANYEXT %4(s32)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            sdiv_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i64
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i64
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s64) = G_SDIV [[COPY]], [[COPY1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s64) = G_SDIV %0, %1
+    $x10 = COPY %2(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            sdiv_i72
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i72
+    ; CHECK-I: %xhi:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: %xlo:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: %yhi:_(s64) = COPY $x12
+    ; CHECK-I-NEXT: %ylo:_(s64) = COPY $x13
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG %xlo, 8
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG %ylo, 8
+    ; CHECK-I-NEXT: $x10 = COPY %xhi(s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x12 = COPY %yhi(s64)
+    ; CHECK-I-NEXT: $x13 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i72
+    ; CHECK-M: %xhi:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: %xlo:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: %yhi:_(s64) = COPY $x12
+    ; CHECK-M-NEXT: %ylo:_(s64) = COPY $x13
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG %xlo, 8
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG %ylo, 8
+    ; CHECK-M-NEXT: $x10 = COPY %xhi(s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-M-NEXT: $x12 = COPY %yhi(s64)
+    ; CHECK-M-NEXT: $x13 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__divti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %xhi:_(s64) = COPY $x10
+    %xlo:_(s64) = COPY $x11
+    %yhi:_(s64) = COPY $x12
+    %ylo:_(s64) = COPY $x13
+    %x0:_(s128) = G_MERGE_VALUES %xhi(s64), %xlo(s64)
+    %y0:_(s128) = G_MERGE_VALUES %yhi(s64), %ylo(s64)
+    %x:_(s72) = G_TRUNC %x0
+    %y:_(s72) = G_TRUNC %y0
+    %z:_(s72) = G_SDIV %x, %y
+    %z0:_(s128) = G_ANYEXT %z
+    %zhi:_(s64), %zlo:_(s64) = G_UNMERGE_VALUES %z0(s128)
+    $x10 = COPY %zhi(s64)
+    $x11 = COPY %zlo(s64)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            sdiv_i128
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: sdiv_i128
+    ; CHECK-I: %hi1:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-I-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-I-NEXT: $x10 = COPY %hi1(s64)
+    ; CHECK-I-NEXT: $x11 = COPY %lo1(s64)
+    ; CHECK-I-NEXT: $x12 = COPY %hi2(s64)
+    ; CHECK-I-NEXT: $x13 = COPY %lo2(s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: sdiv_i128
+    ; CHECK-M: %hi1:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-M-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-M-NEXT: $x10 = COPY %hi1(s64)
+    ; CHECK-M-NEXT: $x11 = COPY %lo1(s64)
+    ; CHECK-M-NEXT: $x12 = COPY %hi2(s64)
+    ; CHECK-M-NEXT: $x13 = COPY %lo2(s64)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__divti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %hi1:_(s64) = COPY $x10
+    %lo1:_(s64) = COPY $x11
+    %hi2:_(s64) = COPY $x12
+    %lo2:_(s64) = COPY $x13
+    %x1:_(s128) = G_MERGE_VALUES %hi1(s64), %lo1(s64)
+    %x2:_(s128) = G_MERGE_VALUES %hi2(s64), %lo2(s64)
+    %y:_(s128) = G_SDIV %x1, %x2
+    %hiy:_(s64), %loy:_(s64) = G_UNMERGE_VALUES %y(s128)
+    $x10 = COPY %hiy(s64)
+    $x11 = COPY %loy(s64)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            udiv_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i8
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: udiv_i8
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s64) = G_UDIV [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s8) = G_TRUNC %0(s64)
+    %3:_(s8) = G_TRUNC %1(s64)
+    %4:_(s8) = G_UDIV %2, %3
+    %5:_(s64) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            udiv_i15
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i15
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32767
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32767
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: udiv_i15
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32767
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32767
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s64) = G_UDIV [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s15) = G_TRUNC %0(s64)
+    %3:_(s15) = G_TRUNC %1(s64)
+    %4:_(s15) = G_UDIV %2, %3
+    %5:_(s64) = G_ANYEXT %4(s15)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            udiv_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i16
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: udiv_i16
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s64) = G_UDIV [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s16) = G_TRUNC %0(s64)
+    %3:_(s16) = G_TRUNC %1(s64)
+    %4:_(s16) = G_UDIV %2, %3
+    %5:_(s64) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            udiv_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i32
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4294967295
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4294967295
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: udiv_i32
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4294967295
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4294967295
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s64) = G_UDIV [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s32) = G_TRUNC %0(s64)
+    %3:_(s32) = G_TRUNC %1(s64)
+    %4:_(s32) = G_UDIV %2, %3
+    %5:_(s64) = G_ANYEXT %4(s32)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            udiv_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i64
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: udiv_i64
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s64) = G_UDIV [[COPY]], [[COPY1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UDIV]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s64) = G_UDIV %0, %1
+    $x10 = COPY %2(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            udiv_i72
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i72
+    ; CHECK-I: %xhi:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: %xlo:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: %yhi:_(s64) = COPY $x12
+    ; CHECK-I-NEXT: %ylo:_(s64) = COPY $x13
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND %xhi, [[C]]
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND %xlo, [[C1]]
+    ; CHECK-I-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-I-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-I-NEXT: [[AND2:%[0-9]+]]:_(s64) = G_AND %yhi, [[C2]]
+    ; CHECK-I-NEXT: [[AND3:%[0-9]+]]:_(s64) = G_AND %ylo, [[C3]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: $x12 = COPY [[AND2]](s64)
+    ; CHECK-I-NEXT: $x13 = COPY [[AND3]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: udiv_i72
+    ; CHECK-M: %xhi:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: %xlo:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: %yhi:_(s64) = COPY $x12
+    ; CHECK-M-NEXT: %ylo:_(s64) = COPY $x13
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND %xhi, [[C]]
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND %xlo, [[C1]]
+    ; CHECK-M-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-M-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-M-NEXT: [[AND2:%[0-9]+]]:_(s64) = G_AND %yhi, [[C2]]
+    ; CHECK-M-NEXT: [[AND3:%[0-9]+]]:_(s64) = G_AND %ylo, [[C3]]
+    ; CHECK-M-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-M-NEXT: $x12 = COPY [[AND2]](s64)
+    ; CHECK-M-NEXT: $x13 = COPY [[AND3]](s64)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__udivti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %xhi:_(s64) = COPY $x10
+    %xlo:_(s64) = COPY $x11
+    %yhi:_(s64) = COPY $x12
+    %ylo:_(s64) = COPY $x13
+    %x0:_(s128) = G_MERGE_VALUES %xhi(s64), %xlo(s64)
+    %y0:_(s128) = G_MERGE_VALUES %yhi(s64), %ylo(s64)
+    %x:_(s72) = G_TRUNC %x0
+    %y:_(s72) = G_TRUNC %y0
+    %z:_(s72) = G_UDIV %x, %y
+    %z0:_(s128) = G_ANYEXT %z
+    %zhi:_(s64), %zlo:_(s64) = G_UNMERGE_VALUES %z0(s128)
+    $x10 = COPY %zhi(s64)
+    $x11 = COPY %zlo(s64)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            udiv_i128
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: udiv_i128
+    ; CHECK-I: %hi1:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-I-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-I-NEXT: $x10 = COPY %hi1(s64)
+    ; CHECK-I-NEXT: $x11 = COPY %lo1(s64)
+    ; CHECK-I-NEXT: $x12 = COPY %hi2(s64)
+    ; CHECK-I-NEXT: $x13 = COPY %lo2(s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__udivti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: udiv_i128
+    ; CHECK-M: %hi1:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-M-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-M-NEXT: $x10 = COPY %hi1(s64)
+    ; CHECK-M-NEXT: $x11 = COPY %lo1(s64)
+    ; CHECK-M-NEXT: $x12 = COPY %hi2(s64)
+    ; CHECK-M-NEXT: $x13 = COPY %lo2(s64)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__udivti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %hi1:_(s64) = COPY $x10
+    %lo1:_(s64) = COPY $x11
+    %hi2:_(s64) = COPY $x12
+    %lo2:_(s64) = COPY $x13
+    %x1:_(s128) = G_MERGE_VALUES %hi1(s64), %lo1(s64)
+    %x2:_(s128) = G_MERGE_VALUES %hi2(s64), %lo2(s64)
+    %y:_(s128) = G_UDIV %x1, %x2
+    %hiy:_(s64), %loy:_(s64) = G_UNMERGE_VALUES %y(s128)
+    $x10 = COPY %hiy(s64)
+    $x11 = COPY %loy(s64)
+    PseudoRET implicit $x10, implicit $x11
+
+...

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-rem.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-rem.mir
new file mode 100644
index 00000000000000..99be1fcbe49652
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-rem.mir
@@ -0,0 +1,565 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s -check-prefix=CHECK-I
+# RUN: llc -mattr=+m -mtriple=riscv64 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s -check-prefix=CHECK-M
+---
+name:            srem_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i8
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 8
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 8
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: srem_i8
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 8
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 8
+    ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s8) = G_TRUNC %0(s64)
+    %3:_(s8) = G_TRUNC %1(s64)
+    %4:_(s8) = G_SREM %2, %3
+    %5:_(s64) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            srem_i15
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i15
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 15
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 15
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: srem_i15
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 15
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 15
+    ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s15) = G_TRUNC %0(s64)
+    %3:_(s15) = G_TRUNC %1(s64)
+    %4:_(s15) = G_SREM %2, %3
+    %5:_(s64) = G_ANYEXT %4(s15)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            srem_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i16
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 16
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 16
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: srem_i16
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 16
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 16
+    ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s16) = G_TRUNC %0(s64)
+    %3:_(s16) = G_TRUNC %1(s64)
+    %4:_(s16) = G_SREM %2, %3
+    %5:_(s64) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            srem_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i32
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32
+    ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: srem_i32
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32
+    ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[SEXT_INREG]], [[SEXT_INREG1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s32) = G_TRUNC %0(s64)
+    %3:_(s32) = G_TRUNC %1(s64)
+    %4:_(s32) = G_SREM %2, %3
+    %5:_(s64) = G_ANYEXT %4(s32)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            srem_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i64
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: srem_i64
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[COPY]], [[COPY1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s64) = G_SREM %0, %1
+    $x10 = COPY %2(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            srem_i72
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i72
+    ; CHECK-I: %xhi:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: %xlo:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: %yhi:_(s64) = COPY $x12
+    ; CHECK-I-NEXT: %ylo:_(s64) = COPY $x13
+    ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG %xlo, 8
+    ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG %ylo, 8
+    ; CHECK-I-NEXT: $x10 = COPY %xhi(s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-I-NEXT: $x12 = COPY %yhi(s64)
+    ; CHECK-I-NEXT: $x13 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__modti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: srem_i72
+    ; CHECK-M: %xhi:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: %xlo:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: %yhi:_(s64) = COPY $x12
+    ; CHECK-M-NEXT: %ylo:_(s64) = COPY $x13
+    ; CHECK-M-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG %xlo, 8
+    ; CHECK-M-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG %ylo, 8
+    ; CHECK-M-NEXT: $x10 = COPY %xhi(s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[SEXT_INREG]](s64)
+    ; CHECK-M-NEXT: $x12 = COPY %yhi(s64)
+    ; CHECK-M-NEXT: $x13 = COPY [[SEXT_INREG1]](s64)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__modti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %xhi:_(s64) = COPY $x10
+    %xlo:_(s64) = COPY $x11
+    %yhi:_(s64) = COPY $x12
+    %ylo:_(s64) = COPY $x13
+    %x0:_(s128) = G_MERGE_VALUES %xhi(s64), %xlo(s64)
+    %y0:_(s128) = G_MERGE_VALUES %yhi(s64), %ylo(s64)
+    %x:_(s72) = G_TRUNC %x0
+    %y:_(s72) = G_TRUNC %y0
+    %z:_(s72) = G_SREM %x, %y
+    %z0:_(s128) = G_ANYEXT %z
+    %zhi:_(s64), %zlo:_(s64) = G_UNMERGE_VALUES %z0(s128)
+    $x10 = COPY %zhi(s64)
+    $x11 = COPY %zlo(s64)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            srem_i128
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: srem_i128
+    ; CHECK-I: %hi1:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-I-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-I-NEXT: $x10 = COPY %hi1(s64)
+    ; CHECK-I-NEXT: $x11 = COPY %lo1(s64)
+    ; CHECK-I-NEXT: $x12 = COPY %hi2(s64)
+    ; CHECK-I-NEXT: $x13 = COPY %lo2(s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__modti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: srem_i128
+    ; CHECK-M: %hi1:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-M-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-M-NEXT: $x10 = COPY %hi1(s64)
+    ; CHECK-M-NEXT: $x11 = COPY %lo1(s64)
+    ; CHECK-M-NEXT: $x12 = COPY %hi2(s64)
+    ; CHECK-M-NEXT: $x13 = COPY %lo2(s64)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__modti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %hi1:_(s64) = COPY $x10
+    %lo1:_(s64) = COPY $x11
+    %hi2:_(s64) = COPY $x12
+    %lo2:_(s64) = COPY $x13
+    %x1:_(s128) = G_MERGE_VALUES %hi1(s64), %lo1(s64)
+    %x2:_(s128) = G_MERGE_VALUES %hi2(s64), %lo2(s64)
+    %y:_(s128) = G_SREM %x1, %x2
+    %hiy:_(s64), %loy:_(s64) = G_UNMERGE_VALUES %y(s128)
+    $x10 = COPY %hiy(s64)
+    $x11 = COPY %loy(s64)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            urem_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i8
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: urem_i8
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s64) = G_UREM [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s8) = G_TRUNC %0(s64)
+    %3:_(s8) = G_TRUNC %1(s64)
+    %4:_(s8) = G_UREM %2, %3
+    %5:_(s64) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            urem_i15
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i15
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32767
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32767
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: urem_i15
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32767
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32767
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s64) = G_UREM [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s15) = G_TRUNC %0(s64)
+    %3:_(s15) = G_TRUNC %1(s64)
+    %4:_(s15) = G_UREM %2, %3
+    %5:_(s64) = G_ANYEXT %4(s15)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            urem_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i16
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: urem_i16
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 65535
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s64) = G_UREM [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s16) = G_TRUNC %0(s64)
+    %3:_(s16) = G_TRUNC %1(s64)
+    %4:_(s16) = G_UREM %2, %3
+    %5:_(s64) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            urem_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i32
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4294967295
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4294967295
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: urem_i32
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4294967295
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[C]]
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4294967295
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C1]]
+    ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s64) = G_UREM [[AND]], [[AND1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s32) = G_TRUNC %0(s64)
+    %3:_(s32) = G_TRUNC %1(s64)
+    %4:_(s32) = G_UREM %2, %3
+    %5:_(s64) = G_ANYEXT %4(s32)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            urem_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i64
+    ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umoddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10
+    ;
+    ; CHECK-M-LABEL: name: urem_i64
+    ; CHECK-M: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: [[UREM:%[0-9]+]]:_(s64) = G_UREM [[COPY]], [[COPY1]]
+    ; CHECK-M-NEXT: $x10 = COPY [[UREM]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s64) = G_UREM %0, %1
+    $x10 = COPY %2(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            urem_i72
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i72
+    ; CHECK-I: %xhi:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: %xlo:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: %yhi:_(s64) = COPY $x12
+    ; CHECK-I-NEXT: %ylo:_(s64) = COPY $x13
+    ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-I-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND %xhi, [[C]]
+    ; CHECK-I-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND %xlo, [[C1]]
+    ; CHECK-I-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-I-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-I-NEXT: [[AND2:%[0-9]+]]:_(s64) = G_AND %yhi, [[C2]]
+    ; CHECK-I-NEXT: [[AND3:%[0-9]+]]:_(s64) = G_AND %ylo, [[C3]]
+    ; CHECK-I-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-I-NEXT: $x12 = COPY [[AND2]](s64)
+    ; CHECK-I-NEXT: $x13 = COPY [[AND3]](s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umodti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: urem_i72
+    ; CHECK-M: %xhi:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: %xlo:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: %yhi:_(s64) = COPY $x12
+    ; CHECK-M-NEXT: %ylo:_(s64) = COPY $x13
+    ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-M-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND %xhi, [[C]]
+    ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND %xlo, [[C1]]
+    ; CHECK-M-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-M-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
+    ; CHECK-M-NEXT: [[AND2:%[0-9]+]]:_(s64) = G_AND %yhi, [[C2]]
+    ; CHECK-M-NEXT: [[AND3:%[0-9]+]]:_(s64) = G_AND %ylo, [[C3]]
+    ; CHECK-M-NEXT: $x10 = COPY [[AND]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[AND1]](s64)
+    ; CHECK-M-NEXT: $x12 = COPY [[AND2]](s64)
+    ; CHECK-M-NEXT: $x13 = COPY [[AND3]](s64)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__umodti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %xhi:_(s64) = COPY $x10
+    %xlo:_(s64) = COPY $x11
+    %yhi:_(s64) = COPY $x12
+    %ylo:_(s64) = COPY $x13
+    %x0:_(s128) = G_MERGE_VALUES %xhi(s64), %xlo(s64)
+    %y0:_(s128) = G_MERGE_VALUES %yhi(s64), %ylo(s64)
+    %x:_(s72) = G_TRUNC %x0
+    %y:_(s72) = G_TRUNC %y0
+    %z:_(s72) = G_UREM %x, %y
+    %z0:_(s128) = G_ANYEXT %z
+    %zhi:_(s64), %zlo:_(s64) = G_UNMERGE_VALUES %z0(s128)
+    $x10 = COPY %zhi(s64)
+    $x11 = COPY %zlo(s64)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            urem_i128
+body:             |
+  bb.0.entry:
+    ; CHECK-I-LABEL: name: urem_i128
+    ; CHECK-I: %hi1:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-I-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-I-NEXT: $x10 = COPY %hi1(s64)
+    ; CHECK-I-NEXT: $x11 = COPY %lo1(s64)
+    ; CHECK-I-NEXT: $x12 = COPY %hi2(s64)
+    ; CHECK-I-NEXT: $x13 = COPY %lo2(s64)
+    ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__umodti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-I-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-I-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-I-NEXT: PseudoRET implicit $x10, implicit $x11
+    ;
+    ; CHECK-M-LABEL: name: urem_i128
+    ; CHECK-M: %hi1:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-M-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-M-NEXT: $x10 = COPY %hi1(s64)
+    ; CHECK-M-NEXT: $x11 = COPY %lo1(s64)
+    ; CHECK-M-NEXT: $x12 = COPY %hi2(s64)
+    ; CHECK-M-NEXT: $x13 = COPY %lo2(s64)
+    ; CHECK-M-NEXT: PseudoCALL target-flags(riscv-call) &__umodti3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-M-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-M-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-M-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-M-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-M-NEXT: PseudoRET implicit $x10, implicit $x11
+    %hi1:_(s64) = COPY $x10
+    %lo1:_(s64) = COPY $x11
+    %hi2:_(s64) = COPY $x12
+    %lo2:_(s64) = COPY $x13
+    %x1:_(s128) = G_MERGE_VALUES %hi1(s64), %lo1(s64)
+    %x2:_(s128) = G_MERGE_VALUES %hi2(s64), %lo2(s64)
+    %y:_(s128) = G_UREM %x1, %x2
+    %hiy:_(s64), %loy:_(s64) = G_UNMERGE_VALUES %y(s128)
+    $x10 = COPY %hiy(s64)
+    $x11 = COPY %loy(s64)
+    PseudoRET implicit $x10, implicit $x11
+
+...


        


More information about the llvm-commits mailing list