Skip to content

Commit

Permalink
[CodeGen][MachineVerifier] Use TypeSize instead of unsigned for getRe… (
Browse files Browse the repository at this point in the history
llvm#70881)

…gSizeInBits

This patch changes getRegSizeInBits to return a TypeSize instead of an
unsigned in the case that a virtual register has a scalable LLT. In the
case that register is physical, a Fixed TypeSize is returned.

The MachineVerifier pass is updated to allow copies between fixed and
scalable operands as long as the Src size will fit into the Dest size.

This is a precommit which will be stacked on by a change to GISel to
generate COPYs with a scalable destination but a fixed size source.

This patch is stacked on llvm#70893
for the ability to use scalable vector types in MIR tests.
  • Loading branch information
michaelmaitland committed Nov 7, 2023
1 parent fb8ff4c commit ac4ff61
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 23 deletions.
6 changes: 3 additions & 3 deletions llvm/include/llvm/CodeGen/TargetRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
// DenseMapInfo<unsigned> 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
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 10 additions & 8 deletions llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1937,29 +1937,31 @@ 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);
if (SrcRC)
SrcSize = TRI->getRegSizeInBits(*SrcRC);
}

if (SrcSize == 0)
SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);

if (DstReg.isPhysical() && SrcTy.isValid()) {
const TargetRegisterClass *DstRC =
TRI->getMinimalPhysRegClassLLT(DstReg, SrcTy);
if (DstRC)
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
Expand Down
19 changes: 9 additions & 10 deletions llvm/lib/CodeGen/TargetRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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{};
Expand All @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ entry:
ret <vscale x 1 x i8> %a
}

; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction{{.*}}scalable_inst
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: call:
; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_inst
define <vscale x 1 x i8> @scalable_inst(i64 %0) nounwind {
entry:
Expand All @@ -35,7 +35,7 @@ entry:
ret <vscale x 1 x i8> %a
}

; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction{{.*}}scalable_alloca
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: alloca:
; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_alloca
define void @scalable_alloca() #1 {
%local0 = alloca <vscale x 16 x i8>
Expand Down
23 changes: 23 additions & 0 deletions llvm/test/MachineVerifier/copy-scalable.mir
Original file line number Diff line number Diff line change
@@ -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]+]]:_(<vscale x 1 x s8>) = COPY $v8
%0:_(<vscale x 1 x s8>) = COPY $v8
...

0 comments on commit ac4ff61

Please sign in to comment.