-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV] Add regalloc hints for Zcb instructions. #78949
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
@llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesThis hints the register allocator to use the same register for source and destination to enable more compression. Full diff: https://github.com/llvm/llvm-project/pull/78949.diff 2 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index 730838ea004aa2a..16ded1403272a2d 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -753,6 +753,7 @@ bool RISCVRegisterInfo::getRegAllocationHints(
SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,
const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
const MachineRegisterInfo *MRI = &MF.getRegInfo();
+ auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
VirtReg, Order, Hints, MF, VRM, Matrix);
@@ -776,7 +777,7 @@ bool RISCVRegisterInfo::getRegAllocationHints(
// This is all of the compressible binary instructions. If an instruction
// needs GPRC register class operands \p NeedGPRC will be set to true.
- auto isCompressible = [](const MachineInstr &MI, bool &NeedGPRC) {
+ auto isCompressible = [&Subtarget](const MachineInstr &MI, bool &NeedGPRC) {
NeedGPRC = false;
switch (MI.getOpcode()) {
default:
@@ -789,9 +790,16 @@ bool RISCVRegisterInfo::getRegAllocationHints(
case RISCV::SUBW:
NeedGPRC = true;
return true;
- case RISCV::ANDI:
+ case RISCV::ANDI: {
NeedGPRC = true;
- return MI.getOperand(2).isImm() && isInt<6>(MI.getOperand(2).getImm());
+ if (!MI.getOperand(2).isImm())
+ return false;
+ int64_t Imm = MI.getOperand(2).getImm();
+ if (isInt<6>(Imm))
+ return true;
+ // c.zext.h
+ return Subtarget.hasStdExtZcb() && Imm == 255;
+ }
case RISCV::SRAI:
case RISCV::SRLI:
NeedGPRC = true;
@@ -802,6 +810,23 @@ bool RISCVRegisterInfo::getRegAllocationHints(
case RISCV::ADDI:
case RISCV::ADDIW:
return MI.getOperand(2).isImm() && isInt<6>(MI.getOperand(2).getImm());
+ case RISCV::MUL:
+ case RISCV::SEXT_B:
+ case RISCV::SEXT_H:
+ case RISCV::ZEXT_H_RV32:
+ case RISCV::ZEXT_H_RV64:
+ // c.mul, c.sext.b, c.sext.h, c.zext.h
+ NeedGPRC = true;
+ return Subtarget.hasStdExtZcb();
+ case RISCV::ADD_UW:
+ // c.zext.w
+ NeedGPRC = true;
+ return Subtarget.hasStdExtZcb() && MI.getOperand(2).getReg() == RISCV::X0;
+ case RISCV::XORI:
+ // c.not
+ NeedGPRC = true;
+ return Subtarget.hasStdExtZcb() && MI.getOperand(2).isImm() &&
+ MI.getOperand(2).getImm() == -1;
}
};
@@ -823,13 +848,15 @@ bool RISCVRegisterInfo::getRegAllocationHints(
bool NeedGPRC;
if (isCompressible(MI, NeedGPRC)) {
if (OpIdx == 0 && MI.getOperand(1).isReg()) {
- if (!NeedGPRC || isCompressibleOpnd(MI.getOperand(2)))
+ if (!NeedGPRC || MI.getNumExplicitOperands() < 3 ||
+ MI.getOpcode() == RISCV::ADD_UW ||
+ isCompressibleOpnd(MI.getOperand(2)))
tryAddHint(MO, MI.getOperand(1), NeedGPRC);
if (MI.isCommutable() && MI.getOperand(2).isReg() &&
(!NeedGPRC || isCompressibleOpnd(MI.getOperand(1))))
tryAddHint(MO, MI.getOperand(2), NeedGPRC);
- } else if (OpIdx == 1 &&
- (!NeedGPRC || isCompressibleOpnd(MI.getOperand(2)))) {
+ } else if (OpIdx == 1 && (!NeedGPRC || MI.getNumExplicitOperands() < 3 ||
+ isCompressibleOpnd(MI.getOperand(2)))) {
tryAddHint(MO, MI.getOperand(0), NeedGPRC);
} else if (MI.isCommutable() && OpIdx == 2 &&
(!NeedGPRC || isCompressibleOpnd(MI.getOperand(1)))) {
diff --git a/llvm/test/CodeGen/RISCV/zcb-regalloc-hints.ll b/llvm/test/CodeGen/RISCV/zcb-regalloc-hints.ll
new file mode 100644
index 000000000000000..545d6c6aca04145
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/zcb-regalloc-hints.ll
@@ -0,0 +1,86 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba,+zbb,+zcb | FileCheck %s
+
+define i64 @c_not(i64 %x, i64 %y, i64 %z) {
+; CHECK-LABEL: c_not:
+; CHECK: # %bb.0:
+; CHECK-NEXT: not a1, a1
+; CHECK-NEXT: li a0, 1234
+; CHECK-NEXT: mul a0, a0, a1
+; CHECK-NEXT: ret
+ %a = xor i64 %y, -1
+ %b = mul i64 %a, 1234
+ ret i64 %b
+}
+
+define i64 @c_mul(i64 %x, i64 %y, i64 %z, i64 %w) {
+; CHECK-LABEL: c_mul:
+; CHECK: # %bb.0:
+; CHECK-NEXT: mul a1, a1, a2
+; CHECK-NEXT: lui a0, 1
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: ret
+ %a = mul i64 %y, %z
+ %b = or i64 %a, 4096
+ ret i64 %b
+}
+
+define i64 @c_sext_b(i64 %x, i8 %y, i64 %z) {
+; CHECK-LABEL: c_sext_b:
+; CHECK: # %bb.0:
+; CHECK-NEXT: sext.b a1, a1
+; CHECK-NEXT: lui a0, 1
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: ret
+ %a = sext i8 %y to i64
+ %b = or i64 %a, 4096
+ ret i64 %b
+}
+
+define i64 @c_sext_h(i64 %x, i16 %y, i64 %z) {
+; CHECK-LABEL: c_sext_h:
+; CHECK: # %bb.0:
+; CHECK-NEXT: sext.h a1, a1
+; CHECK-NEXT: lui a0, 1
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: ret
+ %a = sext i16 %y to i64
+ %b = or i64 %a, 4096
+ ret i64 %b
+}
+
+define i64 @c_zext_b(i64 %x, i8 %y, i64 %z) {
+; CHECK-LABEL: c_zext_b:
+; CHECK: # %bb.0:
+; CHECK-NEXT: andi a1, a1, 255
+; CHECK-NEXT: lui a0, 1
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: ret
+ %a = zext i8 %y to i64
+ %b = or i64 %a, 4096
+ ret i64 %b
+}
+
+define i64 @c_zext_h(i64 %x, i16 %y) {
+; CHECK-LABEL: c_zext_h:
+; CHECK: # %bb.0:
+; CHECK-NEXT: zext.h a1, a1
+; CHECK-NEXT: lui a0, 4096
+; CHECK-NEXT: or a0, a0, a1
+; CHECK-NEXT: ret
+ %a = zext i16 %y to i64
+ %b = or i64 %a, 16777216
+ ret i64 %b
+}
+
+define i64 @c_zext_w(i64 %x, i32 %y) {
+; CHECK-LABEL: c_zext_w:
+; CHECK: # %bb.0:
+; CHECK-NEXT: zext.w a1, a1
+; CHECK-NEXT: li a0, 1234
+; CHECK-NEXT: mul a0, a0, a1
+; CHECK-NEXT: ret
+ %a = zext i32 %y to i64
+ %b = mul i64 %a, 1234
+ ret i64 %b
+}
|
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. Thanks!
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.
This hints the register allocator to use the same register for source and destination to enable more compression.