[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