Skip to content

Commit ac4ff61

Browse files
[CodeGen][MachineVerifier] Use TypeSize instead of unsigned for getRe… (#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 #70893 for the ability to use scalable vector types in MIR tests.
1 parent fb8ff4c commit ac4ff61

File tree

5 files changed

+47
-23
lines changed

5 files changed

+47
-23
lines changed

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
283283
// DenseMapInfo<unsigned> uses -1u and -2u.
284284

285285
/// Return the size in bits of a register from class RC.
286-
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const {
287-
return getRegClassInfo(RC).RegSize;
286+
TypeSize getRegSizeInBits(const TargetRegisterClass &RC) const {
287+
return TypeSize::Fixed(getRegClassInfo(RC).RegSize);
288288
}
289289

290290
/// Return the size in bytes of the stack slot allocated to hold a spilled
@@ -858,7 +858,7 @@ class TargetRegisterInfo : public MCRegisterInfo {
858858
const TargetRegisterClass *RC) const = 0;
859859

860860
/// Returns size in bits of a phys/virtual/generic register.
861-
unsigned getRegSizeInBits(Register Reg, const MachineRegisterInfo &MRI) const;
861+
TypeSize getRegSizeInBits(Register Reg, const MachineRegisterInfo &MRI) const;
862862

863863
/// Get the weight in units of pressure for this register unit.
864864
virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0;

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,29 +1937,31 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
19371937

19381938
// If we have only one valid type, this is likely a copy between a virtual
19391939
// and physical register.
1940-
unsigned SrcSize = 0;
1941-
unsigned DstSize = 0;
1940+
TypeSize SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
1941+
TypeSize DstSize = TRI->getRegSizeInBits(DstReg, *MRI);
19421942
if (SrcReg.isPhysical() && DstTy.isValid()) {
19431943
const TargetRegisterClass *SrcRC =
19441944
TRI->getMinimalPhysRegClassLLT(SrcReg, DstTy);
19451945
if (SrcRC)
19461946
SrcSize = TRI->getRegSizeInBits(*SrcRC);
19471947
}
19481948

1949-
if (SrcSize == 0)
1950-
SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
1951-
19521949
if (DstReg.isPhysical() && SrcTy.isValid()) {
19531950
const TargetRegisterClass *DstRC =
19541951
TRI->getMinimalPhysRegClassLLT(DstReg, SrcTy);
19551952
if (DstRC)
19561953
DstSize = TRI->getRegSizeInBits(*DstRC);
19571954
}
19581955

1959-
if (DstSize == 0)
1960-
DstSize = TRI->getRegSizeInBits(DstReg, *MRI);
1956+
// If this is a copy from physical register to virtual register, and if the
1957+
// Dst is scalable and the Src is fixed, then the Dst can only hold the Src
1958+
// if the minimum size Dst can hold is at least as big as Src.
1959+
if (SrcReg.isPhysical() && DstReg.isVirtual() && DstSize.isScalable() &&
1960+
!SrcSize.isScalable() &&
1961+
DstSize.getKnownMinValue() <= SrcSize.getFixedValue())
1962+
break;
19611963

1962-
if (SrcSize != 0 && DstSize != 0 && SrcSize != DstSize) {
1964+
if (SrcSize.isNonZero() && DstSize.isNonZero() && SrcSize != DstSize) {
19631965
if (!DstOp.getSubReg() && !SrcOp.getSubReg()) {
19641966
report("Copy Instruction is illegal with mismatching sizes", MI);
19651967
errs() << "Def Size = " << DstSize << ", Src Size = " << SrcSize

llvm/lib/CodeGen/TargetRegisterInfo.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ bool TargetRegisterInfo::regmaskSubsetEqual(const uint32_t *mask0,
499499
return true;
500500
}
501501

502-
unsigned
502+
TypeSize
503503
TargetRegisterInfo::getRegSizeInBits(Register Reg,
504504
const MachineRegisterInfo &MRI) const {
505505
const TargetRegisterClass *RC{};
@@ -508,16 +508,15 @@ TargetRegisterInfo::getRegSizeInBits(Register Reg,
508508
// Instead, we need to access a register class that contains Reg and
509509
// get the size of that register class.
510510
RC = getMinimalPhysRegClass(Reg);
511-
} else {
512-
LLT Ty = MRI.getType(Reg);
513-
unsigned RegSize = Ty.isValid() ? Ty.getSizeInBits() : 0;
514-
// If Reg is not a generic register, query the register class to
515-
// get its size.
516-
if (RegSize)
517-
return RegSize;
518-
// Since Reg is not a generic register, it must have a register class.
519-
RC = MRI.getRegClass(Reg);
511+
assert(RC && "Unable to deduce the register class");
512+
return getRegSizeInBits(*RC);
520513
}
514+
LLT Ty = MRI.getType(Reg);
515+
if (Ty.isValid())
516+
return Ty.getSizeInBits();
517+
518+
// Since Reg is not a generic register, it may have a register class.
519+
RC = MRI.getRegClass(Reg);
521520
assert(RC && "Unable to deduce the register class");
522521
return getRegSizeInBits(*RC);
523522
}

llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ entry:
2222
ret <vscale x 1 x i8> %a
2323
}
2424

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

38-
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction{{.*}}scalable_alloca
38+
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: alloca:
3939
; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_alloca
4040
define void @scalable_alloca() #1 {
4141
%local0 = alloca <vscale x 16 x i8>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
2+
# RUN: llc -mtriple=riscv64 -o - -global-isel -run-pass=none -verify-machineinstrs %s | FileCheck %s
3+
# REQUIRES: riscv64-registered-target
4+
5+
---
6+
name: test_copy_fixed_to_scalable
7+
legalized: true
8+
regBankSelected: false
9+
selected: false
10+
tracksRegLiveness: true
11+
registers:
12+
- { id: 0, class: _, preferred-register: '' }
13+
liveins:
14+
body: |
15+
bb.0:
16+
liveins: $v8
17+
18+
; CHECK-LABEL: name: test_copy_fixed_to_scalable
19+
; CHECK: liveins: $v8
20+
; CHECK-NEXT: {{ $}}
21+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<vscale x 1 x s8>) = COPY $v8
22+
%0:_(<vscale x 1 x s8>) = COPY $v8
23+
...

0 commit comments

Comments
 (0)