diff options
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.h | 3 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/MIR/AArch64/generic-virtual-registers-error.mir | 44 |
4 files changed, 55 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 158502ce353..405e508b51e 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -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, diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.h b/llvm/lib/CodeGen/MIRParser/MIParser.h index ce39805e0c5..3557b9a6d5d 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.h +++ b/llvm/lib/CodeGen/MIRParser/MIParser.h @@ -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 diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp index 69aae373f2e..e977973b1a5 100644 --- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp @@ -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)) diff --git a/llvm/test/CodeGen/MIR/AArch64/generic-virtual-registers-error.mir b/llvm/test/CodeGen/MIR/AArch64/generic-virtual-registers-error.mir new file mode 100644 index 00000000000..16408ad88d5 --- /dev/null +++ b/llvm/test/CodeGen/MIR/AArch64/generic-virtual-registers-error.mir @@ -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 +... |