-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV] Custom promote s32 G_UDIV/UREM/SDIV on RV64. Promote SREM using G_SEXT. #115402
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
Conversation
SREM is promoted with G_SEXT just like SelectionDAG. Need to add a GISel equivalent of sexti32 ComplexPattern to select as REMW.
@llvm/pr-subscribers-llvm-globalisel @llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesWe don't add a custom node for SREM as we can detect it with (srem (sexti32), (sexti32)) Patch is 25.61 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/115402.diff 6 Files Affected:
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 0704b57ff95650..53ae01ef05ee93 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -456,11 +456,17 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
}
if (ST.hasStdExtM()) {
- getActionDefinitionsBuilder({G_UDIV, G_SDIV, G_UREM, G_SREM})
- .legalFor({s32, sXLen})
+ getActionDefinitionsBuilder({G_UDIV, G_SDIV, G_UREM})
+ .legalFor({sXLen})
+ .customFor({s32})
.libcallFor({sDoubleXLen})
.clampScalar(0, s32, sDoubleXLen)
.widenScalarToNextPow2(0);
+ getActionDefinitionsBuilder(G_SREM)
+ .legalFor({sXLen})
+ .libcallFor({sDoubleXLen})
+ .clampScalar(0, sXLen, sDoubleXLen)
+ .widenScalarToNextPow2(0);
} else {
getActionDefinitionsBuilder({G_UDIV, G_SDIV, G_UREM, G_SREM})
.libcallFor({sXLen, sDoubleXLen})
@@ -1163,6 +1169,12 @@ static unsigned getRISCVWOpcode(unsigned Opcode) {
switch (Opcode) {
default:
llvm_unreachable("Unexpected opcode");
+ case TargetOpcode::G_SDIV:
+ return RISCV::G_DIVW;
+ case TargetOpcode::G_UDIV:
+ return RISCV::G_DIVUW;
+ case TargetOpcode::G_UREM:
+ return RISCV::G_REMUW;
case TargetOpcode::G_ROTL:
return RISCV::G_ROLW;
case TargetOpcode::G_ROTR:
@@ -1210,6 +1222,9 @@ bool RISCVLegalizerInfo::legalizeCustom(
return Helper.lower(MI, 0, /* Unused hint type */ LLT()) ==
LegalizerHelper::Legalized;
}
+ case TargetOpcode::G_SDIV:
+ case TargetOpcode::G_UDIV:
+ case TargetOpcode::G_UREM:
case TargetOpcode::G_ROTL:
case TargetOpcode::G_ROTR: {
Helper.Observer.changingInstr(MI);
diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td
index 10906aebf1bf84..61a09f6721b6b4 100644
--- a/llvm/lib/Target/RISCV/RISCVGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVGISel.td
@@ -255,13 +255,6 @@ let Predicates = [HasStdExtZmmul, IsRV64] in {
def : PatGprGpr<mul, MULW, i32, i32>;
}
-let Predicates = [HasStdExtM, IsRV64] in {
-def : PatGprGpr<sdiv, DIVW, i32, i32>;
-def : PatGprGpr<udiv, DIVUW, i32, i32>;
-def : PatGprGpr<srem, REMW, i32, i32>;
-def : PatGprGpr<urem, REMUW, i32, i32>;
-}
-
//===----------------------------------------------------------------------===//
// Zb* RV64 i32 patterns not used by SelectionDAG.
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrGISel.td b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
index 424623360d2556..eb4fddd6569ac7 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
@@ -17,6 +17,30 @@ class RISCVGenericInstruction : GenericInstruction {
let Namespace = "RISCV";
}
+// Pseudo equivalent to a RISCVISD::DIVW.
+def G_DIVW : RISCVGenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = false;
+}
+def : GINodeEquiv<G_DIVW, riscv_divw>;
+
+// Pseudo equivalent to a RISCVISD::DIVUW.
+def G_DIVUW : RISCVGenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = false;
+}
+def : GINodeEquiv<G_DIVUW, riscv_divuw>;
+
+// Pseudo equivalent to a RISCVISD::REMUW.
+def G_REMUW : RISCVGenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = false;
+}
+def : GINodeEquiv<G_REMUW, riscv_remuw>;
+
// Pseudo equivalent to a RISCVISD::RORW.
def G_RORW : RISCVGenericInstruction {
let OutOperandList = (outs type0:$dst);
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu_m-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu_m-rv64.mir
index f748f0811a99c6..50c61ad1a051bf 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu_m-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu_m-rv64.mir
@@ -47,39 +47,9 @@ body: |
; RV64I-NEXT: $x10 = COPY [[DIVW]]
; RV64I-NEXT: PseudoRET implicit $x10
%0:gprb(s64) = COPY $x10
- %1:gprb(s32) = G_TRUNC %0(s64)
- %2:gprb(s64) = COPY $x11
- %3:gprb(s32) = G_TRUNC %2(s64)
- %4:gprb(s32) = G_SDIV %1, %3
- %5:gprb(s64) = G_ANYEXT %4(s32)
- $x10 = COPY %5(s64)
- PseudoRET implicit $x10
-
-...
----
-name: srem_i32
-legalized: true
-regBankSelected: true
-tracksRegLiveness: true
-body: |
- bb.0.entry:
- liveins: $x10, $x11
-
- ; RV64I-LABEL: name: srem_i32
- ; RV64I: liveins: $x10, $x11
- ; RV64I-NEXT: {{ $}}
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
- ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
- ; RV64I-NEXT: [[REMW:%[0-9]+]]:gpr = REMW [[COPY]], [[COPY1]]
- ; RV64I-NEXT: $x10 = COPY [[REMW]]
- ; RV64I-NEXT: PseudoRET implicit $x10
- %0:gprb(s64) = COPY $x10
- %1:gprb(s32) = G_TRUNC %0(s64)
- %2:gprb(s64) = COPY $x11
- %3:gprb(s32) = G_TRUNC %2(s64)
- %4:gprb(s32) = G_SREM %1, %3
- %5:gprb(s64) = G_ANYEXT %4(s32)
- $x10 = COPY %5(s64)
+ %1:gprb(s64) = COPY $x11
+ %2:gprb(s64) = G_DIVW %0, %1
+ $x10 = COPY %2(s64)
PseudoRET implicit $x10
...
@@ -101,12 +71,9 @@ body: |
; RV64I-NEXT: $x10 = COPY [[DIVUW]]
; RV64I-NEXT: PseudoRET implicit $x10
%0:gprb(s64) = COPY $x10
- %1:gprb(s32) = G_TRUNC %0(s64)
- %2:gprb(s64) = COPY $x11
- %3:gprb(s32) = G_TRUNC %2(s64)
- %4:gprb(s32) = G_UDIV %1, %3
- %5:gprb(s64) = G_ANYEXT %4(s32)
- $x10 = COPY %5(s64)
+ %1:gprb(s64) = COPY $x11
+ %2:gprb(s64) = G_DIVUW %0, %1
+ $x10 = COPY %2(s64)
PseudoRET implicit $x10
...
@@ -124,16 +91,13 @@ body: |
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
- ; RV64I-NEXT: [[REMUW:%[0-9]+]]:gpr = REMUW [[COPY]], [[COPY1]]
- ; RV64I-NEXT: $x10 = COPY [[REMUW]]
+ ; RV64I-NEXT: [[REMU:%[0-9]+]]:gpr = REMU [[COPY]], [[COPY1]]
+ ; RV64I-NEXT: $x10 = COPY [[REMU]]
; RV64I-NEXT: PseudoRET implicit $x10
%0:gprb(s64) = COPY $x10
- %1:gprb(s32) = G_TRUNC %0(s64)
- %2:gprb(s64) = COPY $x11
- %3:gprb(s32) = G_TRUNC %2(s64)
- %4:gprb(s32) = G_UREM %1, %3
- %5:gprb(s64) = G_ANYEXT %4(s32)
- $x10 = COPY %5(s64)
+ %1:gprb(s64) = COPY $x11
+ %2:gprb(s64) = G_UREM %0, %1
+ $x10 = COPY %2(s64)
PseudoRET implicit $x10
...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir
index 183f5e59282396..657dd3cc63226b 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-div-rv64.mir
@@ -27,16 +27,13 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
- ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[TRUNC]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[TRUNC1]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
- ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[ASHR]], [[ASHR1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[SDIV]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[DIVW:%[0-9]+]]:_(s64) = G_DIVW [[ASHR]], [[ASHR1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[DIVW]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
@@ -72,16 +69,13 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 17
- ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[TRUNC]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[TRUNC1]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
- ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[ASHR]], [[ASHR1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[SDIV]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 49
+ ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[DIVW:%[0-9]+]]:_(s64) = G_DIVW [[ASHR]], [[ASHR1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[DIVW]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
@@ -117,16 +111,13 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
- ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[TRUNC]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[TRUNC1]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
- ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[ASHR]], [[ASHR1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[SDIV]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
+ ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[DIVW:%[0-9]+]]:_(s64) = G_DIVW [[ASHR]], [[ASHR1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[DIVW]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
@@ -159,11 +150,8 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[TRUNC]], [[TRUNC1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[SDIV]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; CHECK-M-NEXT: [[DIVW:%[0-9]+]]:_(s64) = G_DIVW [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[DIVW]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
@@ -343,14 +331,11 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
- ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[TRUNC]], [[C]]
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[TRUNC1]], [[C]]
- ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[AND]], [[AND1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[UDIV]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; 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: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C]]
+ ; CHECK-M-NEXT: [[DIVUW:%[0-9]+]]:_(s64) = G_DIVUW [[AND]], [[AND1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[DIVUW]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
@@ -384,14 +369,11 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 32767
- ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[TRUNC]], [[C]]
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[TRUNC1]], [[C]]
- ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[AND]], [[AND1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[UDIV]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; 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: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C]]
+ ; CHECK-M-NEXT: [[DIVUW:%[0-9]+]]:_(s64) = G_DIVUW [[AND]], [[AND1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[DIVUW]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
@@ -425,14 +407,11 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
- ; CHECK-M-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[TRUNC]], [[C]]
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[TRUNC1]], [[C]]
- ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[AND]], [[AND1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[UDIV]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; 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: [[AND1:%[0-9]+]]:_(s64) = G_AND [[COPY1]], [[C]]
+ ; CHECK-M-NEXT: [[DIVUW:%[0-9]+]]:_(s64) = G_DIVUW [[AND]], [[AND1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[DIVUW]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
@@ -466,11 +445,8 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[TRUNC]], [[TRUNC1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[UDIV]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; CHECK-M-NEXT: [[DIVUW:%[0-9]+]]:_(s64) = G_DIVUW [[COPY]], [[COPY1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[DIVUW]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-rem-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-rem-rv64.mir
index cd951688843eee..8239bb69508675 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-rem-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-rem-rv64.mir
@@ -27,16 +27,13 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
- ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[TRUNC]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[TRUNC1]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
- ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[ASHR]], [[ASHR1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[SREM]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[ASHR]], [[ASHR1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
@@ -72,16 +69,13 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 17
- ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[TRUNC]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[TRUNC1]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
- ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[ASHR]], [[ASHR1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[SREM]](s32)
- ; CHECK-M-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 49
+ ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C]](s64)
+ ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s64) = G_SREM [[ASHR]], [[ASHR1]]
+ ; CHECK-M-NEXT: $x10 = COPY [[SREM]](s64)
; CHECK-M-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%1:_(s64) = COPY $x11
@@ -117,16 +111,13 @@ body: |
; 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: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; CHECK-M-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
- ; CHECK-M-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[TRUNC]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
- ; CHECK-M-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
- ; CHECK-M-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[TRUNC1]], [[C]](s32)
- ; CHECK-M-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
- ; CHECK-M-NEXT: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[ASHR]], [[ASHR1]]
- ; CHECK-M-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[SREM]](s32)
- ; C...
[truncated]
|
PseudoRET implicit $x10 | ||
|
||
... | ||
--- |
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 removed the srem i32 test here but it's still covered by an IR test.
llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu_m-rv64.mir
Outdated
Show resolved
Hide resolved
as a result of |
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
def G_REMUW : RISCVGenericInstruction { | ||
let OutOperandList = (outs type0:$dst); | ||
let InOperandList = (ins type0:$src1, type0:$src2); | ||
let hasSideEffects = false; | ||
} | ||
def : GINodeEquiv<G_REMUW, riscv_remuw>; |
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.
we probably can factor out RISCVGenericInstruction of this kind into a separate TableGen class in the future
That's how the type is widened, but the comment was about the math. The important thing is that the behavior of (srem (sexti32 X), (sexti32 Y)) is exactly equivalent to REMW for all values of X and Y. From computeNumSignBits for srem.
The result of (sexti32 X) has at least 33 sign bits so the result of (srem (sexti32 X), (sexti32 Y)) has at least 33 sign bits. REMW produces a value with at least 33 sign bits. This doesn't work for (sdiv (sexti32 X), (sexti32 Y)). 0xffffffff80000000 / 0xfffffffffffffff is 0x0000000080000000, but DIVW produces 0xffffffff80000000 for that case. We use a custom opcode to remember that we started with i32 where 0x80000000 / 0xffffffff is immediate UB so that case doesn't matter. (urem (zexti32 X), (zexti32 Y)) is not equivalent to REMUW because 0x0000000080000000 % 0x00000000ffffffff is 0x0000000080000000, but REMUW will produce 0xffffffff80000000. Since we started with an i32 type, the upper bits don't matter at the time of promotion so we use a custom opcode to remember that. After promotion, later optimizations may become dependent on the G_REMUW producing a sign extended value. Though I haven't addded that to computeNumSignBits yet for GISel. (udiv (zexti32 X), (zexti32 Y)) is not equivalent to DIVUW because 0x0000000080000000 % 0x0000000000000001 is 0x0000000080000000, but DIVUW will return 0xffffffff80000000. Again at promotion time the upper don't matter so we use a custom opcode. |
…ng G_SEXT. (llvm#115402) We don't add a custom node for REMW as we can detect it with (srem (sexti32), (sexti32)).
We don't add a custom node for SREM as we can detect it with (srem (sexti32), (sexti32))