mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-15 19:24:33 +00:00
MIR Serialization: Serialize the block address machine operands.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243453 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -147,6 +147,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
|
|||||||
.Case(".cfi_offset", MIToken::kw_cfi_offset)
|
.Case(".cfi_offset", MIToken::kw_cfi_offset)
|
||||||
.Case(".cfi_def_cfa_register", MIToken::kw_cfi_def_cfa_register)
|
.Case(".cfi_def_cfa_register", MIToken::kw_cfi_def_cfa_register)
|
||||||
.Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset)
|
.Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset)
|
||||||
|
.Case("blockaddress", MIToken::kw_blockaddress)
|
||||||
.Default(MIToken::Identifier);
|
.Default(MIToken::Identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,8 +240,16 @@ static Cursor maybeLexConstantPoolItem(Cursor C, MIToken &Token) {
|
|||||||
return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem);
|
return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Cursor maybeLexIRBlock(Cursor C, MIToken &Token) {
|
static Cursor maybeLexIRBlock(
|
||||||
return maybeLexIndex(C, Token, "%ir-block.", MIToken::IRBlock);
|
Cursor C, MIToken &Token,
|
||||||
|
function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
|
||||||
|
const StringRef Rule = "%ir-block.";
|
||||||
|
if (!C.remaining().startswith(Rule))
|
||||||
|
return None;
|
||||||
|
if (isdigit(C.peek(Rule.size())))
|
||||||
|
return maybeLexIndex(C, Token, Rule, MIToken::IRBlock);
|
||||||
|
return lexName(C, Token, MIToken::NamedIRBlock, MIToken::QuotedNamedIRBlock,
|
||||||
|
Rule.size(), ErrorCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
|
static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
|
||||||
@@ -319,6 +328,10 @@ static MIToken::TokenKind symbolToken(char C) {
|
|||||||
return MIToken::colon;
|
return MIToken::colon;
|
||||||
case '!':
|
case '!':
|
||||||
return MIToken::exclaim;
|
return MIToken::exclaim;
|
||||||
|
case '(':
|
||||||
|
return MIToken::lparen;
|
||||||
|
case ')':
|
||||||
|
return MIToken::rparen;
|
||||||
default:
|
default:
|
||||||
return MIToken::Error;
|
return MIToken::Error;
|
||||||
}
|
}
|
||||||
@@ -355,7 +368,7 @@ StringRef llvm::lexMIToken(
|
|||||||
return R.remaining();
|
return R.remaining();
|
||||||
if (Cursor R = maybeLexConstantPoolItem(C, Token))
|
if (Cursor R = maybeLexConstantPoolItem(C, Token))
|
||||||
return R.remaining();
|
return R.remaining();
|
||||||
if (Cursor R = maybeLexIRBlock(C, Token))
|
if (Cursor R = maybeLexIRBlock(C, Token, ErrorCallback))
|
||||||
return R.remaining();
|
return R.remaining();
|
||||||
if (Cursor R = maybeLexRegister(C, Token))
|
if (Cursor R = maybeLexRegister(C, Token))
|
||||||
return R.remaining();
|
return R.remaining();
|
||||||
|
@@ -37,6 +37,8 @@ struct MIToken {
|
|||||||
underscore,
|
underscore,
|
||||||
colon,
|
colon,
|
||||||
exclaim,
|
exclaim,
|
||||||
|
lparen,
|
||||||
|
rparen,
|
||||||
|
|
||||||
// Keywords
|
// Keywords
|
||||||
kw_implicit,
|
kw_implicit,
|
||||||
@@ -49,6 +51,7 @@ struct MIToken {
|
|||||||
kw_cfi_offset,
|
kw_cfi_offset,
|
||||||
kw_cfi_def_cfa_register,
|
kw_cfi_def_cfa_register,
|
||||||
kw_cfi_def_cfa_offset,
|
kw_cfi_def_cfa_offset,
|
||||||
|
kw_blockaddress,
|
||||||
|
|
||||||
// Identifier tokens
|
// Identifier tokens
|
||||||
Identifier,
|
Identifier,
|
||||||
@@ -67,6 +70,8 @@ struct MIToken {
|
|||||||
VirtualRegister,
|
VirtualRegister,
|
||||||
ConstantPoolItem,
|
ConstantPoolItem,
|
||||||
JumpTableIndex,
|
JumpTableIndex,
|
||||||
|
NamedIRBlock,
|
||||||
|
QuotedNamedIRBlock,
|
||||||
IRBlock,
|
IRBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -105,7 +110,8 @@ public:
|
|||||||
StringRef::iterator location() const { return Range.begin(); }
|
StringRef::iterator location() const { return Range.begin(); }
|
||||||
|
|
||||||
bool isStringValueQuoted() const {
|
bool isStringValueQuoted() const {
|
||||||
return Kind == QuotedNamedGlobalValue || Kind == QuotedExternalSymbol;
|
return Kind == QuotedNamedGlobalValue || Kind == QuotedExternalSymbol ||
|
||||||
|
Kind == QuotedNamedIRBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the token's raw string value.
|
/// Return the token's raw string value.
|
||||||
|
@@ -22,8 +22,10 @@
|
|||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/IR/ModuleSlotTracker.h"
|
#include "llvm/IR/ModuleSlotTracker.h"
|
||||||
|
#include "llvm/IR/ValueSymbolTable.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Support/SourceMgr.h"
|
#include "llvm/Support/SourceMgr.h"
|
||||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||||
@@ -123,6 +125,8 @@ public:
|
|||||||
bool parseCFIOffset(int &Offset);
|
bool parseCFIOffset(int &Offset);
|
||||||
bool parseCFIRegister(unsigned &Reg);
|
bool parseCFIRegister(unsigned &Reg);
|
||||||
bool parseCFIOperand(MachineOperand &Dest);
|
bool parseCFIOperand(MachineOperand &Dest);
|
||||||
|
bool parseIRBlock(BasicBlock *&BB, const Function &F);
|
||||||
|
bool parseBlockAddressOperand(MachineOperand &Dest);
|
||||||
bool parseMachineOperand(MachineOperand &Dest);
|
bool parseMachineOperand(MachineOperand &Dest);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -200,6 +204,10 @@ static const char *toString(MIToken::TokenKind TokenKind) {
|
|||||||
switch (TokenKind) {
|
switch (TokenKind) {
|
||||||
case MIToken::comma:
|
case MIToken::comma:
|
||||||
return "','";
|
return "','";
|
||||||
|
case MIToken::lparen:
|
||||||
|
return "'('";
|
||||||
|
case MIToken::rparen:
|
||||||
|
return "')'";
|
||||||
default:
|
default:
|
||||||
return "<unknown token>";
|
return "<unknown token>";
|
||||||
}
|
}
|
||||||
@@ -741,6 +749,65 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) {
|
||||||
|
switch (Token.kind()) {
|
||||||
|
case MIToken::NamedIRBlock:
|
||||||
|
case MIToken::QuotedNamedIRBlock: {
|
||||||
|
StringValueUtility Name(Token);
|
||||||
|
BB = dyn_cast_or_null<BasicBlock>(F.getValueSymbolTable().lookup(Name));
|
||||||
|
if (!BB)
|
||||||
|
return error(Twine("use of undefined IR block '%ir-block.") +
|
||||||
|
Token.rawStringValue() + "'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MIToken::IRBlock: {
|
||||||
|
unsigned SlotNumber = 0;
|
||||||
|
if (getUnsigned(SlotNumber))
|
||||||
|
return true;
|
||||||
|
BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber));
|
||||||
|
if (!BB)
|
||||||
|
return error(Twine("use of undefined IR block '%ir-block.") +
|
||||||
|
Twine(SlotNumber) + "'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
llvm_unreachable("The current token should be an IR block reference");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) {
|
||||||
|
assert(Token.is(MIToken::kw_blockaddress));
|
||||||
|
lex();
|
||||||
|
if (expectAndConsume(MIToken::lparen))
|
||||||
|
return true;
|
||||||
|
if (Token.isNot(MIToken::GlobalValue) &&
|
||||||
|
Token.isNot(MIToken::NamedGlobalValue) &&
|
||||||
|
Token.isNot(MIToken::QuotedNamedGlobalValue))
|
||||||
|
return error("expected a global value");
|
||||||
|
GlobalValue *GV = nullptr;
|
||||||
|
if (parseGlobalValue(GV))
|
||||||
|
return true;
|
||||||
|
auto *F = dyn_cast<Function>(GV);
|
||||||
|
if (!F)
|
||||||
|
return error("expected an IR function reference");
|
||||||
|
lex();
|
||||||
|
if (expectAndConsume(MIToken::comma))
|
||||||
|
return true;
|
||||||
|
BasicBlock *BB = nullptr;
|
||||||
|
if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock) &&
|
||||||
|
Token.isNot(MIToken::QuotedNamedIRBlock))
|
||||||
|
return error("expected an IR block reference");
|
||||||
|
if (parseIRBlock(BB, *F))
|
||||||
|
return true;
|
||||||
|
lex();
|
||||||
|
if (expectAndConsume(MIToken::rparen))
|
||||||
|
return true;
|
||||||
|
// TODO: parse offset and target flags.
|
||||||
|
Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool MIParser::parseMachineOperand(MachineOperand &Dest) {
|
bool MIParser::parseMachineOperand(MachineOperand &Dest) {
|
||||||
switch (Token.kind()) {
|
switch (Token.kind()) {
|
||||||
case MIToken::kw_implicit:
|
case MIToken::kw_implicit:
|
||||||
@@ -777,6 +844,8 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) {
|
|||||||
case MIToken::kw_cfi_def_cfa_register:
|
case MIToken::kw_cfi_def_cfa_register:
|
||||||
case MIToken::kw_cfi_def_cfa_offset:
|
case MIToken::kw_cfi_def_cfa_offset:
|
||||||
return parseCFIOperand(Dest);
|
return parseCFIOperand(Dest);
|
||||||
|
case MIToken::kw_blockaddress:
|
||||||
|
return parseBlockAddressOperand(Dest);
|
||||||
case MIToken::Error:
|
case MIToken::Error:
|
||||||
return true;
|
return true;
|
||||||
case MIToken::Identifier:
|
case MIToken::Identifier:
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/MIRYamlMapping.h"
|
#include "llvm/CodeGen/MIRYamlMapping.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/IRPrintingPasses.h"
|
#include "llvm/IR/IRPrintingPasses.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
@@ -103,6 +104,7 @@ public:
|
|||||||
|
|
||||||
void print(const MachineInstr &MI);
|
void print(const MachineInstr &MI);
|
||||||
void printMBBReference(const MachineBasicBlock &MBB);
|
void printMBBReference(const MachineBasicBlock &MBB);
|
||||||
|
void printIRBlockReference(const BasicBlock &BB);
|
||||||
void printStackObjectReference(int FrameIndex);
|
void printStackObjectReference(int FrameIndex);
|
||||||
void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
|
void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
|
||||||
|
|
||||||
@@ -428,6 +430,19 @@ void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MIPrinter::printIRBlockReference(const BasicBlock &BB) {
|
||||||
|
OS << "%ir-block.";
|
||||||
|
if (BB.hasName()) {
|
||||||
|
printLLVMNameWithoutPrefix(OS, BB.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int Slot = MST.getLocalSlot(&BB);
|
||||||
|
if (Slot == -1)
|
||||||
|
OS << "<badref>";
|
||||||
|
else
|
||||||
|
OS << Slot;
|
||||||
|
}
|
||||||
|
|
||||||
void MIPrinter::printStackObjectReference(int FrameIndex) {
|
void MIPrinter::printStackObjectReference(int FrameIndex) {
|
||||||
auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
|
auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
|
||||||
assert(ObjectInfo != StackObjectOperandMapping.end() &&
|
assert(ObjectInfo != StackObjectOperandMapping.end() &&
|
||||||
@@ -485,6 +500,15 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
|
|||||||
Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
|
Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
|
||||||
// TODO: Print offset and target flags.
|
// TODO: Print offset and target flags.
|
||||||
break;
|
break;
|
||||||
|
case MachineOperand::MO_BlockAddress:
|
||||||
|
OS << "blockaddress(";
|
||||||
|
Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
|
||||||
|
MST);
|
||||||
|
OS << ", ";
|
||||||
|
printIRBlockReference(*Op.getBlockAddress()->getBasicBlock());
|
||||||
|
OS << ')';
|
||||||
|
// TODO: Print offset and target flags.
|
||||||
|
break;
|
||||||
case MachineOperand::MO_RegisterMask: {
|
case MachineOperand::MO_RegisterMask: {
|
||||||
auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
|
auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
|
||||||
if (RegMaskInfo != RegisterMaskIds.end())
|
if (RegMaskInfo != RegisterMaskIds.end())
|
||||||
|
89
test/CodeGen/MIR/X86/block-address-operands.mir
Normal file
89
test/CodeGen/MIR/X86/block-address-operands.mir
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
|
||||||
|
# This test ensures that the MIR parser parses the block address operands
|
||||||
|
# correctly.
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
@addr = global i8* null
|
||||||
|
|
||||||
|
define void @test() {
|
||||||
|
entry:
|
||||||
|
store volatile i8* blockaddress(@test, %block), i8** @addr
|
||||||
|
%val = load volatile i8*, i8** @addr
|
||||||
|
indirectbr i8* %val, [label %block]
|
||||||
|
|
||||||
|
block:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @test2() {
|
||||||
|
entry:
|
||||||
|
store volatile i8* blockaddress(@test2, %"quoted block"), i8** @addr
|
||||||
|
%val = load volatile i8*, i8** @addr
|
||||||
|
indirectbr i8* %val, [label %"quoted block"]
|
||||||
|
|
||||||
|
"quoted block":
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @test3() {
|
||||||
|
entry:
|
||||||
|
store volatile i8* blockaddress(@test3, %0), i8** @addr
|
||||||
|
%val = load volatile i8*, i8** @addr
|
||||||
|
indirectbr i8* %val, [label %0]
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1.block' ]
|
||||||
|
instructions:
|
||||||
|
# CHECK: %rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block.block), _
|
||||||
|
- '%rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block.block), _'
|
||||||
|
- 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
|
||||||
|
- 'JMP64m %rip, 1, _, @addr, _'
|
||||||
|
- id: 1
|
||||||
|
name: block
|
||||||
|
addressTaken: true
|
||||||
|
instructions:
|
||||||
|
- RETQ
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test2
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1' ]
|
||||||
|
instructions:
|
||||||
|
# CHECK: %rax = LEA64r %rip, 1, _, blockaddress(@test2, %ir-block."quoted block"), _
|
||||||
|
- '%rax = LEA64r %rip, 1, _, blockaddress(@test2, %ir-block."quoted block"), _'
|
||||||
|
- 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
|
||||||
|
- 'JMP64m %rip, 1, _, @addr, _'
|
||||||
|
- id: 1
|
||||||
|
addressTaken: true
|
||||||
|
instructions:
|
||||||
|
- RETQ
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test3
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1' ]
|
||||||
|
instructions:
|
||||||
|
# CHECK: %rax = LEA64r %rip, 1, _, blockaddress(@test3, %ir-block.0), _
|
||||||
|
- '%rax = LEA64r %rip, 1, _, blockaddress(@test3, %ir-block.0), _'
|
||||||
|
- 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
|
||||||
|
- 'JMP64m %rip, 1, _, @addr, _'
|
||||||
|
- id: 1
|
||||||
|
addressTaken: true
|
||||||
|
instructions:
|
||||||
|
- RETQ
|
||||||
|
...
|
@@ -0,0 +1,34 @@
|
|||||||
|
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
@addr = global i8* null
|
||||||
|
|
||||||
|
define void @test() {
|
||||||
|
entry:
|
||||||
|
store volatile i8* blockaddress(@test, %block), i8** @addr
|
||||||
|
%val = load volatile i8*, i8** @addr
|
||||||
|
indirectbr i8* %val, [label %block]
|
||||||
|
|
||||||
|
block:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1.block' ]
|
||||||
|
instructions:
|
||||||
|
# CHECK: [[@LINE+1]]:56: expected an IR block reference
|
||||||
|
- '%rax = LEA64r %rip, 1, _, blockaddress(@test, _), _'
|
||||||
|
- 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
|
||||||
|
- 'JMP64m %rip, 1, _, @addr, _'
|
||||||
|
- id: 1
|
||||||
|
name: block
|
||||||
|
addressTaken: true
|
||||||
|
instructions:
|
||||||
|
- RETQ
|
||||||
|
...
|
@@ -0,0 +1,34 @@
|
|||||||
|
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
@addr = global i8* null
|
||||||
|
|
||||||
|
define void @test() {
|
||||||
|
entry:
|
||||||
|
store volatile i8* blockaddress(@test, %block), i8** @addr
|
||||||
|
%val = load volatile i8*, i8** @addr
|
||||||
|
indirectbr i8* %val, [label %block]
|
||||||
|
|
||||||
|
block:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1.block' ]
|
||||||
|
instructions:
|
||||||
|
# CHECK: [[@LINE+1]]:49: expected an IR function reference
|
||||||
|
- '%rax = LEA64r %rip, 1, _, blockaddress(@addr, %ir-block.block), _'
|
||||||
|
- 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
|
||||||
|
- 'JMP64m %rip, 1, _, @addr, _'
|
||||||
|
- id: 1
|
||||||
|
name: block
|
||||||
|
addressTaken: true
|
||||||
|
instructions:
|
||||||
|
- RETQ
|
||||||
|
...
|
@@ -0,0 +1,34 @@
|
|||||||
|
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
@addr = global i8* null
|
||||||
|
|
||||||
|
define void @test() {
|
||||||
|
entry:
|
||||||
|
store volatile i8* blockaddress(@test, %block), i8** @addr
|
||||||
|
%val = load volatile i8*, i8** @addr
|
||||||
|
indirectbr i8* %val, [label %block]
|
||||||
|
|
||||||
|
block:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1.block' ]
|
||||||
|
instructions:
|
||||||
|
# CHECK: [[@LINE+1]]:49: expected a global value
|
||||||
|
- '%rax = LEA64r %rip, 1, _, blockaddress(0, %ir-block.block), _'
|
||||||
|
- 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
|
||||||
|
- 'JMP64m %rip, 1, _, @addr, _'
|
||||||
|
- id: 1
|
||||||
|
name: block
|
||||||
|
addressTaken: true
|
||||||
|
instructions:
|
||||||
|
- RETQ
|
||||||
|
...
|
34
test/CodeGen/MIR/X86/undefined-ir-block-in-blockaddress.mir
Normal file
34
test/CodeGen/MIR/X86/undefined-ir-block-in-blockaddress.mir
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
@addr = global i8* null
|
||||||
|
|
||||||
|
define void @test() {
|
||||||
|
entry:
|
||||||
|
store volatile i8* blockaddress(@test, %block), i8** @addr
|
||||||
|
%val = load volatile i8*, i8** @addr
|
||||||
|
indirectbr i8* %val, [label %block]
|
||||||
|
|
||||||
|
block:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1.block' ]
|
||||||
|
instructions:
|
||||||
|
# CHECK: [[@LINE+1]]:56: use of undefined IR block '%ir-block."block "'
|
||||||
|
- '%rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block."block "), _'
|
||||||
|
- 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
|
||||||
|
- 'JMP64m %rip, 1, _, @addr, _'
|
||||||
|
- id: 1
|
||||||
|
name: block
|
||||||
|
addressTaken: true
|
||||||
|
instructions:
|
||||||
|
- RETQ
|
||||||
|
...
|
@@ -0,0 +1,32 @@
|
|||||||
|
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
@addr = global i8* null
|
||||||
|
|
||||||
|
define void @test() {
|
||||||
|
entry:
|
||||||
|
store volatile i8* blockaddress(@test, %0), i8** @addr
|
||||||
|
%val = load volatile i8*, i8** @addr
|
||||||
|
indirectbr i8* %val, [label %0]
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: test
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1' ]
|
||||||
|
instructions:
|
||||||
|
# CHECK: [[@LINE+1]]:56: use of undefined IR block '%ir-block.1'
|
||||||
|
- '%rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block.1), _'
|
||||||
|
- 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
|
||||||
|
- 'JMP64m %rip, 1, _, @addr, _'
|
||||||
|
- id: 1
|
||||||
|
addressTaken: true
|
||||||
|
instructions:
|
||||||
|
- RETQ
|
||||||
|
...
|
Reference in New Issue
Block a user