-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISCV][GISel] Legalize G_SMULO/G_UMULO #67635
Conversation
I'm unhappy with the XLen case when we need to make a libcall. We get two libcalls.
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-llvm-globalisel ChangesI'm unhappy with the XLen case when we need to make a libcall. We get two libcalls. Patch is 37.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/67635.diff 3 Files Affected:
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 313a8221ab1bd4a..a9d6f61541253f7 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -145,6 +145,10 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
.legalFor({XLenLLT})
.lower();
// clang-format on
+
+ getActionDefinitionsBuilder({G_SMULO, G_UMULO})
+ .minScalar(0, XLenLLT)
+ .lower();
} else {
getActionDefinitionsBuilder(G_MUL)
.libcallFor({XLenLLT, DoubleXLenLLT})
@@ -152,6 +156,10 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
.clampScalar(0, XLenLLT, DoubleXLenLLT);
getActionDefinitionsBuilder({G_SMULH, G_UMULH}).lowerFor({XLenLLT});
+
+ getActionDefinitionsBuilder({G_SMULO, G_UMULO})
+ .minScalar(0, XLenLLT)
+ .lower();
}
if (ST.hasStdExtM()) {
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mulo.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mulo.mir
new file mode 100644
index 000000000000000..35bea08f426a3a3
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-mulo.mir
@@ -0,0 +1,340 @@
+# 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
+# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s --check-prefix=LIBCALL
+
+---
+name: smulo_i8
+body: |
+ bb.1:
+ liveins: $x10, $x11
+
+ ; CHECK-LABEL: name: smulo_i8
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C1]](s32)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C1]](s32)
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[MUL]], [[C2]](s32)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C2]](s32)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[MUL]](s32), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ ;
+ ; LIBCALL-LABEL: name: smulo_i8
+ ; LIBCALL: liveins: $x10, $x11
+ ; LIBCALL-NEXT: {{ $}}
+ ; LIBCALL-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; LIBCALL-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; LIBCALL-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
+ ; LIBCALL-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; LIBCALL-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; LIBCALL-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C1]](s32)
+ ; LIBCALL-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C1]](s32)
+ ; LIBCALL-NEXT: $x10 = COPY [[ASHR]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[ASHR1]](s32)
+ ; LIBCALL-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; LIBCALL-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; LIBCALL-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[COPY2]], [[C2]](s32)
+ ; LIBCALL-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C2]](s32)
+ ; LIBCALL-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY2]](s32), [[ASHR2]]
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY2]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; LIBCALL-NEXT: PseudoRET implicit $x10, implicit $x11
+ %2:_(s32) = COPY $x10
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:_(s32) = COPY $x11
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8), %5:_(s1) = G_SMULO %0, %1
+ %6:_(s32) = G_ANYEXT %4(s8)
+ %7:_(s32) = G_ANYEXT %5(s1)
+ $x10 = COPY %6(s32)
+ $x11 = COPY %7(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: smulo_i16
+body: |
+ bb.1:
+ liveins: $x10, $x11
+
+ ; CHECK-LABEL: name: smulo_i16
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C1]](s32)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C1]](s32)
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[MUL]], [[C2]](s32)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C2]](s32)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[MUL]](s32), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ ;
+ ; LIBCALL-LABEL: name: smulo_i16
+ ; LIBCALL: liveins: $x10, $x11
+ ; LIBCALL-NEXT: {{ $}}
+ ; LIBCALL-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; LIBCALL-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; LIBCALL-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
+ ; LIBCALL-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; LIBCALL-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; LIBCALL-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C1]](s32)
+ ; LIBCALL-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C1]](s32)
+ ; LIBCALL-NEXT: $x10 = COPY [[ASHR]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[ASHR1]](s32)
+ ; LIBCALL-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; LIBCALL-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; LIBCALL-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[COPY2]], [[C2]](s32)
+ ; LIBCALL-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C2]](s32)
+ ; LIBCALL-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY2]](s32), [[ASHR2]]
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY2]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; LIBCALL-NEXT: PseudoRET implicit $x10, implicit $x11
+ %2:_(s32) = COPY $x10
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:_(s32) = COPY $x11
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16), %5:_(s1) = G_SMULO %0, %1
+ %6:_(s32) = G_ANYEXT %4(s16)
+ %7:_(s32) = G_ANYEXT %5(s1)
+ $x10 = COPY %6(s32)
+ $x11 = COPY %7(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: smulo_i32
+body: |
+ bb.1:
+ liveins: $x10, $x11
+
+ ; CHECK-LABEL: name: smulo_i32
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[SMULH:%[0-9]+]]:_(s32) = G_SMULH [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[MUL]], [[C]](s32)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[SMULH]](s32), [[ASHR]]
+ ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ ;
+ ; LIBCALL-LABEL: name: smulo_i32
+ ; LIBCALL: liveins: $x10, $x11
+ ; LIBCALL-NEXT: {{ $}}
+ ; LIBCALL-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; LIBCALL-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; LIBCALL-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[COPY]], [[C]](s32)
+ ; LIBCALL-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; LIBCALL-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[COPY1]], [[C1]](s32)
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[ASHR]](s32)
+ ; LIBCALL-NEXT: $x12 = COPY [[COPY1]](s32)
+ ; LIBCALL-NEXT: $x13 = COPY [[ASHR1]](s32)
+ ; LIBCALL-NEXT: PseudoCALL target-flags(riscv-call) &__muldi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+ ; LIBCALL-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[COPY1]](s32)
+ ; LIBCALL-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; LIBCALL-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
+ ; LIBCALL-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[COPY3]], [[C2]](s32)
+ ; LIBCALL-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY2]](s32), [[ASHR2]]
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY3]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; LIBCALL-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s32) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(s32), %3:_(s1) = G_SMULO %0, %1
+ %4:_(s32) = G_ANYEXT %3(s1)
+ $x10 = COPY %2(s32)
+ $x11 = COPY %4(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: umulo_i8
+body: |
+ bb.1:
+ liveins: $x10, $x11
+
+ ; CHECK-LABEL: name: umulo_i8
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[AND]], [[AND1]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[MUL]], [[C2]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[MUL]](s32), [[AND2]]
+ ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ ;
+ ; LIBCALL-LABEL: name: umulo_i8
+ ; LIBCALL: liveins: $x10, $x11
+ ; LIBCALL-NEXT: {{ $}}
+ ; LIBCALL-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; LIBCALL-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; LIBCALL-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+ ; LIBCALL-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; LIBCALL-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+ ; LIBCALL-NEXT: $x10 = COPY [[AND]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[AND1]](s32)
+ ; LIBCALL-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; LIBCALL-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; LIBCALL-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C2]]
+ ; LIBCALL-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY2]](s32), [[AND2]]
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY2]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; LIBCALL-NEXT: PseudoRET implicit $x10, implicit $x11
+ %2:_(s32) = COPY $x10
+ %0:_(s8) = G_TRUNC %2(s32)
+ %3:_(s32) = COPY $x11
+ %1:_(s8) = G_TRUNC %3(s32)
+ %4:_(s8), %5:_(s1) = G_UMULO %0, %1
+ %6:_(s32) = G_ANYEXT %4(s8)
+ %7:_(s32) = G_ANYEXT %5(s1)
+ $x10 = COPY %6(s32)
+ $x11 = COPY %7(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: umulo_i16
+body: |
+ bb.1:
+ liveins: $x10, $x11
+
+ ; CHECK-LABEL: name: umulo_i16
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[AND]], [[AND1]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[MUL]], [[C2]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[MUL]](s32), [[AND2]]
+ ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ ;
+ ; LIBCALL-LABEL: name: umulo_i16
+ ; LIBCALL: liveins: $x10, $x11
+ ; LIBCALL-NEXT: {{ $}}
+ ; LIBCALL-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; LIBCALL-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; LIBCALL-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+ ; LIBCALL-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; LIBCALL-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
+ ; LIBCALL-NEXT: $x10 = COPY [[AND]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[AND1]](s32)
+ ; LIBCALL-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; LIBCALL-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+ ; LIBCALL-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C2]]
+ ; LIBCALL-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY2]](s32), [[AND2]]
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY2]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; LIBCALL-NEXT: PseudoRET implicit $x10, implicit $x11
+ %2:_(s32) = COPY $x10
+ %0:_(s16) = G_TRUNC %2(s32)
+ %3:_(s32) = COPY $x11
+ %1:_(s16) = G_TRUNC %3(s32)
+ %4:_(s16), %5:_(s1) = G_UMULO %0, %1
+ %6:_(s32) = G_ANYEXT %4(s16)
+ %7:_(s32) = G_ANYEXT %5(s1)
+ $x10 = COPY %6(s32)
+ $x11 = COPY %7(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: umulo_i32
+body: |
+ bb.1:
+ liveins: $x10, $x11
+
+ ; CHECK-LABEL: name: umulo_i32
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[UMULH:%[0-9]+]]:_(s32) = G_UMULH [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[UMULH]](s32), [[C]]
+ ; CHECK-NEXT: $x10 = COPY [[MUL]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ ;
+ ; LIBCALL-LABEL: name: umulo_i32
+ ; LIBCALL: liveins: $x10, $x11
+ ; LIBCALL-NEXT: {{ $}}
+ ; LIBCALL-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; LIBCALL-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; LIBCALL-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[C]](s32)
+ ; LIBCALL-NEXT: $x12 = COPY [[COPY1]](s32)
+ ; LIBCALL-NEXT: $x13 = COPY [[C1]](s32)
+ ; LIBCALL-NEXT: PseudoCALL target-flags(riscv-call) &__muldi3, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit-def $x10, implicit-def $x11
+ ; LIBCALL-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; LIBCALL-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[COPY1]](s32)
+ ; LIBCALL-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; LIBCALL-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x10
+ ; LIBCALL-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY2]](s32), [[C2]]
+ ; LIBCALL-NEXT: $x10 = COPY [[COPY3]](s32)
+ ; LIBCALL-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; LIBCALL-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s32) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(s32), %3:_(s1) = G_UMULO %0, %1
+ %4:_(s32) = G_ANYEXT %3(s1)
+ $x10 = COPY %2(s32)
+ $x11 = COPY %4(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mulo.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mulo.mir
new file mode 100644
index 000000000000000..219635914efdd1d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-mulo.mir
@@ -0,0 +1,442 @@
+# 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
+# RUN: llc -mtriple=riscv64 -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s --check-prefix=LIBCALL
+
+---
+name: smulo_i8
+body: |
+ bb.1:
+ liveins: $x10, $x11
+
+ ; CHECK-LABEL: name: smulo_i8
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C1]](s64)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C1]](s64)
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s64) = G_SHL [[MUL]], [[C2]](s64)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s64) = G_ASHR [[SHL2]], [[C2]](s64)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ne), [[MUL]](s64), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[MUL]](s64)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ ;
+ ; LIBCALL-LABEL: name: smulo_i8
+ ; LIBCALL: liveins: $x10, $x11
+ ; LIBCALL-NEXT: {{ $}}
+ ; LIBCALL-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; LIBCALL-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; LIBCALL-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; LIBCALL-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; LIBCALL-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; LIBCALL-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; LIBCALL-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C1]](s64)
+ ; LIBCALL-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C1]](s64)
+ ; LIBCALL-NEXT: $x10 = COPY [[ASHR]](s64)
+ ; LIBCALL-NEXT: $x11 = COPY [[ASHR1]](s64)
+ ; LIBCALL-NEXT: PseudoCALL target-flags(riscv-call) &__muldi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; LIBCALL-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10
+ ; LIBCALL-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; LIBCALL-NEXT: [[SHL2:%[0-9]+...
[truncated]
|
@@ -145,13 +145,21 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) { | |||
.legalFor({XLenLLT}) | |||
.lower(); | |||
// clang-format on | |||
|
|||
getActionDefinitionsBuilder({G_SMULO, G_UMULO}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am maybe blind, but could you hoist them above the if? They look similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah they're the same. They were briefly different while I tried and failed to fix the 2 libcall issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a feeling that you are going for coverage and not performance. Could you instead do a custom
legalization, i.e. RISC-V specific and not generic lower?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The widening of small types creates an XLenLLT sized G_SMULO even though that can't overflow if the small type was half of XLen or less. I don't know how to distinquish that G_SMULO from the original. So I ended up with a double XLen libcall no matter what which is not really what I wanted.
I guess I could write custom legalization for everything, but didn't seem ideal.
✅ With the latest revision this PR passed the C/C++ code formatter. |
Ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
// the low bits for the mul result and high bits to do the overflow | ||
// check. | ||
.widenScalarIf( | ||
[=, &ST](const LegalityQuery &Query) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for ST
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Copy and pasted from elsewhere. Will remove.
I'm unhappy with the XLen case when we need to make a libcall. We get two libcalls.