Index: include/llvm/Target/TargetRegisterInfo.h =================================================================== --- include/llvm/Target/TargetRegisterInfo.h +++ include/llvm/Target/TargetRegisterInfo.h @@ -741,6 +741,9 @@ virtual const RegClassWeight &getRegClassWeight( const TargetRegisterClass *RC) const = 0; + /// Returns size in bits of a phys/virtual/generic register. + unsigned getRegSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI) const; + /// Get the weight in units of pressure for this register unit. virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0; Index: lib/CodeGen/GlobalISel/RegisterBankInfo.cpp =================================================================== --- lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -442,24 +442,7 @@ unsigned RegisterBankInfo::getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) { - const TargetRegisterClass *RC = nullptr; - if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - // The size is not directly available for physical registers. - // Instead, we need to access a register class that contains Reg and - // get the size of that register class. - RC = TRI.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 TRI.getRegSizeInBits(*RC); + return TRI.getRegSizeInBits(Reg, MRI); } //------------------------------------------------------------------------------ Index: lib/CodeGen/MachineVerifier.cpp =================================================================== --- lib/CodeGen/MachineVerifier.cpp +++ lib/CodeGen/MachineVerifier.cpp @@ -943,6 +943,26 @@ MI); break; } + case TargetOpcode::COPY: { + const MachineOperand &DstOp = MI->getOperand(0); + const MachineOperand &SrcOp = MI->getOperand(1); + LLT DstTy = MRI->getType(DstOp.getReg()); + LLT SrcTy = MRI->getType(SrcOp.getReg()); + if (SrcTy.isValid() || DstTy.isValid()) { + unsigned SrcSize = TRI->getRegSizeInBits(SrcOp.getReg(), *MRI); + unsigned DstSize = TRI->getRegSizeInBits(DstOp.getReg(), *MRI); + assert(SrcSize && "Expecting size here"); + assert(DstSize && "Expecting size here"); + if (SrcSize != DstSize) + // Catch only obvious cases not involving subregs for now. + if (!DstOp.getSubReg() && !SrcOp.getSubReg()) { + report("Copy Instruction is illegal with mismatching sizes", MI); + errs() << "Def Size = " << DstSize << ", Src Size = " << SrcSize + << "\n"; + } + } + break; + } case TargetOpcode::STATEPOINT: if (!MI->getOperand(StatepointOpers::IDPos).isImm() || !MI->getOperand(StatepointOpers::NBytesPos).isImm() || Index: lib/CodeGen/TargetRegisterInfo.cpp =================================================================== --- lib/CodeGen/TargetRegisterInfo.cpp +++ lib/CodeGen/TargetRegisterInfo.cpp @@ -421,6 +421,21 @@ return true; } +unsigned +TargetRegisterInfo::getRegSizeInBits(unsigned Reg, + const MachineRegisterInfo &MRI) const { + const TargetRegisterClass *RC = nullptr; + if (isPhysicalRegister(Reg)) + RC = getMinimalPhysRegClass(Reg); + else + RC = MRI.getRegClassOrNull(Reg); + if (!RC) { + LLT Ty = MRI.getType(Reg); + assert(Ty.isValid() && "Expecting valid type here"); + return Ty.getSizeInBits(); + } + return getRegSizeInBits(*RC); +} #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void TargetRegisterInfo::dumpReg(unsigned Reg, unsigned SubRegIndex, Index: test/Verifier/test_copy.mir =================================================================== --- /dev/null +++ test/Verifier/test_copy.mir @@ -0,0 +1,30 @@ +#RUN: not llc -o - -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: global-isel, aarch64-registered-target +--- | + ; ModuleID = 'test.ll' + source_filename = "test.ll" + target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" + target triple = "aarch64-unknown-unknown" + + define i32 @test_copy(i32 %argc) { + ret i32 0 + } + +... +--- +name: test_copy +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: _, preferred-register: '' } +liveins: +body: | + bb.0: + liveins: %w0 + ; This test is used to catch verifier errors with copys having mismatching sizes + ; CHECK: Bad machine code: Copy Instruction is illegal with mismatching sizes + + %0(s8) = COPY %w0 +...