mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 13:11:39 +01:00
MIR Serialization: Serialize the frame index machine operands.
Reviewers: Duncan P. N. Exon Smith llvm-svn: 242487
This commit is contained in:
parent
9e8d1a2460
commit
b3441a0f38
@ -128,10 +128,39 @@ static Cursor maybeLexIndex(Cursor C, MIToken &Token, StringRef Rule,
|
||||
return C;
|
||||
}
|
||||
|
||||
static Cursor maybeLexIndexAndName(Cursor C, MIToken &Token, StringRef Rule,
|
||||
MIToken::TokenKind Kind) {
|
||||
if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size())))
|
||||
return None;
|
||||
auto Range = C;
|
||||
C.advance(Rule.size());
|
||||
auto NumberRange = C;
|
||||
while (isdigit(C.peek()))
|
||||
C.advance();
|
||||
StringRef Number = NumberRange.upto(C);
|
||||
unsigned StringOffset = Rule.size() + Number.size();
|
||||
if (C.peek() == '.') {
|
||||
C.advance();
|
||||
++StringOffset;
|
||||
while (isIdentifierChar(C.peek()))
|
||||
C.advance();
|
||||
}
|
||||
Token = MIToken(Kind, Range.upto(C), APSInt(Number), StringOffset);
|
||||
return C;
|
||||
}
|
||||
|
||||
static Cursor maybeLexJumpTableIndex(Cursor C, MIToken &Token) {
|
||||
return maybeLexIndex(C, Token, "%jump-table.", MIToken::JumpTableIndex);
|
||||
}
|
||||
|
||||
static Cursor maybeLexStackObject(Cursor C, MIToken &Token) {
|
||||
return maybeLexIndexAndName(C, Token, "%stack.", MIToken::StackObject);
|
||||
}
|
||||
|
||||
static Cursor maybeLexFixedStackObject(Cursor C, MIToken &Token) {
|
||||
return maybeLexIndex(C, Token, "%fixed-stack.", MIToken::FixedStackObject);
|
||||
}
|
||||
|
||||
static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
|
||||
auto Range = C;
|
||||
C.advance(); // Skip '%'
|
||||
@ -228,6 +257,10 @@ StringRef llvm::lexMIToken(
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexJumpTableIndex(C, Token))
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexStackObject(C, Token))
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexFixedStackObject(C, Token))
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexRegister(C, Token))
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexGlobalValue(C, Token))
|
||||
|
@ -48,6 +48,8 @@ struct MIToken {
|
||||
Identifier,
|
||||
NamedRegister,
|
||||
MachineBasicBlock,
|
||||
StackObject,
|
||||
FixedStackObject,
|
||||
NamedGlobalValue,
|
||||
GlobalValue,
|
||||
|
||||
@ -97,6 +99,7 @@ public:
|
||||
|
||||
bool hasIntegerValue() const {
|
||||
return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
|
||||
Kind == StackObject || Kind == FixedStackObject ||
|
||||
Kind == GlobalValue || Kind == VirtualRegister ||
|
||||
Kind == JumpTableIndex;
|
||||
}
|
||||
|
@ -17,8 +17,10 @@
|
||||
#include "llvm/AsmParser/SlotMapping.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
@ -87,6 +89,8 @@ public:
|
||||
bool parseImmediateOperand(MachineOperand &Dest);
|
||||
bool parseMBBReference(MachineBasicBlock *&MBB);
|
||||
bool parseMBBOperand(MachineOperand &Dest);
|
||||
bool parseStackObjectOperand(MachineOperand &Dest);
|
||||
bool parseFixedStackObjectOperand(MachineOperand &Dest);
|
||||
bool parseGlobalAddressOperand(MachineOperand &Dest);
|
||||
bool parseJumpTableIndexOperand(MachineOperand &Dest);
|
||||
bool parseMachineOperand(MachineOperand &Dest);
|
||||
@ -439,6 +443,41 @@ bool MIParser::parseMBBOperand(MachineOperand &Dest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseStackObjectOperand(MachineOperand &Dest) {
|
||||
assert(Token.is(MIToken::StackObject));
|
||||
unsigned ID;
|
||||
if (getUnsigned(ID))
|
||||
return true;
|
||||
auto ObjectInfo = PFS.StackObjectSlots.find(ID);
|
||||
if (ObjectInfo == PFS.StackObjectSlots.end())
|
||||
return error(Twine("use of undefined stack object '%stack.") + Twine(ID) +
|
||||
"'");
|
||||
StringRef Name;
|
||||
if (const auto *Alloca =
|
||||
MF.getFrameInfo()->getObjectAllocation(ObjectInfo->second))
|
||||
Name = Alloca->getName();
|
||||
if (!Token.stringValue().empty() && Token.stringValue() != Name)
|
||||
return error(Twine("the name of the stack object '%stack.") + Twine(ID) +
|
||||
"' isn't '" + Token.stringValue() + "'");
|
||||
lex();
|
||||
Dest = MachineOperand::CreateFI(ObjectInfo->second);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) {
|
||||
assert(Token.is(MIToken::FixedStackObject));
|
||||
unsigned ID;
|
||||
if (getUnsigned(ID))
|
||||
return true;
|
||||
auto ObjectInfo = PFS.FixedStackObjectSlots.find(ID);
|
||||
if (ObjectInfo == PFS.FixedStackObjectSlots.end())
|
||||
return error(Twine("use of undefined fixed stack object '%fixed-stack.") +
|
||||
Twine(ID) + "'");
|
||||
lex();
|
||||
Dest = MachineOperand::CreateFI(ObjectInfo->second);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
|
||||
switch (Token.kind()) {
|
||||
case MIToken::NamedGlobalValue: {
|
||||
@ -498,6 +537,10 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) {
|
||||
return parseImmediateOperand(Dest);
|
||||
case MIToken::MachineBasicBlock:
|
||||
return parseMBBOperand(Dest);
|
||||
case MIToken::StackObject:
|
||||
return parseStackObjectOperand(Dest);
|
||||
case MIToken::FixedStackObject:
|
||||
return parseFixedStackObjectOperand(Dest);
|
||||
case MIToken::GlobalValue:
|
||||
case MIToken::NamedGlobalValue:
|
||||
return parseGlobalAddressOperand(Dest);
|
||||
|
@ -29,6 +29,8 @@ class SourceMgr;
|
||||
struct PerFunctionMIParsingState {
|
||||
DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
|
||||
DenseMap<unsigned, unsigned> VirtualRegisterSlots;
|
||||
DenseMap<unsigned, int> FixedStackObjectSlots;
|
||||
DenseMap<unsigned, int> StackObjectSlots;
|
||||
DenseMap<unsigned, unsigned> JumpTableSlots;
|
||||
};
|
||||
|
||||
|
@ -109,7 +109,9 @@ public:
|
||||
DenseMap<unsigned, unsigned> &VirtualRegisterSlots);
|
||||
|
||||
bool initializeFrameInfo(const Function &F, MachineFrameInfo &MFI,
|
||||
const yaml::MachineFunction &YamlMF);
|
||||
const yaml::MachineFunction &YamlMF,
|
||||
DenseMap<unsigned, int> &StackObjectSlots,
|
||||
DenseMap<unsigned, int> &FixedStackObjectSlots);
|
||||
|
||||
bool initializeJumpTableInfo(MachineFunction &MF,
|
||||
const yaml::MachineJumpTable &YamlJTI,
|
||||
@ -268,7 +270,8 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
|
||||
if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF,
|
||||
PFS.VirtualRegisterSlots))
|
||||
return true;
|
||||
if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF))
|
||||
if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF,
|
||||
PFS.StackObjectSlots, PFS.FixedStackObjectSlots))
|
||||
return true;
|
||||
|
||||
const auto &F = *MF.getFunction();
|
||||
@ -375,9 +378,11 @@ bool MIRParserImpl::initializeRegisterInfo(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIRParserImpl::initializeFrameInfo(const Function &F,
|
||||
MachineFrameInfo &MFI,
|
||||
const yaml::MachineFunction &YamlMF) {
|
||||
bool MIRParserImpl::initializeFrameInfo(
|
||||
const Function &F, MachineFrameInfo &MFI,
|
||||
const yaml::MachineFunction &YamlMF,
|
||||
DenseMap<unsigned, int> &StackObjectSlots,
|
||||
DenseMap<unsigned, int> &FixedStackObjectSlots) {
|
||||
const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
|
||||
MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
|
||||
MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
|
||||
@ -403,8 +408,8 @@ bool MIRParserImpl::initializeFrameInfo(const Function &F,
|
||||
else
|
||||
ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
|
||||
MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
|
||||
// TODO: Store the mapping between fixed object IDs and object indices to
|
||||
// parse fixed stack object references correctly.
|
||||
// TODO: Report an error when objects are redefined.
|
||||
FixedStackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
|
||||
}
|
||||
|
||||
// Initialize the ordinary frame objects.
|
||||
@ -428,8 +433,8 @@ bool MIRParserImpl::initializeFrameInfo(const Function &F,
|
||||
Object.Size, Object.Alignment,
|
||||
Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
|
||||
MFI.setObjectOffset(ObjectIdx, Object.Offset);
|
||||
// TODO: Store the mapping between object IDs and object indices to parse
|
||||
// stack object references correctly.
|
||||
// TODO: Report an error when objects are redefined.
|
||||
StackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -32,11 +32,34 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
/// This structure describes how to print out stack object references.
|
||||
struct FrameIndexOperand {
|
||||
std::string Name;
|
||||
unsigned ID;
|
||||
bool IsFixed;
|
||||
|
||||
FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
|
||||
: Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
|
||||
|
||||
/// Return an ordinary stack object reference.
|
||||
static FrameIndexOperand create(StringRef Name, unsigned ID) {
|
||||
return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
|
||||
}
|
||||
|
||||
/// Return a fixed stack object reference.
|
||||
static FrameIndexOperand createFixed(unsigned ID) {
|
||||
return FrameIndexOperand("", ID, /*IsFixed=*/true);
|
||||
}
|
||||
};
|
||||
|
||||
/// This class prints out the machine functions using the MIR serialization
|
||||
/// format.
|
||||
class MIRPrinter {
|
||||
raw_ostream &OS;
|
||||
DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
|
||||
/// Maps from stack object indices to operand indices which will be used when
|
||||
/// printing frame index machine operands.
|
||||
DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
|
||||
|
||||
public:
|
||||
MIRPrinter(raw_ostream &OS) : OS(OS) {}
|
||||
@ -63,14 +86,18 @@ class MIPrinter {
|
||||
raw_ostream &OS;
|
||||
ModuleSlotTracker &MST;
|
||||
const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
|
||||
const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
|
||||
|
||||
public:
|
||||
MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
|
||||
const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds)
|
||||
: OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds) {}
|
||||
const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
|
||||
const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
|
||||
: OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
|
||||
StackObjectOperandMapping(StackObjectOperandMapping) {}
|
||||
|
||||
void print(const MachineInstr &MI);
|
||||
void printMBBReference(const MachineBasicBlock &MBB);
|
||||
void printStackObjectReference(int FrameIndex);
|
||||
void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
|
||||
};
|
||||
|
||||
@ -182,7 +209,7 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
|
||||
continue;
|
||||
|
||||
yaml::FixedMachineStackObject YamlObject;
|
||||
YamlObject.ID = ID++;
|
||||
YamlObject.ID = ID;
|
||||
YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
|
||||
? yaml::FixedMachineStackObject::SpillSlot
|
||||
: yaml::FixedMachineStackObject::DefaultType;
|
||||
@ -192,8 +219,8 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
|
||||
YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
|
||||
YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
|
||||
MF.FixedStackObjects.push_back(YamlObject);
|
||||
// TODO: Store the mapping between fixed object IDs and object indices to
|
||||
// print the fixed stack object references correctly.
|
||||
StackObjectOperandMapping.insert(
|
||||
std::make_pair(I, FrameIndexOperand::createFixed(ID++)));
|
||||
}
|
||||
|
||||
// Process ordinary stack objects.
|
||||
@ -203,7 +230,7 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
|
||||
continue;
|
||||
|
||||
yaml::MachineStackObject YamlObject;
|
||||
YamlObject.ID = ID++;
|
||||
YamlObject.ID = ID;
|
||||
if (const auto *Alloca = MFI.getObjectAllocation(I))
|
||||
YamlObject.Name.Value =
|
||||
Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>";
|
||||
@ -217,8 +244,8 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
|
||||
YamlObject.Alignment = MFI.getObjectAlignment(I);
|
||||
|
||||
MF.StackObjects.push_back(YamlObject);
|
||||
// TODO: Store the mapping between object IDs and object indices to print
|
||||
// the stack object references correctly.
|
||||
StackObjectOperandMapping.insert(std::make_pair(
|
||||
I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +260,8 @@ void MIRPrinter::convert(ModuleSlotTracker &MST,
|
||||
Entry.ID = ID++;
|
||||
for (const auto *MBB : Table.MBBs) {
|
||||
raw_string_ostream StrOS(Str);
|
||||
MIPrinter(StrOS, MST, RegisterMaskIds).printMBBReference(*MBB);
|
||||
MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
|
||||
.printMBBReference(*MBB);
|
||||
Entry.Blocks.push_back(StrOS.str());
|
||||
Str.clear();
|
||||
}
|
||||
@ -257,7 +285,8 @@ void MIRPrinter::convert(ModuleSlotTracker &MST,
|
||||
for (const auto *SuccMBB : MBB.successors()) {
|
||||
std::string Str;
|
||||
raw_string_ostream StrOS(Str);
|
||||
MIPrinter(StrOS, MST, RegisterMaskIds).printMBBReference(*SuccMBB);
|
||||
MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
|
||||
.printMBBReference(*SuccMBB);
|
||||
YamlMBB.Successors.push_back(StrOS.str());
|
||||
}
|
||||
// Print the live in registers.
|
||||
@ -274,7 +303,7 @@ void MIRPrinter::convert(ModuleSlotTracker &MST,
|
||||
std::string Str;
|
||||
for (const auto &MI : MBB) {
|
||||
raw_string_ostream StrOS(Str);
|
||||
MIPrinter(StrOS, MST, RegisterMaskIds).print(MI);
|
||||
MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI);
|
||||
YamlMBB.Instructions.push_back(StrOS.str());
|
||||
Str.clear();
|
||||
}
|
||||
@ -327,6 +356,20 @@ void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
|
||||
}
|
||||
}
|
||||
|
||||
void MIPrinter::printStackObjectReference(int FrameIndex) {
|
||||
auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
|
||||
assert(ObjectInfo != StackObjectOperandMapping.end() &&
|
||||
"Invalid frame index");
|
||||
const FrameIndexOperand &Operand = ObjectInfo->second;
|
||||
if (Operand.IsFixed) {
|
||||
OS << "%fixed-stack." << Operand.ID;
|
||||
return;
|
||||
}
|
||||
OS << "%stack." << Operand.ID;
|
||||
if (!Operand.Name.empty())
|
||||
OS << '.' << Operand.Name;
|
||||
}
|
||||
|
||||
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
|
||||
switch (Op.getType()) {
|
||||
case MachineOperand::MO_Register:
|
||||
@ -350,6 +393,9 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
printMBBReference(*Op.getMBB());
|
||||
break;
|
||||
case MachineOperand::MO_FrameIndex:
|
||||
printStackObjectReference(Op.getIndex());
|
||||
break;
|
||||
case MachineOperand::MO_JumpTableIndex:
|
||||
OS << "%jump-table." << Op.getIndex();
|
||||
// TODO: Print target flags.
|
||||
|
@ -0,0 +1,35 @@
|
||||
# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s
|
||||
# This test ensures that an error is reported when an stack object reference
|
||||
# uses a different name then the stack object definition.
|
||||
|
||||
--- |
|
||||
|
||||
define i32 @test(i32 %a) {
|
||||
entry:
|
||||
%b = alloca i32
|
||||
store i32 %a, i32* %b
|
||||
%c = load i32, i32* %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test
|
||||
isSSA: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gr32 }
|
||||
frameInfo:
|
||||
maxAlignment: 4
|
||||
stack:
|
||||
- { id: 0, name: b, size: 4, alignment: 4 }
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
- '%0 = COPY %edi'
|
||||
# CHECK: [[@LINE+1]]:18: the name of the stack object '%stack.0' isn't 'x'
|
||||
- 'MOV32mr %stack.0.x, 1, _, 0, _, %0'
|
||||
- '%eax = COPY %0'
|
||||
- 'RETQ %eax'
|
||||
...
|
48
test/CodeGen/MIR/X86/stack-object-operands.mir
Normal file
48
test/CodeGen/MIR/X86/stack-object-operands.mir
Normal file
@ -0,0 +1,48 @@
|
||||
# RUN: llc -march=x86 -start-after machine-sink -stop-after machine-sink -o /dev/null %s | FileCheck %s
|
||||
# This test ensures that the MIR parser parses stack object machine operands
|
||||
# correctly.
|
||||
|
||||
--- |
|
||||
|
||||
define i32 @test(i32 %a) {
|
||||
entry:
|
||||
%b = alloca i32
|
||||
%0 = alloca i32
|
||||
store i32 %a, i32* %b
|
||||
store i32 2, i32* %0
|
||||
%c = load i32, i32* %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test
|
||||
isSSA: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gr32 }
|
||||
- { id: 1, class: gr32 }
|
||||
frameInfo:
|
||||
maxAlignment: 4
|
||||
fixedStack:
|
||||
- { id: 0, offset: 0, size: 4, isImmutable: true, isAliased: false }
|
||||
stack:
|
||||
- { id: 0, name: b, size: 4, alignment: 4 }
|
||||
- { id: 1, size: 4, alignment: 4 }
|
||||
body:
|
||||
# CHECK: name: entry
|
||||
# CHECK: instructions:
|
||||
# CHECK-NEXT: - '%0 = MOV32rm %fixed-stack.0, 1, _, 0, _'
|
||||
# CHECK-NEXT: - 'MOV32mr %stack.0.b, 1, _, 0, _, %0'
|
||||
# CHECK-NEXT: - 'MOV32mi %stack.1, 1, _, 0, _, 2'
|
||||
# CHECK-NEXT: - '%1 = MOV32rm %stack.0.b, 1, _, 0, _'
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
- '%0 = MOV32rm %fixed-stack.0, 1, _, 0, _'
|
||||
- 'MOV32mr %stack.0.b, 1, _, 0, _, %0'
|
||||
- 'MOV32mi %stack.1, 1, _, 0, _, 2'
|
||||
- '%1 = MOV32rm %stack.0, 1, _, 0, _'
|
||||
- '%eax = COPY %1'
|
||||
- 'RETL %eax'
|
||||
...
|
40
test/CodeGen/MIR/X86/undefined-fixed-stack-object.mir
Normal file
40
test/CodeGen/MIR/X86/undefined-fixed-stack-object.mir
Normal file
@ -0,0 +1,40 @@
|
||||
# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s
|
||||
--- |
|
||||
|
||||
define i32 @test(i32 %a) {
|
||||
entry:
|
||||
%b = alloca i32
|
||||
%0 = alloca i32
|
||||
store i32 %a, i32* %b
|
||||
store i32 2, i32* %0
|
||||
%c = load i32, i32* %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test
|
||||
isSSA: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gr32 }
|
||||
- { id: 1, class: gr32 }
|
||||
frameInfo:
|
||||
maxAlignment: 4
|
||||
fixedStack:
|
||||
- { id: 0, offset: 0, size: 4, isImmutable: true, isAliased: false }
|
||||
stack:
|
||||
- { id: 0, name: b, size: 4, alignment: 4 }
|
||||
- { id: 1, size: 4, alignment: 4 }
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
# CHECK: [[@LINE+1]]:23: use of undefined fixed stack object '%fixed-stack.11'
|
||||
- '%0 = MOV32rm %fixed-stack.11, 1, _, 0, _'
|
||||
- 'MOV32mr %stack.0, 1, _, 0, _, %0'
|
||||
- 'MOV32mi %stack.1, 1, _, 0, _, 2'
|
||||
- '%1 = MOV32rm %stack.0, 1, _, 0, _'
|
||||
- '%eax = COPY %1'
|
||||
- 'RETL %eax'
|
||||
...
|
32
test/CodeGen/MIR/X86/undefined-stack-object.mir
Normal file
32
test/CodeGen/MIR/X86/undefined-stack-object.mir
Normal file
@ -0,0 +1,32 @@
|
||||
# RUN: not llc -march=x86-64 -start-after machine-sink -stop-after machine-sink -o /dev/null %s 2>&1 | FileCheck %s
|
||||
--- |
|
||||
|
||||
define i32 @test(i32 %a) {
|
||||
entry:
|
||||
%b = alloca i32
|
||||
store i32 %a, i32* %b
|
||||
%c = load i32, i32* %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
name: test
|
||||
isSSA: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: gr32 }
|
||||
frameInfo:
|
||||
maxAlignment: 4
|
||||
stack:
|
||||
- { id: 0, name: b, size: 4, alignment: 4 }
|
||||
body:
|
||||
- id: 0
|
||||
name: entry
|
||||
instructions:
|
||||
- '%0 = COPY %edi'
|
||||
# CHECK: [[@LINE+1]]:18: use of undefined stack object '%stack.2'
|
||||
- 'MOV32mr %stack.2, 1, _, 0, _, %0'
|
||||
- '%eax = COPY %0'
|
||||
- 'RETQ %eax'
|
||||
...
|
Loading…
x
Reference in New Issue
Block a user