[llvm] [RISCV] Support RVV register overlapping constraints (PR #145004)
Pengcheng Wang via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 22 21:05:51 PDT 2025
================
@@ -1040,3 +1047,221 @@ bool RISCVRegisterInfo::getRegAllocationHints(
return BaseImplRetVal;
}
+
+unsigned RISCVRegisterInfo::getMCRegIndex(MCRegister Reg,
+ const MachineRegisterInfo *MRI) {
+ const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
+ return TRI->getEncodingValue(Reg);
+}
+
+unsigned RISCVRegisterInfo::getMCRegLMUL(MCRegister Reg) {
+ if (RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg))
+ return 1;
+ if (RISCVMCRegisterClasses[RISCV::VRM2RegClassID].contains(Reg))
+ return 2;
+ if (RISCVMCRegisterClasses[RISCV::VRM4RegClassID].contains(Reg))
+ return 4;
+ if (RISCVMCRegisterClasses[RISCV::VRM8RegClassID].contains(Reg))
+ return 8;
+
+ llvm_unreachable("Not supported Register.");
+}
+
+// The destination EEW is smaller than the source EEW and the overlap is in the
+// lowest-numbered part of the source register group (e.g., when LMUL=1,
+// vnsrl.wi v0, v0, 3 is legal, but a destination of v1 is not).
+bool RISCVRegisterInfo::isRVVConstraintsType2(unsigned DestRegIndex,
+ unsigned DestRegLMUL,
+ unsigned SrcRegIndex,
+ unsigned SrcRegLMUL) {
+ if (DestRegIndex == SrcRegIndex)
+ return false;
+
+ return SrcRegIndex < DestRegIndex && DestRegIndex < SrcRegIndex + SrcRegLMUL;
+}
+
+// The destination EEW is greater than the source EEW, the source EMUL is at
+// least 1, and the overlap is in the highest-numbered part of the destination
+// register group (e.g., when LMUL=8, vzext.vf4 v0, v6 is legal, but a source of
+// v0, v2, or v4 is not).
+bool RISCVRegisterInfo::isRVVConstraintsType3(unsigned DestRegIndex,
+ unsigned DestRegLMUL,
+ unsigned SrcRegIndex,
+ unsigned SrcRegLMUL) {
+ if (DestRegLMUL == SrcRegLMUL && DestRegIndex == SrcRegIndex)
+ return true;
+
+ if (SrcRegIndex == DestRegIndex + DestRegLMUL - SrcRegLMUL)
+ return false;
+
+ return DestRegIndex <= SrcRegIndex &&
+ SrcRegIndex < DestRegIndex + DestRegLMUL - SrcRegLMUL;
+}
+
+static MCRegister getPhysicalReg(const MachineOperand MO,
+ const MachineOperand MObeAllocated,
+ MCRegister PhysRegbeAllocated,
+ const VirtRegMap *VRM) {
+ if (MObeAllocated.isIdenticalTo(MO))
+ return PhysRegbeAllocated;
+
+ if (MO.getReg().isPhysical())
+ return MO.getReg().asMCReg();
+
+ if (MO.getReg().isVirtual() && VRM->hasPhys(MO.getReg()))
+ return VRM->getPhys(MO.getReg());
+
+ return PhysRegbeAllocated;
+}
+
+static bool checkConstraintsWithTwoOperand(
+ const MachineInstr *MI, const MachineOperand MObeAllocated,
+ MCRegister PhysRegbeAllocated, MachineOperand DestMO, MachineOperand SrcMO,
+ const MachineRegisterInfo *MRI, const VirtRegMap *VRM) {
+
+ assert(DestMO.isReg() && SrcMO.isReg() && "Must be Register");
+
+ // Allocate for DestMO or SrcMO.
+ if (!MObeAllocated.isIdenticalTo(DestMO) &&
+ !MObeAllocated.isIdenticalTo(SrcMO))
+ return false;
+
+ // Another Operand already assign phyiscal register.
+ if (DestMO.getReg().isVirtual() && !VRM->hasPhys(DestMO.getReg()) &&
+ SrcMO.getReg().isVirtual() && !VRM->hasPhys(SrcMO.getReg()))
+ return false;
+
+ MCRegister DestReg =
+ getPhysicalReg(DestMO, MObeAllocated, PhysRegbeAllocated, VRM);
+ MCRegister SrcReg =
+ getPhysicalReg(SrcMO, MObeAllocated, PhysRegbeAllocated, VRM);
+
+ const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
+
+ // Handle sub-register like sub_vrm4_0:vrm8
+ if (DestMO.getSubReg() != 0)
+ DestReg = TRI->getSubReg(DestReg, DestMO.getSubReg());
+
+ if (SrcMO.getSubReg() != 0)
+ SrcReg = TRI->getSubReg(SrcReg, SrcMO.getSubReg());
+
+ unsigned DestRegIndex = RISCVRegisterInfo::getMCRegIndex(DestReg, MRI);
+ unsigned DestRegLMUL = RISCVRegisterInfo::getMCRegLMUL(DestReg);
+ unsigned SrcRegIndex = RISCVRegisterInfo::getMCRegIndex(SrcReg, MRI);
+ unsigned SrcRegLMUL = RISCVRegisterInfo::getMCRegLMUL(SrcReg);
+
+ unsigned OverlapConstraints =
+ RISCVInstrInfo::getOverlapConstraintsFromMI(MI->getOpcode());
+ if (OverlapConstraints == 2)
+ return RISCVRegisterInfo::isRVVConstraintsType2(DestRegIndex, DestRegLMUL,
+ SrcRegIndex, SrcRegLMUL);
+ if (OverlapConstraints == 3)
+ return RISCVRegisterInfo::isRVVConstraintsType3(DestRegIndex, DestRegLMUL,
+ SrcRegIndex, SrcRegLMUL);
+ return false;
+}
+
+static bool isVectorVirtRegClass(MachineOperand MO, Register R,
+ const MachineRegisterInfo *MRI) {
+ // Register like sub_vrm4_0:vrn2m4 also need check.
+ return RISCV::VRRegClass.hasSubClassEq(MRI->getRegClass(R)) ||
----------------
wangpc-pp wrote:
Use isRVVRegClass?
https://github.com/llvm/llvm-project/pull/145004
More information about the llvm-commits
mailing list