[llvm] 638865c - [RISCV][GlobalISel] Legalize multiplication

Nitin John Raj via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 17 13:00:17 PDT 2023


Author: Nitin John Raj
Date: 2023-08-17T12:59:34-07:00
New Revision: 638865c8f93989c5f7a237417356c920d55e0136

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

LOG: [RISCV][GlobalISel] Legalize multiplication

Legalize multiplication with the +m, +zmmul extensions and without extensions. With extensions, we test for (s7, s8, s16, s32, s48, s64, s96) on rv32 and (s8, s15, s32, s64, s72, s128, s192) on rv64. Without extensions, test (s7, s8, s16, s32) on rv32 and (s8, s15, s16, s32, s64) on rv64. Does not yet work for the type which is 2 times XLen without extensions.

Reviewed By: craig.topper

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

Added: 
    llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mul-ext.mir
    llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mul.mir
    llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mul-ext.mir
    llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mul.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 37db84fadedecf..b382ae750b8b12 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -22,6 +22,7 @@ using namespace llvm;
 RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
   const unsigned XLen = ST.getXLen();
   const LLT XLenLLT = LLT::scalar(XLen);
+  const LLT DoubleXLenLLT = LLT::scalar(2 * XLen);
   const LLT p0 = LLT::pointer(0, XLen);
 
   using namespace TargetOpcode;
@@ -92,5 +93,25 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
   getActionDefinitionsBuilder(G_GLOBAL_VALUE)
       .legalFor({p0});
 
