1
0
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:
Alex Lorenz 2015-07-16 23:37:45 +00:00
parent 9e8d1a2460
commit b3441a0f38
10 changed files with 307 additions and 20 deletions

View File

@ -128,10 +128,39 @@ static Cursor maybeLexIndex(Cursor C, MIToken &Token, StringRef Rule,
return C; 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) { static Cursor maybeLexJumpTableIndex(Cursor C, MIToken &Token) {
return maybeLexIndex(C, Token, "%jump-table.", MIToken::JumpTableIndex); 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) { static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
auto Range = C; auto Range = C;
C.advance(); // Skip '%' C.advance(); // Skip '%'
@ -228,6 +257,10 @@ StringRef llvm::lexMIToken(
return R.remaining(); return R.remaining();
if (Cursor R = maybeLexJumpTableIndex(C, Token)) if (Cursor R = maybeLexJumpTableIndex(C, Token))
return R.remaining(); 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)) if (Cursor R = maybeLexRegister(C, Token))
return R.remaining(); return R.remaining();
if (Cursor R = maybeLexGlobalValue(C, Token)) if (Cursor R = maybeLexGlobalValue(C, Token))

View File

@ -48,6 +48,8 @@ struct MIToken {
Identifier, Identifier,
NamedRegister, NamedRegister,
MachineBasicBlock, MachineBasicBlock,
StackObject,
FixedStackObject,
NamedGlobalValue, NamedGlobalValue,
GlobalValue, GlobalValue,
@ -97,6 +99,7 @@ public:
bool hasIntegerValue() const { bool hasIntegerValue() const {
return Kind == IntegerLiteral || Kind == MachineBasicBlock || return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
Kind == StackObject || Kind == FixedStackObject ||
Kind == GlobalValue || Kind == VirtualRegister || Kind == GlobalValue || Kind == VirtualRegister ||
Kind == JumpTableIndex; Kind == JumpTableIndex;
} }

View File

@ -17,8 +17,10 @@
#include "llvm/AsmParser/SlotMapping.h" #include "llvm/AsmParser/SlotMapping.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SourceMgr.h"
@ -87,6 +89,8 @@ public:
bool parseImmediateOperand(MachineOperand &Dest); bool parseImmediateOperand(MachineOperand &Dest);
bool parseMBBReference(MachineBasicBlock *&MBB); bool parseMBBReference(MachineBasicBlock *&MBB);
bool parseMBBOperand(MachineOperand &Dest); bool parseMBBOperand(MachineOperand &Dest);
bool parseStackObjectOperand(MachineOperand &Dest);
bool parseFixedStackObjectOperand(MachineOperand &Dest);
bool parseGlobalAddressOperand(MachineOperand &Dest); bool parseGlobalAddressOperand(MachineOperand &Dest);
bool parseJumpTableIndexOperand(MachineOperand &Dest); bool parseJumpTableIndexOperand(MachineOperand &Dest);
bool parseMachineOperand(MachineOperand &Dest); bool parseMachineOperand(MachineOperand &Dest);
@ -439,6 +443,41 @@ bool MIParser::parseMBBOperand(MachineOperand &Dest) {
return false; 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) { bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
switch (Token.kind()) { switch (Token.kind()) {
case MIToken::NamedGlobalValue: { case MIToken::NamedGlobalValue: {
@ -498,6 +537,10 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) {
return parseImmediateOperand(Dest); return parseImmediateOperand(Dest);
case MIToken::MachineBasicBlock: case MIToken::MachineBasicBlock:
return parseMBBOperand(Dest); return parseMBBOperand(Dest);
case MIToken::StackObject:
return parseStackObjectOperand(Dest);
case MIToken::FixedStackObject:
return parseFixedStackObjectOperand(Dest);
case MIToken::GlobalValue: case MIToken::GlobalValue:
case MIToken::NamedGlobalValue: case MIToken::NamedGlobalValue:
return parseGlobalAddressOperand(Dest); return parseGlobalAddressOperand(Dest);

View File

@ -29,6 +29,8 @@ class SourceMgr;
struct PerFunctionMIParsingState { struct PerFunctionMIParsingState {
DenseMap<unsigned, MachineBasicBlock *> MBBSlots; DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
DenseMap<unsigned, unsigned> VirtualRegisterSlots; DenseMap<unsigned, unsigned> VirtualRegisterSlots;
DenseMap<unsigned, int> FixedStackObjectSlots;
DenseMap<unsigned, int> StackObjectSlots;
DenseMap<unsigned, unsigned> JumpTableSlots; DenseMap<unsigned, unsigned> JumpTableSlots;
}; };

View File

@ -109,7 +109,9 @@ public:
DenseMap<unsigned, unsigned> &VirtualRegisterSlots); DenseMap<unsigned, unsigned> &VirtualRegisterSlots);
bool initializeFrameInfo(const Function &F, MachineFrameInfo &MFI, 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, bool initializeJumpTableInfo(MachineFunction &MF,
const yaml::MachineJumpTable &YamlJTI, const yaml::MachineJumpTable &YamlJTI,
@ -268,7 +270,8 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF, if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF,
PFS.VirtualRegisterSlots)) PFS.VirtualRegisterSlots))
return true; return true;
if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF)) if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF,
PFS.StackObjectSlots, PFS.FixedStackObjectSlots))
return true; return true;
const auto &F = *MF.getFunction(); const auto &F = *MF.getFunction();
@ -375,9 +378,11 @@ bool MIRParserImpl::initializeRegisterInfo(
return false; return false;
} }
bool MIRParserImpl::initializeFrameInfo(const Function &F, bool MIRParserImpl::initializeFrameInfo(
MachineFrameInfo &MFI, const Function &F, MachineFrameInfo &MFI,
const yaml::MachineFunction &YamlMF) { const yaml::MachineFunction &YamlMF,
DenseMap<unsigned, int> &StackObjectSlots,
DenseMap<unsigned, int> &FixedStackObjectSlots) {
const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo; const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken); MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken); MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
@ -403,8 +408,8 @@ bool MIRParserImpl::initializeFrameInfo(const Function &F,
else else
ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset); ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
MFI.setObjectAlignment(ObjectIdx, Object.Alignment); MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
// TODO: Store the mapping between fixed object IDs and object indices to // TODO: Report an error when objects are redefined.
// parse fixed stack object references correctly. FixedStackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
} }
// Initialize the ordinary frame objects. // Initialize the ordinary frame objects.
@ -428,8 +433,8 @@ bool MIRParserImpl::initializeFrameInfo(const Function &F,
Object.Size, Object.Alignment, Object.Size, Object.Alignment,
Object.Type == yaml::MachineStackObject::SpillSlot, Alloca); Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
MFI.setObjectOffset(ObjectIdx, Object.Offset); MFI.setObjectOffset(ObjectIdx, Object.Offset);
// TODO: Store the mapping between object IDs and object indices to parse // TODO: Report an error when objects are redefined.
// stack object references correctly. StackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
} }
return false; return false;
} }

