Skip to content

Commit d360963

Browse files
authored
[RISCV] Add regalloc hints for Zcb instructions. (#78949)
This hints the register allocator to use the same register for source and destination to enable more compression.
1 parent a0f69be commit d360963

File tree

2 files changed

+120
-6
lines changed

2 files changed

+120
-6
lines changed

llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,7 @@ bool RISCVRegisterInfo::getRegAllocationHints(
753753
SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,
754754
const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
755755
const MachineRegisterInfo *MRI = &MF.getRegInfo();
756+
auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
756757

757758
bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
758759
VirtReg, Order, Hints, MF, VRM, Matrix);
@@ -776,7 +777,7 @@ bool RISCVRegisterInfo::getRegAllocationHints(
776777

777778
// This is all of the compressible binary instructions. If an instruction
778779
// needs GPRC register class operands \p NeedGPRC will be set to true.
779-
auto isCompressible = [](const MachineInstr &MI, bool &NeedGPRC) {
780+
auto isCompressible = [&Subtarget](const MachineInstr &MI, bool &NeedGPRC) {
780781
NeedGPRC = false;
781782
switch (MI.getOpcode()) {
782783
default:
@@ -789,9 +790,16 @@ bool RISCVRegisterInfo::getRegAllocationHints(
789790
case RISCV::SUBW:
790791
NeedGPRC = true;
791792
return true;
792-
case RISCV::ANDI:
793+
case RISCV::ANDI: {
793794
NeedGPRC = true;
794-
return MI.getOperand(2).isImm() && isInt<6>(MI.getOperand(2).getImm());
795+
if (!MI.getOperand(2).isImm())
796+
return false;
797+
int64_t Imm = MI.getOperand(2).getImm();
798+
if (isInt<6>(Imm))
799+
return true;
800+
// c.zext.b
801+
return Subtarget.hasStdExtZcb() && Imm == 255;
802+
}
795803
case RISCV::SRAI:
796804
case RISCV::SRLI:
797805
NeedGPRC = true;
@@ -802,6 +810,24 @@ bool RISCVRegisterInfo::getRegAllocationHints(
802810
case RISCV::ADDI:
803811
case RISCV::ADDIW:
804812
return MI.getOperand(2).isImm() && isInt<6>(MI.getOperand(2).getImm());
813+
case RISCV::MUL:
814+
case RISCV::SEXT_B:
815+
case RISCV::SEXT_H:
816+
case RISCV::ZEXT_H_RV32:
817+
case RISCV::ZEXT_H_RV64:
818+
// c.mul, c.sext.b, c.sext.h, c.zext.h
819+
NeedGPRC = true;
820+
return Subtarget.hasStdExtZcb();
821+
case RISCV::ADD_UW:
822+
// c.zext.w
823+
NeedGPRC = true;
824+
return Subtarget.hasStdExtZcb() && MI.getOperand(2).isReg() &&
825+
MI.getOperand(2).getReg() == RISCV::X0;
826+
case RISCV::XORI:
827+
// c.not
828+
NeedGPRC = true;
829+
return Subtarget.hasStdExtZcb() && MI.getOperand(2).isImm() &&
830+
MI.getOperand(2).getImm() == -1;
805831
}
806832
};
807833

@@ -823,13 +849,15 @@ bool RISCVRegisterInfo::getRegAllocationHints(
823849
bool NeedGPRC;
824850
if (isCompressible(MI, NeedGPRC)) {
825851
if (OpIdx == 0 && MI.getOperand(1).isReg()) {
826-
if (!NeedGPRC || isCompressibleOpnd(MI.getOperand(2)))
852+
if (!NeedGPRC || MI.getNumExplicitOperands() < 3 ||
853+
MI.getOpcode() == RISCV::ADD_UW ||
854+
isCompressibleOpnd(MI.getOperand(2)))
827855
tryAddHint(MO, MI.getOperand(1), NeedGPRC);
828856
if (MI.isCommutable() && MI.getOperand(2).isReg() &&
829857
(!NeedGPRC || isCompressibleOpnd(MI.getOperand(1))))
830858
tryAddHint(MO, MI.getOperand(2), NeedGPRC);
831-
} else if (OpIdx == 1 &&
832-
(!NeedGPRC || isCompressibleOpnd(MI.getOperand(2)))) {
859+
} else if (OpIdx == 1 && (!NeedGPRC || MI.getNumExplicitOperands() < 3 ||
860+
isCompressibleOpnd(MI.getOperand(2)))) {
833861
tryAddHint(MO, MI.getOperand(0), NeedGPRC);
834862
} else if (MI.isCommutable() && OpIdx == 2 &&
835863
(!NeedGPRC || isCompressibleOpnd(MI.getOperand(1)))) {
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba,+zbb,+zcb | FileCheck %s
3+
4+
define i64 @c_not(i64 %x, i64 %y, i64 %z) {
5+
; CHECK-LABEL: c_not:
6+
; CHECK: # %bb.0:
7+
; CHECK-NEXT: not a1, a1
8+
; CHECK-NEXT: li a0, 1234
9+
; CHECK-NEXT: mul a0, a0, a1
10+
; CHECK-NEXT: ret
11+
%a = xor i64 %y, -1
12+
%b = mul i64 %a, 1234
13+
ret i64 %b
14+
}
15+
16+
define i64 @c_mul(i64 %x, i64 %y, i64 %z, i64 %w) {
17+
; CHECK-LABEL: c_mul:
18+
; CHECK: # %bb.0:
19+
; CHECK-NEXT: mul a1, a1, a2
20+
; CHECK-NEXT: lui a0, 1
21+
; CHECK-NEXT: or a0, a0, a1
22+
; CHECK-NEXT: ret
23+
%a = mul i64 %y, %z
24+
%b = or i64 %a, 4096
25+
ret i64 %b
26+
}
27+
28+
define i64 @c_sext_b(i64 %x, i8 %y, i64 %z) {
29+
; CHECK-LABEL: c_sext_b:
30+
; CHECK: # %bb.0:
31+
; CHECK-NEXT: sext.b a1, a1
32+
; CHECK-NEXT: lui a0, 1
33+
; CHECK-NEXT: or a0, a0, a1
34+
; CHECK-NEXT: ret
35+
%a = sext i8 %y to i64
36+
%b = or i64 %a, 4096
37+
ret i64 %b
38+
}
39+
40+
define i64 @c_sext_h(i64 %x, i16 %y, i64 %z) {
41+
; CHECK-LABEL: c_sext_h:
42+
; CHECK: # %bb.0:
43+
; CHECK-NEXT: sext.h a1, a1
44+
; CHECK-NEXT: lui a0, 1
45+
; CHECK-NEXT: or a0, a0, a1
46+
; CHECK-NEXT: ret
47+
%a = sext i16 %y to i64
48+
%b = or i64 %a, 4096
49+
ret i64 %b
50+
}
51+
52+
define i64 @c_zext_b(i64 %x, i8 %y, i64 %z) {
53+
; CHECK-LABEL: c_zext_b:
54+
; CHECK: # %bb.0:
55+
; CHECK-NEXT: andi a1, a1, 255
56+
; CHECK-NEXT: lui a0, 1
57+
; CHECK-NEXT: or a0, a0, a1
58+
; CHECK-NEXT: ret
59+
%a = zext i8 %y to i64
60+
%b = or i64 %a, 4096
61+
ret i64 %b
62+
}
63+
64+
define i64 @c_zext_h(i64 %x, i16 %y) {
65+
; CHECK-LABEL: c_zext_h:
66+
; CHECK: # %bb.0:
67+
; CHECK-NEXT: zext.h a1, a1
68+
; CHECK-NEXT: lui a0, 4096
69+
; CHECK-NEXT: or a0, a0, a1
70+
; CHECK-NEXT: ret
71+
%a = zext i16 %y to i64
72+
%b = or i64 %a, 16777216
73+
ret i64 %b
74+
}
75+
76+
define i64 @c_zext_w(i64 %x, i32 %y) {
77+
; CHECK-LABEL: c_zext_w:
78+
; CHECK: # %bb.0:
79+
; CHECK-NEXT: zext.w a1, a1
80+
; CHECK-NEXT: li a0, 1234
81+
; CHECK-NEXT: mul a0, a0, a1
82+
; CHECK-NEXT: ret
83+
%a = zext i32 %y to i64
84+
%b = mul i64 %a, 1234
85+
ret i64 %b
86+
}

0 commit comments

Comments
 (0)