[MIR] Check that generic virtual registers get a size.

Without that check it was possible to write test cases where the size
was not specified and we ended up with weird asserts down the road,
because the default value (1) would not make sense.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272226 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Quentin Colombet 2016-06-08 23:27:46 +00:00
parent 45d1685851
commit c4f21c06ed
4 changed files with 55 additions and 4 deletions

View File

@ -970,10 +970,7 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest,
TiedDefIdx = Idx;
}
} else if (consumeIfPresent(MIToken::lparen)) {
// Generic virtual registers must have a size.
// The "must" part will be verify by the machine verifier,
// because at this point we actually do not know if Reg is
// a generic virtual register.
// Virtual registers may have a size with GlobalISel.
if (!TargetRegisterInfo::isVirtualRegister(Reg))
return error("unexpected size on physical register");
unsigned Size;
@ -982,6 +979,11 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest,
MachineRegisterInfo &MRI = MF.getRegInfo();
MRI.setSize(Reg, Size);
} else if (PFS.GenericVRegs.count(Reg)) {
// Generic virtual registers must have a size.
// If we end up here this means the size hasn't been specified and
// this is bad!
return error("generic virtual registers must have a size");
}
Dest = MachineOperand::CreateReg(
Reg, Flags & RegState::Define, Flags & RegState::Implicit,

View File

@ -15,6 +15,7 @@
#define LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
namespace llvm {
@ -35,6 +36,8 @@ struct PerFunctionMIParsingState {
DenseMap<unsigned, int> StackObjectSlots;
DenseMap<unsigned, unsigned> ConstantPoolSlots;
DenseMap<unsigned, unsigned> JumpTableSlots;
/// Hold the generic virtual registers.
SmallSet<unsigned, 8> GenericVRegs;
};
/// Parse the machine basic block definitions, and skip the machine

View File

@ -365,6 +365,7 @@ bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF,
// This is a generic virtual register.
// The size will be set appropriately when we reach the definition.
Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
PFS.GenericVRegs.insert(Reg);
} else {
const auto *RC = getRegClass(MF, VReg.Class.Value);
if (RC) {
@ -378,6 +379,7 @@ bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF,
VReg.Class.Value + "'");
Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
RegInfo.setRegBank(Reg, *RegBank);
PFS.GenericVRegs.insert(Reg);
}
}
if (!PFS.VirtualRegisterSlots.insert(std::make_pair(VReg.ID.Value, Reg))

View File

@ -0,0 +1,44 @@
# RUN: not llc -mtriple=aarch64-apple-ios -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2> %t.log
# Everything is written on STDERR with mir, which is bad. So make two runs for now.
# RUN: FileCheck %s -input-file=%t.log --check-prefix=CHECK
# RUN: FileCheck %s -input-file=%t.log --check-prefix=ERR
# RUN: rm -f %t.log
# REQUIRES: global-isel
# This test ensures that the MIR parser errors out when
# generic virtual register definitions are not correct.
--- |
define void @bar() { ret void }
define void @baz() { ret void }
...
---
name: bar
isSSA: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr }
registers:
- { id: 0, class: gpr }
body: |
bb.0:
liveins: %w0
; ERR: generic virtual registers must have a size
; ERR-NEXT: %0
%0 = G_ADD i32 %w0, %w0
...
---
name: baz
isSSA: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: _ }
registers:
- { id: 0, class: _ }
body: |
bb.0:
liveins: %w0
; ERR: generic virtual registers must have a size
; ERR-NEXT: %0
%0 = G_ADD i32 %w0, %w0
...