+  if (ST.hasStdExtM() || ST.hasStdExtZmmul()) {
+    getActionDefinitionsBuilder(G_MUL)
+        .legalFor({XLenLLT})
+        .widenScalarToNextPow2(0)
+        .clampScalar(0, XLenLLT, XLenLLT);
+
+    // clang-format off
+    getActionDefinitionsBuilder({G_SMULH, G_UMULH})
+        .legalFor({XLenLLT})
+        .lower();
+    // clang-format on
+  } else {
+    getActionDefinitionsBuilder(G_MUL)
+        .libcallFor({XLenLLT, DoubleXLenLLT})
+        .widenScalarToNextPow2(0)
+        .clampScalar(0, XLenLLT, DoubleXLenLLT);
+
+    getActionDefinitionsBuilder({G_SMULH, G_UMULH}).lowerFor({XLenLLT});
+  }
+
   getLegacyLegalizerInfo().computeTables();
 }

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mul-ext.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mul-ext.mir
new file mode 100644
index 00000000000000..591a99865094c9
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mul-ext.mir
@@ -0,0 +1,199 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mattr=+m -mtriple=riscv32 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+# RUN: llc -mattr=+zmmul -mtriple=riscv32 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+---
+name:            mul_i7
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i7
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s32) = G_ANYEXT %4(s7)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i8
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s32) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i16
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s32) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i32
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s32) = G_MUL %0, %1
+    $x10 = COPY %2(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i48
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i48
+    ; CHECK: %xhi:_(s32) = COPY $x10
+    ; CHECK-NEXT: %xlo:_(s32) = COPY $x11
+    ; CHECK-NEXT: %yhi:_(s32) = COPY $x12
+    ; CHECK-NEXT: %ylo:_(s32) = COPY $x13
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL %xhi, %yhi
+    ; CHECK-NEXT: [[MUL1:%[0-9]+]]:_(s32) = G_MUL %xlo, %yhi
+    ; CHECK-NEXT: [[MUL2:%[0-9]+]]:_(s32) = G_MUL %xhi, %ylo
+    ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s32) = G_UMULH %xhi, %yhi
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[MUL1]], [[MUL2]]
+    ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[UMULH]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+    ; CHECK-NEXT: $x11 = COPY [[ADD1]](s32)
+    ; CHECK-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(s64)
+    %y:_(s48) = G_TRUNC %y0(s64)
+    %z:_(s48) = G_MUL %x, %y
+    %z0:_(s64) = G_ANYEXT %z(s48)
+    %zhi:_(s32), %zlo:_(s32) = G_UNMERGE_VALUES %z0(s64)
+    $x10 = COPY %zhi(s32)
+    $x11 = COPY %zlo(s32)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            mul_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i64
+    ; CHECK: %hi1:_(s32) = COPY $x10
+    ; CHECK-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL %hi1, %hi2
+    ; CHECK-NEXT: [[MUL1:%[0-9]+]]:_(s32) = G_MUL %lo1, %hi2
+    ; CHECK-NEXT: [[MUL2:%[0-9]+]]:_(s32) = G_MUL %hi1, %lo2
+    ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s32) = G_UMULH %hi1, %hi2
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[MUL1]], [[MUL2]]
+    ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[UMULH]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+    ; CHECK-NEXT: $x11 = COPY [[ADD1]](s32)
+    ; CHECK-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_MUL %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:            mul_i96
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i96
+    ; CHECK: %hi1:_(s32) = COPY $x10
+    ; CHECK-NEXT: %mid1:_(s32) = COPY $x11
+    ; CHECK-NEXT: %lo1:_(s32) = COPY $x12
+    ; CHECK-NEXT: %hi2:_(s32) = COPY $x13
+    ; CHECK-NEXT: %mid2:_(s32) = COPY $x14
+    ; CHECK-NEXT: %lo2:_(s32) = COPY $x15
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL %hi1, %hi2
+    ; CHECK-NEXT: [[MUL1:%[0-9]+]]:_(s32) = G_MUL %mid1, %hi2
+    ; CHECK-NEXT: [[MUL2:%[0-9]+]]:_(s32) = G_MUL %hi1, %mid2
+    ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s32) = G_UMULH %hi1, %hi2
+    ; CHECK-NEXT: [[UADDO:%[0-9]+]]:_(s32), [[UADDO1:%[0-9]+]]:_(s32) = G_UADDO [[MUL1]], [[MUL2]]
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[UADDO1]], [[C]]
+    ; CHECK-NEXT: [[UADDO2:%[0-9]+]]:_(s32), [[UADDO3:%[0-9]+]]:_(s32) = G_UADDO [[UADDO]], [[UMULH]]
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[UADDO3]], [[C1]]
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[AND]], [[AND1]]
+    ; CHECK-NEXT: [[MUL3:%[0-9]+]]:_(s32) = G_MUL %lo1, %hi2
+    ; CHECK-NEXT: [[MUL4:%[0-9]+]]:_(s32) = G_MUL %mid1, %mid2
+    ; CHECK-NEXT: [[MUL5:%[0-9]+]]:_(s32) = G_MUL %hi1, %lo2
+    ; CHECK-NEXT: [[UMULH1:%[0-9]+]]:_(s32) = G_UMULH %mid1, %hi2
+    ; CHECK-NEXT: [[UMULH2:%[0-9]+]]:_(s32) = G_UMULH %hi1, %mid2
+    ; CHECK-NEXT: [[UADDO4:%[0-9]+]]:_(s32), [[UADDO5:%[0-9]+]]:_(s32) = G_UADDO [[MUL3]], [[MUL4]]
+    ; CHECK-NEXT: [[UADDO6:%[0-9]+]]:_(s32), [[UADDO7:%[0-9]+]]:_(s32) = G_UADDO [[UADDO4]], [[MUL5]]
+    ; CHECK-NEXT: [[UADDO8:%[0-9]+]]:_(s32), [[UADDO9:%[0-9]+]]:_(s32) = G_UADDO [[UADDO6]], [[UMULH1]]
+    ; CHECK-NEXT: [[UADDO10:%[0-9]+]]:_(s32), [[UADDO11:%[0-9]+]]:_(s32) = G_UADDO [[UADDO8]], [[UMULH2]]
+    ; CHECK-NEXT: [[UADDO12:%[0-9]+]]:_(s32), [[UADDO13:%[0-9]+]]:_(s32) = G_UADDO [[UADDO10]], [[ADD]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+    ; CHECK-NEXT: $x11 = COPY [[UADDO2]](s32)
+    ; CHECK-NEXT: $x12 = COPY [[UADDO12]](s32)
+    ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11, implicit $x12
+    %hi1:_(s32) = COPY $x10
+    %mid1:_(s32) = COPY $x11
+    %lo1:_(s32) = COPY $x12
+    %hi2:_(s32) = COPY $x13
+    %mid2:_(s32) = COPY $x14
+    %lo2:_(s32) = COPY $x15
+    %x1:_(s96) = G_MERGE_VALUES %hi1(s32), %mid1(s32), %lo1(s32)
+    %x2:_(s96) = G_MERGE_VALUES %hi2(s32), %mid2(s32), %lo2(s32)
+    %y:_(s96) = G_MUL %x1, %x2
+    %hi:_(s32), %mid:_(s32), %lo:_(s32) = G_UNMERGE_VALUES %y(s96)
+    $x10 = COPY %hi(s32)
+    $x11 = COPY %mid(s32)
+    $x12 = COPY %lo(s32)
+    PseudoRET implicit $x10, implicit $x11, implicit $x12
+
+...

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mul.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mul.mir
new file mode 100644
index 00000000000000..6829f55c708e7e
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mul.mir
@@ -0,0 +1,124 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+---
+name:            mul_i7
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i7
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s32) = G_ANYEXT %4(s7)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i8
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s32) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i16
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s32) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i32
+    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: $x10 = COPY [[COPY2]](s32)
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:_(s32) = COPY $x10
+    %1:_(s32) = COPY $x11
+    %2:_(s32) = G_MUL %0, %1
+    $x10 = COPY %2(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i64
+    ; CHECK: %hi1:_(s32) = COPY $x10
+    ; CHECK-NEXT: %lo1:_(s32) = COPY $x11
+    ; CHECK-NEXT: %hi2:_(s32) = COPY $x12
+    ; CHECK-NEXT: %lo2:_(s32) = COPY $x13
+    ; CHECK-NEXT: $x10 = COPY %hi1(s32)
+    ; CHECK-NEXT: $x11 = COPY %lo1(s32)
+    ; CHECK-NEXT: $x12 = COPY %hi2(s32)
+    ; CHECK-NEXT: $x13 = COPY %lo2(s32)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__muldi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s32)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s32)
+    ; CHECK-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_MUL %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-mul-ext.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mul-ext.mir
new file mode 100644
index 00000000000000..876d2bfcfeb1cb
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mul-ext.mir
@@ -0,0 +1,219 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mattr=+m -mtriple=riscv64 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+# RUN: llc -mattr=+zmmul -mtriple=riscv64 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+---
+name:            mul_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i8
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s64)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s64) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i15
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i15
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s64)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s64) = G_ANYEXT %4(s15)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i16
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s64)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s64) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i32
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s64)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s64) = G_ANYEXT %4(s32)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i64
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s64)
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s64) = G_MUL %0, %1
+    $x10 = COPY %2(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i72
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i72
+    ; CHECK: %xhi:_(s64) = COPY $x10
+    ; CHECK-NEXT: %xlo:_(s64) = COPY $x11
+    ; CHECK-NEXT: %yhi:_(s64) = COPY $x12
+    ; CHECK-NEXT: %ylo:_(s64) = COPY $x13
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL %xhi, %yhi
+    ; CHECK-NEXT: [[MUL1:%[0-9]+]]:_(s64) = G_MUL %xlo, %yhi
+    ; CHECK-NEXT: [[MUL2:%[0-9]+]]:_(s64) = G_MUL %xhi, %ylo
+    ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s64) = G_UMULH %xhi, %yhi
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[MUL1]], [[MUL2]]
+    ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[UMULH]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s64)
+    ; CHECK-NEXT: $x11 = COPY [[ADD1]](s64)
+    ; CHECK-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(s128)
+    %y:_(s72) = G_TRUNC %y0(s128)
+    %z:_(s72) = G_MUL %x, %y
+    %z0:_(s128) = G_ANYEXT %z(s72)
+    %zhi:_(s64), %zlo:_(s64) = G_UNMERGE_VALUES %z0(s128)
+    $x10 = COPY %zhi(s64)
+    $x11 = COPY %zlo(s64)
+    PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name:            mul_i128
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i128
+    ; CHECK: %hi1:_(s64) = COPY $x10
+    ; CHECK-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL %hi1, %hi2
+    ; CHECK-NEXT: [[MUL1:%[0-9]+]]:_(s64) = G_MUL %lo1, %hi2
+    ; CHECK-NEXT: [[MUL2:%[0-9]+]]:_(s64) = G_MUL %hi1, %lo2
+    ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s64) = G_UMULH %hi1, %hi2
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[MUL1]], [[MUL2]]
+    ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[UMULH]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s64)
+    ; CHECK-NEXT: $x11 = COPY [[ADD1]](s64)
+    ; CHECK-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_MUL %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:            mul_i192
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i192
+    ; CHECK: %hi1:_(s64) = COPY $x10
+    ; CHECK-NEXT: %mid1:_(s64) = COPY $x11
+    ; CHECK-NEXT: %lo1:_(s64) = COPY $x12
+    ; CHECK-NEXT: %hi2:_(s64) = COPY $x13
+    ; CHECK-NEXT: %mid2:_(s64) = COPY $x14
+    ; CHECK-NEXT: %lo2:_(s64) = COPY $x15
+    ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL %hi1, %hi2
+    ; CHECK-NEXT: [[MUL1:%[0-9]+]]:_(s64) = G_MUL %mid1, %hi2
+    ; CHECK-NEXT: [[MUL2:%[0-9]+]]:_(s64) = G_MUL %hi1, %mid2
+    ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s64) = G_UMULH %hi1, %hi2
+    ; CHECK-NEXT: [[UADDO:%[0-9]+]]:_(s64), [[UADDO1:%[0-9]+]]:_(s64) = G_UADDO [[MUL1]], [[MUL2]]
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[UADDO1]], [[C]]
+    ; CHECK-NEXT: [[UADDO2:%[0-9]+]]:_(s64), [[UADDO3:%[0-9]+]]:_(s64) = G_UADDO [[UADDO]], [[UMULH]]
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[UADDO3]], [[C1]]
+    ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[AND]], [[AND1]]
+    ; CHECK-NEXT: [[MUL3:%[0-9]+]]:_(s64) = G_MUL %lo1, %hi2
+    ; CHECK-NEXT: [[MUL4:%[0-9]+]]:_(s64) = G_MUL %mid1, %mid2
+    ; CHECK-NEXT: [[MUL5:%[0-9]+]]:_(s64) = G_MUL %hi1, %lo2
+    ; CHECK-NEXT: [[UMULH1:%[0-9]+]]:_(s64) = G_UMULH %mid1, %hi2
+    ; CHECK-NEXT: [[UMULH2:%[0-9]+]]:_(s64) = G_UMULH %hi1, %mid2
+    ; CHECK-NEXT: [[UADDO4:%[0-9]+]]:_(s64), [[UADDO5:%[0-9]+]]:_(s64) = G_UADDO [[MUL3]], [[MUL4]]
+    ; CHECK-NEXT: [[UADDO6:%[0-9]+]]:_(s64), [[UADDO7:%[0-9]+]]:_(s64) = G_UADDO [[UADDO4]], [[MUL5]]
+    ; CHECK-NEXT: [[UADDO8:%[0-9]+]]:_(s64), [[UADDO9:%[0-9]+]]:_(s64) = G_UADDO [[UADDO6]], [[UMULH1]]
+    ; CHECK-NEXT: [[UADDO10:%[0-9]+]]:_(s64), [[UADDO11:%[0-9]+]]:_(s64) = G_UADDO [[UADDO8]], [[UMULH2]]
+    ; CHECK-NEXT: [[UADDO12:%[0-9]+]]:_(s64), [[UADDO13:%[0-9]+]]:_(s64) = G_UADDO [[UADDO10]], [[ADD]]
+    ; CHECK-NEXT: $x10 = COPY [[MUL]](s64)
+    ; CHECK-NEXT: $x11 = COPY [[UADDO2]](s64)
+    ; CHECK-NEXT: $x12 = COPY [[UADDO12]](s64)
+    ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11, implicit $x12
+    %hi1:_(s64) = COPY $x10
+    %mid1:_(s64) = COPY $x11
+    %lo1:_(s64) = COPY $x12
+    %hi2:_(s64) = COPY $x13
+    %mid2:_(s64) = COPY $x14
+    %lo2:_(s64) = COPY $x15
+    %x1:_(s192) = G_MERGE_VALUES %hi1(s64), %mid1(s64), %lo1(s64)
+    %x2:_(s192) = G_MERGE_VALUES %hi2(s64), %mid2(s64), %lo2(s64)
+    %y:_(s192) = G_MUL %x1, %x2
+    %hi:_(s64), %mid:_(s64), %lo:_(s64) = G_UNMERGE_VALUES %y(s192)
+    $x10 = COPY %hi(s64)
+    $x11 = COPY %mid(s64)
+    $x12 = COPY %lo(s64)
+    PseudoRET implicit $x10, implicit $x11, implicit $x12
+
+...

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mul.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mul.mir
new file mode 100644
index 00000000000000..7bc0e7da4de337
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mul.mir
@@ -0,0 +1,147 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+---
+name:            mul_i8
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i8
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__muldi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s64) = G_ANYEXT %4(s8)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i15
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i15
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__muldi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s64) = G_ANYEXT %4(s15)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i16
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i16
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__muldi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s64) = G_ANYEXT %4(s16)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i32
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i32
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__muldi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-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_MUL %2, %3
+    %5:_(s64) = G_ANYEXT %4(s32)
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i64
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i64
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__muldi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: $x10 = COPY [[COPY2]](s64)
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s64) = G_MUL %0, %1
+    $x10 = COPY %2(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            mul_i128
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: mul_i128
+    ; CHECK: %hi1:_(s64) = COPY $x10
+    ; CHECK-NEXT: %lo1:_(s64) = COPY $x11
+    ; CHECK-NEXT: %hi2:_(s64) = COPY $x12
+    ; CHECK-NEXT: %lo2:_(s64) = COPY $x13
+    ; CHECK-NEXT: $x10 = COPY %hi1(s64)
+    ; CHECK-NEXT: $x11 = COPY %lo1(s64)
+    ; CHECK-NEXT: $x12 = COPY %hi2(s64)
+    ; CHECK-NEXT: $x13 = COPY %lo2(s64)
+    ; CHECK-NEXT: PseudoCALL target-flags(riscv-call) &__multi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+    ; CHECK-NEXT: $x10 = COPY [[COPY]](s64)
+    ; CHECK-NEXT: $x11 = COPY [[COPY1]](s64)
+    ; CHECK-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_MUL %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