View File

@ -32,11 +32,34 @@ using namespace llvm;
namespace { 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 /// This class prints out the machine functions using the MIR serialization
/// format. /// format.
class MIRPrinter { class MIRPrinter {
raw_ostream &OS; raw_ostream &OS;
DenseMap<const uint32_t *, unsigned> RegisterMaskIds; 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: public:
MIRPrinter(raw_ostream &OS) : OS(OS) {} MIRPrinter(raw_ostream &OS) : OS(OS) {}
@ -63,14 +86,18 @@ class MIPrinter {
raw_ostream &OS; raw_ostream &OS;
ModuleSlotTracker &MST; ModuleSlotTracker &MST;
const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds; const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
public: public:
MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST, MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds) const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
: OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds) {} const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
: OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
StackObjectOperandMapping(StackObjectOperandMapping) {}
void print(const MachineInstr &MI); void print(const MachineInstr &MI);
void printMBBReference(const MachineBasicBlock &MBB); void printMBBReference(const MachineBasicBlock &MBB);
void printStackObjectReference(int FrameIndex);
void print(const MachineOperand &Op, const TargetRegisterInfo *TRI); void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
}; };
@ -182,7 +209,7 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
continue; continue;
yaml::FixedMachineStackObject YamlObject; yaml::FixedMachineStackObject YamlObject;
YamlObject.ID = ID++; YamlObject.ID = ID;
YamlObject.Type = MFI.isSpillSlotObjectIndex(I) YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
? yaml::FixedMachineStackObject::SpillSlot ? yaml::FixedMachineStackObject::SpillSlot
: yaml::FixedMachineStackObject::DefaultType; : yaml::FixedMachineStackObject::DefaultType;
@ -192,8 +219,8 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
MF.FixedStackObjects.push_back(YamlObject); MF.FixedStackObjects.push_back(YamlObject);
// TODO: Store the mapping between fixed object IDs and object indices to StackObjectOperandMapping.insert(
// print the fixed stack object references correctly. std::make_pair(I, FrameIndexOperand::createFixed(ID++)));
} }
// Process ordinary stack objects. // Process ordinary stack objects.
@ -203,7 +230,7 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
continue; continue;
yaml::MachineStackObject YamlObject; yaml::MachineStackObject YamlObject;
YamlObject.ID = ID++; YamlObject.ID = ID;
if (const auto *Alloca = MFI.getObjectAllocation(I)) if (const auto *Alloca = MFI.getObjectAllocation(I))
YamlObject.Name.Value = YamlObject.Name.Value =
Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>";
@ -217,8 +244,8 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
YamlObject.Alignment = MFI.getObjectAlignment(I); YamlObject.Alignment = MFI.getObjectAlignment(I);
MF.StackObjects.push_back(YamlObject); MF.StackObjects.push_back(YamlObject);
// TODO: Store the mapping between object IDs and object indices to print StackObjectOperandMapping.insert(std::make_pair(
// the stack object references correctly. I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
} }
} }
@ -233,7 +260,8 @@ void MIRPrinter::convert(ModuleSlotTracker &MST,
Entry.ID = ID++; Entry.ID = ID++;
for (const auto *MBB : Table.MBBs) { for (const auto *MBB : Table.MBBs) {
raw_string_ostream StrOS(Str); raw_string_ostream StrOS(Str);
MIPrinter(StrOS, MST, RegisterMaskIds).printMBBReference(*MBB); MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
.printMBBReference(*MBB);
Entry.Blocks.push_back(StrOS.str()); Entry.Blocks.push_back(StrOS.str());
Str.clear(); Str.clear();
} }
@ -257,7 +285,8 @@ void MIRPrinter::convert(ModuleSlotTracker &MST,
for (const auto *SuccMBB : MBB.successors()) { for (const auto *SuccMBB : MBB.successors()) {
std::string Str; std::string Str;
raw_string_ostream StrOS(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()); YamlMBB.Successors.push_back(StrOS.str());
} }
// Print the live in registers. // Print the live in registers.
@ -274,7 +303,7 @@ void MIRPrinter::convert(ModuleSlotTracker &MST,
std::string Str; std::string Str;
for (const auto &MI : MBB) { for (const auto &MI : MBB) {
raw_string_ostream StrOS(Str); raw_string_ostream StrOS(Str);
MIPrinter(StrOS, MST, RegisterMaskIds).print(MI); MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI);
YamlMBB.Instructions.push_back(StrOS.str()); YamlMBB.Instructions.push_back(StrOS.str());
Str.clear(); 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) { void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
switch (Op.getType()) { switch (Op.getType()) {
case MachineOperand::MO_Register: case MachineOperand::MO_Register:
@ -350,6 +393,9 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
case MachineOperand::MO_MachineBasicBlock: case MachineOperand::MO_MachineBasicBlock:
printMBBReference(*Op.getMBB()); printMBBReference(*Op.getMBB());
break; break;
case MachineOperand::MO_FrameIndex:
printStackObjectReference(Op.getIndex());
break;
case MachineOperand::MO_JumpTableIndex: case MachineOperand::MO_JumpTableIndex:
OS << "%jump-table." << Op.getIndex(); OS << "%jump-table." << Op.getIndex();
// TODO: Print target flags. // TODO: Print target flags.

View File

@ -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'
...

View 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'
...

View 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'
...

View 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'
...