diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h index 337fab735a095..4fb6ba7c26930 100644 --- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -283,8 +283,8 @@ class TargetRegisterInfo : public MCRegisterInfo { // DenseMapInfo uses -1u and -2u. /// Return the size in bits of a register from class RC. - unsigned getRegSizeInBits(const TargetRegisterClass &RC) const { - return getRegClassInfo(RC).RegSize; + TypeSize getRegSizeInBits(const TargetRegisterClass &RC) const { + return TypeSize::Fixed(getRegClassInfo(RC).RegSize); } /// Return the size in bytes of the stack slot allocated to hold a spilled @@ -858,7 +858,7 @@ class TargetRegisterInfo : public MCRegisterInfo { const TargetRegisterClass *RC) const = 0; /// Returns size in bits of a phys/virtual/generic register. - unsigned getRegSizeInBits(Register Reg, const MachineRegisterInfo &MRI) const; + TypeSize getRegSizeInBits(Register Reg, const MachineRegisterInfo &MRI) const; /// Get the weight in units of pressure for this register unit. virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0; diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index dadaf60fa09da..dc15f0d3b8423 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1937,8 +1937,8 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { // If we have only one valid type, this is likely a copy between a virtual // and physical register. - unsigned SrcSize = 0; - unsigned DstSize = 0; + TypeSize SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI); + TypeSize DstSize = TRI->getRegSizeInBits(DstReg, *MRI); if (SrcReg.isPhysical() && DstTy.isValid()) { const TargetRegisterClass *SrcRC = TRI->getMinimalPhysRegClassLLT(SrcReg, DstTy); @@ -1946,9 +1946,6 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { SrcSize = TRI->getRegSizeInBits(*SrcRC); } - if (SrcSize == 0) - SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI); - if (DstReg.isPhysical() && SrcTy.isValid()) { const TargetRegisterClass *DstRC = TRI->getMinimalPhysRegClassLLT(DstReg, SrcTy); @@ -1956,10 +1953,15 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { DstSize = TRI->getRegSizeInBits(*DstRC); } - if (DstSize == 0) - DstSize = TRI->getRegSizeInBits(DstReg, *MRI); + // If this is a copy from physical register to virtual register, and if the + // Dst is scalable and the Src is fixed, then the Dst can only hold the Src + // if the minimum size Dst can hold is at least as big as Src. + if (SrcReg.isPhysical() && DstReg.isVirtual() && DstSize.isScalable() && + !SrcSize.isScalable() && + DstSize.getKnownMinValue() <= SrcSize.getFixedValue()) + break; - if (SrcSize != 0 && DstSize != 0 && SrcSize != DstSize) { + if (SrcSize.isNonZero() && DstSize.isNonZero() && SrcSize != DstSize) { if (!DstOp.getSubReg() && !SrcOp.getSubReg()) { report("Copy Instruction is illegal with mismatching sizes", MI); errs() << "Def Size = " << DstSize << ", Src Size = " << SrcSize diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp index 1bb35f40facfd..c50b1cf942271 100644 --- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp +++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp @@ -499,7 +499,7 @@ bool TargetRegisterInfo::regmaskSubsetEqual(const uint32_t *mask0, return true; } -unsigned +TypeSize TargetRegisterInfo::getRegSizeInBits(Register Reg, const MachineRegisterInfo &MRI) const { const TargetRegisterClass *RC{}; @@ -508,16 +508,15 @@ TargetRegisterInfo::getRegSizeInBits(Register Reg, // Instead, we need to access a register class that contains Reg and // get the size of that register class. RC = getMinimalPhysRegClass(Reg); - } else { - LLT Ty = MRI.getType(Reg); - unsigned RegSize = Ty.isValid() ? Ty.getSizeInBits() : 0; - // If Reg is not a generic register, query the register class to - // get its size. - if (RegSize) - return RegSize; - // Since Reg is not a generic register, it must have a register class. - RC = MRI.getRegClass(Reg); + assert(RC && "Unable to deduce the register class"); + return getRegSizeInBits(*RC); } + LLT Ty = MRI.getType(Reg); + if (Ty.isValid()) + return Ty.getSizeInBits(); + + // Since Reg is not a generic register, it may have a register class. + RC = MRI.getRegClass(Reg); assert(RC && "Unable to deduce the register class"); return getRegSizeInBits(*RC); } diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll index 5dd62de8a6bc4..a3a913d8ce02d 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll @@ -22,7 +22,7 @@ entry: ret %a } -; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to translate instruction{{.*}}scalable_inst +; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to translate instruction: call: ; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_inst define @scalable_inst(i64 %0) nounwind { entry: @@ -35,7 +35,7 @@ entry: ret %a } -; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to translate instruction{{.*}}scalable_alloca +; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to translate instruction: alloca: ; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_alloca define void @scalable_alloca() #1 { %local0 = alloca diff --git a/llvm/test/MachineVerifier/copy-scalable.mir b/llvm/test/MachineVerifier/copy-scalable.mir new file mode 100644 index 0000000000000..f4088f7aed34d --- /dev/null +++ b/llvm/test/MachineVerifier/copy-scalable.mir @@ -0,0 +1,23 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3 +# RUN: llc -mtriple=riscv64 -o - -global-isel -run-pass=none -verify-machineinstrs %s | FileCheck %s +# REQUIRES: riscv64-registered-target + +--- +name: test_copy_fixed_to_scalable +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: _, preferred-register: '' } +liveins: +body: | + bb.0: + liveins: $v8 + + ; CHECK-LABEL: name: test_copy_fixed_to_scalable + ; CHECK: liveins: $v8 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_() = COPY $v8 + %0:_() = COPY $v8 +...