forked from OSchip/llvm-project
Untangle the mess which is MachineBasicBlock::hasAddressTaken().
There are two different senses in which a block can be "address-taken". There can be a BlockAddress involved, which means we need to map the IR-level value to some specific block of machine code. Or there can be constructs inside a function which involve using the address of a basic block to implement certain kinds of control flow. Mixing these together causes a problem: if target-specific passes are marking random blocks "address-taken", if we have a BlockAddress, we can't actually tell which MachineBasicBlock corresponds to the BlockAddress. So split this into two separate bits: one for BlockAddress, and one for the machine-specific bits. Discovered while trying to sort out related stuff on D102817. Differential Revision: https://reviews.llvm.org/D124697
This commit is contained in:
parent
d9198f64d9
commit
cfd2c5ce58
|
@ -143,9 +143,13 @@ private:
|
|||
/// Indicate that this basic block is entered via an exception handler.
|
||||
bool IsEHPad = false;
|
||||
|
||||
/// Indicate that this basic block is potentially the target of an indirect
|
||||
/// branch.
|
||||
bool AddressTaken = false;
|
||||
/// Indicate that this MachineBasicBlock is referenced somewhere other than
|
||||
/// as predecessor/successor, a terminator MachineInstr, or a jump table.
|
||||
bool MachineBlockAddressTaken = false;
|
||||
|
||||
/// If this MachineBasicBlock corresponds to an IR-level "blockaddress"
|
||||
/// constant, this contains a pointer to that block.
|
||||
BasicBlock *AddressTakenIRBlock = nullptr;
|
||||
|
||||
/// Indicate that this basic block needs its symbol be emitted regardless of
|
||||
/// whether the flow just falls-through to it.
|
||||
|
@ -216,12 +220,35 @@ public:
|
|||
/// Return a formatted string to identify this block and its parent function.
|
||||
std::string getFullName() const;
|
||||
|
||||
/// Test whether this block is potentially the target of an indirect branch.
|
||||
bool hasAddressTaken() const { return AddressTaken; }
|
||||
/// Test whether this block is used as as something other than the target
|
||||
/// of a terminator, exception-handling target, or jump table. This is
|
||||
/// either the result of an IR-level "blockaddress", or some form
|
||||
/// of target-specific branch lowering.
|
||||
bool hasAddressTaken() const {
|
||||
return MachineBlockAddressTaken || AddressTakenIRBlock;
|
||||
}
|
||||
|
||||
/// Set this block to reflect that it potentially is the target of an indirect
|
||||
/// branch.
|
||||
void setHasAddressTaken() { AddressTaken = true; }
|
||||
/// Test whether this block is used as something other than the target of a
|
||||
/// terminator, exception-handling target, jump table, or IR blockaddress.
|
||||
/// For example, its address might be loaded into a register, or
|
||||
/// stored in some branch table that isn't part of MachineJumpTableInfo.
|
||||
bool isMachineBlockAddressTaken() const { return MachineBlockAddressTaken; }
|
||||
|
||||
/// Test whether this block is the target of an IR BlockAddress. (There can
|
||||
/// more than one MBB associated with an IR BB where the address is taken.)
|
||||
bool isIRBlockAddressTaken() const { return AddressTakenIRBlock; }
|
||||
|
||||
/// Retrieves the BasicBlock which corresponds to this MachineBasicBlock.
|
||||
BasicBlock *getAddressTakenIRBlock() const { return AddressTakenIRBlock; }
|
||||
|
||||
/// Set this block to indicate that its address is used as something other
|
||||
/// than the target of a terminator, exception-handling target, jump table,
|
||||
/// or IR-level "blockaddress".
|
||||
void setMachineBlockAddressTaken() { MachineBlockAddressTaken = true; }
|
||||
|
||||
/// Set this block to reflect that it corresponds to an IR-level basic block
|
||||
/// with a BlockAddress.
|
||||
void setAddressTakenIRBlock(BasicBlock *BB) { AddressTakenIRBlock = BB; }
|
||||
|
||||
/// Test whether this block must have its label emitted.
|
||||
bool hasLabelMustBeEmitted() const { return LabelMustBeEmitted; }
|
||||
|
|
|
@ -3545,21 +3545,21 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
|
|||
// reference the block. It is possible that there is more than one label
|
||||
// here, because multiple LLVM BB's may have been RAUW'd to this block after
|
||||
// the references were generated.
|
||||
const BasicBlock *BB = MBB.getBasicBlock();
|
||||
if (MBB.hasAddressTaken()) {
|
||||
if (MBB.isIRBlockAddressTaken()) {
|
||||
if (isVerbose())
|
||||
OutStreamer->AddComment("Block address taken");
|
||||
|
||||
// MBBs can have their address taken as part of CodeGen without having
|
||||
// their corresponding BB's address taken in IR
|
||||
if (BB && BB->hasAddressTaken())
|
||||
for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB))
|
||||
OutStreamer->emitLabel(Sym);
|
||||
BasicBlock *BB = MBB.getAddressTakenIRBlock();
|
||||
assert(BB && BB->hasAddressTaken() && "Missing BB");
|
||||
for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB))
|
||||
OutStreamer->emitLabel(Sym);
|
||||
} else if (isVerbose() && MBB.isMachineBlockAddressTaken()) {
|
||||
OutStreamer->AddComment("Block address taken");
|
||||
}
|
||||
|
||||
// Print some verbose block comments.
|
||||
if (isVerbose()) {
|
||||
if (BB) {
|
||||
if (const BasicBlock *BB = MBB.getBasicBlock()) {
|
||||
if (BB->hasName()) {
|
||||
BB->printAsOperand(OutStreamer->getCommentOS(),
|
||||
/*PrintType=*/false, BB->getModule());
|
||||
|
|
|
@ -3437,7 +3437,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
|
|||
MF->push_back(MBB);
|
||||
|
||||
if (BB.hasAddressTaken())
|
||||
MBB->setHasAddressTaken();
|
||||
MBB->setAddressTakenIRBlock(const_cast<BasicBlock *>(&BB));
|
||||
|
||||
if (!HasMustTailInVarArgFn)
|
||||
HasMustTailInVarArgFn = checkForMustTailInVarArgFn(IsVarArg, BB);
|
||||
|
|
|
@ -258,7 +258,6 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
|
|||
.Case("call-entry", MIToken::kw_call_entry)
|
||||
.Case("custom", MIToken::kw_custom)
|
||||
.Case("liveout", MIToken::kw_liveout)
|
||||
.Case("address-taken", MIToken::kw_address_taken)
|
||||
.Case("landing-pad", MIToken::kw_landing_pad)
|
||||
.Case("inlineasm-br-indirect-target",
|
||||
MIToken::kw_inlineasm_br_indirect_target)
|
||||
|
@ -275,6 +274,8 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
|
|||
.Case("unknown-size", MIToken::kw_unknown_size)
|
||||
.Case("unknown-address", MIToken::kw_unknown_address)
|
||||
.Case("distinct", MIToken::kw_distinct)
|
||||
.Case("ir-block-address-taken", MIToken::kw_ir_block_address_taken)
|
||||
.Case("machine-block-address-taken", MIToken::kw_machine_block_address_taken)
|
||||
.Default(MIToken::Identifier);
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,6 @@ struct MIToken {
|
|||
kw_call_entry,
|
||||
kw_custom,
|
||||
kw_liveout,
|
||||
kw_address_taken,
|
||||
kw_landing_pad,
|
||||
kw_inlineasm_br_indirect_target,
|
||||
kw_ehfunclet_entry,
|
||||
|
@ -129,6 +128,8 @@ struct MIToken {
|
|||
kw_bbsections,
|
||||
kw_unknown_size,
|
||||
kw_unknown_address,
|
||||
kw_ir_block_address_taken,
|
||||
kw_machine_block_address_taken,
|
||||
|
||||
// Metadata types.
|
||||
kw_distinct,
|
||||
|
|
|
@ -495,6 +495,7 @@ public:
|
|||
MachineOperand &Dest,
|
||||
Optional<unsigned> &TiedDefIdx);
|
||||
bool parseOffset(int64_t &Offset);
|
||||
bool parseIRBlockAddressTaken(BasicBlock *&BB);
|
||||
bool parseAlignment(uint64_t &Alignment);
|
||||
bool parseAddrspace(unsigned &Addrspace);
|
||||
bool parseSectionID(Optional<MBBSectionID> &SID);
|
||||
|
@ -669,7 +670,8 @@ bool MIParser::parseBasicBlockDefinition(
|
|||
auto Loc = Token.location();
|
||||
auto Name = Token.stringValue();
|
||||
lex();
|
||||
bool HasAddressTaken = false;
|
||||
bool MachineBlockAddressTaken = false;
|
||||
BasicBlock *AddressTakenIRBlock = nullptr;
|
||||
bool IsLandingPad = false;
|
||||
bool IsInlineAsmBrIndirectTarget = false;
|
||||
bool IsEHFuncletEntry = false;
|
||||
|
@ -680,10 +682,14 @@ bool MIParser::parseBasicBlockDefinition(
|
|||
do {
|
||||
// TODO: Report an error when multiple same attributes are specified.
|
||||
switch (Token.kind()) {
|
||||
case MIToken::kw_address_taken:
|
||||
HasAddressTaken = true;
|
||||
case MIToken::kw_machine_block_address_taken:
|
||||
MachineBlockAddressTaken = true;
|
||||
lex();
|
||||
break;
|
||||
case MIToken::kw_ir_block_address_taken:
|
||||
if (parseIRBlockAddressTaken(AddressTakenIRBlock))
|
||||
return true;
|
||||
break;
|
||||
case MIToken::kw_landing_pad:
|
||||
IsLandingPad = true;
|
||||
lex();
|
||||
|
@ -701,6 +707,7 @@ bool MIParser::parseBasicBlockDefinition(
|
|||
return true;
|
||||
break;
|
||||
case MIToken::IRBlock:
|
||||
case MIToken::NamedIRBlock:
|
||||
// TODO: Report an error when both name and ir block are specified.
|
||||
if (parseIRBlock(BB, MF.getFunction()))
|
||||
return true;
|
||||
|
@ -736,8 +743,10 @@ bool MIParser::parseBasicBlockDefinition(
|
|||
Twine(ID));
|
||||
if (Alignment)
|
||||
MBB->setAlignment(Align(Alignment));
|
||||
if (HasAddressTaken)
|
||||
MBB->setHasAddressTaken();
|
||||
if (MachineBlockAddressTaken)
|
||||
MBB->setMachineBlockAddressTaken();
|
||||
if (AddressTakenIRBlock)
|
||||
MBB->setAddressTakenIRBlock(AddressTakenIRBlock);
|
||||
MBB->setIsEHPad(IsLandingPad);
|
||||
MBB->setIsInlineAsmBrIndirectTarget(IsInlineAsmBrIndirectTarget);
|
||||
MBB->setIsEHFuncletEntry(IsEHFuncletEntry);
|
||||
|
@ -2918,6 +2927,19 @@ bool MIParser::parseOffset(int64_t &Offset) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseIRBlockAddressTaken(BasicBlock *&BB) {
|
||||
assert(Token.is(MIToken::kw_ir_block_address_taken));
|
||||
lex();
|
||||
if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
|
||||
return error("expected basic block after 'ir_block_address_taken'");
|
||||
|
||||
if (parseIRBlock(BB, MF.getFunction()))
|
||||
return true;
|
||||
|
||||
lex();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseAlignment(uint64_t &Alignment) {
|
||||
assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign));
|
||||
lex();
|
||||
|
|
|
@ -476,6 +476,28 @@ void MachineBasicBlock::printName(raw_ostream &os, unsigned printNameFlags,
|
|||
os << "bb." << getNumber();
|
||||
bool hasAttributes = false;
|
||||
|
||||
auto PrintBBRef = [&](const BasicBlock *bb) {
|
||||
os << "%ir-block.";
|
||||
if (bb->hasName()) {
|
||||
os << bb->getName();
|
||||
} else {
|
||||
int slot = -1;
|
||||
|
||||
if (moduleSlotTracker) {
|
||||
slot = moduleSlotTracker->getLocalSlot(bb);
|
||||
} else if (bb->getParent()) {
|
||||
ModuleSlotTracker tmpTracker(bb->getModule(), false);
|
||||
tmpTracker.incorporateFunction(*bb->getParent());
|
||||
slot = tmpTracker.getLocalSlot(bb);
|
||||
}
|
||||
|
||||
if (slot == -1)
|
||||
os << "<ir-block badref>";
|
||||
else
|
||||
os << slot;
|
||||
}
|
||||
};
|
||||
|
||||
if (printNameFlags & PrintNameIr) {
|
||||
if (const auto *bb = getBasicBlock()) {
|
||||
if (bb->hasName()) {
|
||||
|
@ -483,29 +505,21 @@ void MachineBasicBlock::printName(raw_ostream &os, unsigned printNameFlags,
|
|||
} else {
|
||||
hasAttributes = true;
|
||||
os << " (";
|
||||
|
||||
int slot = -1;
|
||||
|
||||
if (moduleSlotTracker) {
|
||||
slot = moduleSlotTracker->getLocalSlot(bb);
|
||||
} else if (bb->getParent()) {
|
||||
ModuleSlotTracker tmpTracker(bb->getModule(), false);
|
||||
tmpTracker.incorporateFunction(*bb->getParent());
|
||||
slot = tmpTracker.getLocalSlot(bb);
|
||||
}
|
||||
|
||||
if (slot == -1)
|
||||
os << "<ir-block badref>";
|
||||
else
|
||||
os << (Twine("%ir-block.") + Twine(slot)).str();
|
||||
PrintBBRef(bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (printNameFlags & PrintNameAttributes) {
|
||||
if (hasAddressTaken()) {
|
||||
if (isMachineBlockAddressTaken()) {
|
||||
os << (hasAttributes ? ", " : " (");
|
||||
os << "address-taken";
|
||||
os << "machine-block-address-taken";
|
||||
hasAttributes = true;
|
||||
}
|
||||
if (isIRBlockAddressTaken()) {
|
||||
os << (hasAttributes ? ", " : " (");
|
||||
os << "ir-block-address-taken ";
|
||||
PrintBBRef(getAddressTakenIRBlock());
|
||||
hasAttributes = true;
|
||||
}
|
||||
if (isEHPad()) {
|
||||
|
|
|
@ -632,6 +632,13 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
|
|||
}
|
||||
}
|
||||
|
||||
if (MBB->isIRBlockAddressTaken()) {
|
||||
if (!MBB->getAddressTakenIRBlock()->hasAddressTaken())
|
||||
report("ir-block-address-taken is associated with basic block not used by "
|
||||
"a blockaddress.",
|
||||
MBB);
|
||||
}
|
||||
|
||||
// Count the number of landing pad successors.
|
||||
SmallPtrSet<const MachineBasicBlock*, 4> LandingPadSuccs;
|
||||
for (const auto *succ : MBB->successors()) {
|
||||
|
|
|
@ -270,7 +270,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
|
|||
// be multiple MachineBasicBlocks corresponding to one BasicBlock, and only
|
||||
// the first one should be marked.
|
||||
if (BB.hasAddressTaken())
|
||||
MBB->setHasAddressTaken();
|
||||
MBB->setAddressTakenIRBlock(const_cast<BasicBlock *>(&BB));
|
||||
|
||||
// Mark landing pad blocks.
|
||||
if (BB.isEHPad())
|
||||
|
|
|
@ -3007,7 +3007,7 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) {
|
|||
BasicBlock *Dest = I.getIndirectDest(i);
|
||||
MachineBasicBlock *Target = FuncInfo.MBBMap[Dest];
|
||||
Target->setIsInlineAsmBrIndirectTarget();
|
||||
Target->setHasAddressTaken();
|
||||
Target->setMachineBlockAddressTaken();
|
||||
// Don't add duplicate machine successors.
|
||||
if (Dests.insert(Dest).second)
|
||||
addSuccessorWithProb(CallBrMBB, Target, BranchProbability::getZero());
|
||||
|
|
|
@ -1263,13 +1263,8 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L,
|
|||
.addMBB(LoopStart).addImm(CountImm);
|
||||
}
|
||||
|
||||
// Make sure the loop start always has a reference in the CFG. We need
|
||||
// to create a BlockAddress operand to get this mechanism to work both the
|
||||
// MachineBasicBlock and BasicBlock objects need the flag set.
|
||||
LoopStart->setHasAddressTaken();
|
||||
// This line is needed to set the hasAddressTaken flag on the BasicBlock
|
||||
// object.
|
||||
BlockAddress::get(const_cast<BasicBlock *>(LoopStart->getBasicBlock()));
|
||||
// Make sure the loop start always has a reference in the CFG.
|
||||
LoopStart->setMachineBlockAddressTaken();
|
||||
|
||||
// Replace the loop branch with an endloop instruction.
|
||||
DebugLoc LastIDL = LastI->getDebugLoc();
|
||||
|
|
|
@ -2214,7 +2214,7 @@ VETargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
|
|||
MF->insert(I, MainMBB);
|
||||
MF->insert(I, SinkMBB);
|
||||
MF->push_back(RestoreMBB);
|
||||
RestoreMBB->setHasAddressTaken();
|
||||
RestoreMBB->setMachineBlockAddressTaken();
|
||||
|
||||
// Transfer the remainder of BB and its successor edges to SinkMBB.
|
||||
SinkMBB->splice(SinkMBB->begin(), MBB,
|
||||
|
|
|
@ -2777,7 +2777,7 @@ void X86FrameLowering::emitCatchRetReturnValue(MachineBasicBlock &MBB,
|
|||
|
||||
// Record that we've taken the address of CatchRetTarget and no longer just
|
||||
// reference it in a terminator.
|
||||
CatchRetTarget->setHasAddressTaken();
|
||||
CatchRetTarget->setMachineBlockAddressTaken();
|
||||
}
|
||||
|
||||
bool X86FrameLowering::restoreCalleeSavedRegisters(
|
||||
|
|
|
@ -35640,7 +35640,7 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
|
|||
MF->insert(I, mainMBB);
|
||||
MF->insert(I, sinkMBB);
|
||||
MF->push_back(restoreMBB);
|
||||
restoreMBB->setHasAddressTaken();
|
||||
restoreMBB->setMachineBlockAddressTaken();
|
||||
|
||||
MachineInstrBuilder MIB;
|
||||
|
||||
|
|
|
@ -234,11 +234,11 @@ void RetpolineThunkInserter::populateThunk(MachineFunction &MF) {
|
|||
BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::PAUSE));
|
||||
BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::LFENCE));
|
||||
BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::JMP_1)).addMBB(CaptureSpec);
|
||||
CaptureSpec->setHasAddressTaken();
|
||||
CaptureSpec->setMachineBlockAddressTaken();
|
||||
CaptureSpec->addSuccessor(CaptureSpec);
|
||||
|
||||
CallTarget->addLiveIn(ThunkReg);
|
||||
CallTarget->setHasAddressTaken();
|
||||
CallTarget->setMachineBlockAddressTaken();
|
||||
CallTarget->setAlignment(Align(16));
|
||||
|
||||
// Insert return address clobber
|
||||
|
|
|
@ -1145,7 +1145,7 @@ X86SpeculativeLoadHardeningPass::tracePredStateThroughIndirectBranches(
|
|||
// Insert a comparison of the incoming target register with this block's
|
||||
// address. This also requires us to mark the block as having its address
|
||||
// taken explicitly.
|
||||
MBB.setHasAddressTaken();
|
||||
MBB.setMachineBlockAddressTaken();
|
||||
auto InsertPt = MBB.SkipPHIsLabelsAndDebug(MBB.begin());
|
||||
if (MF.getTarget().getCodeModel() == CodeModel::Small &&
|
||||
!Subtarget->isPositionIndependent()) {
|
||||
|
|
|
@ -137,13 +137,13 @@ false:
|
|||
; CHECK-NEXT: successors: %[[BB_L1:bb.[0-9]+]](0x80000000)
|
||||
;
|
||||
; Check basic block L1 has 2 successors: BBL1 and BBL2
|
||||
; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (address-taken):
|
||||
; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (ir-block-address-taken %ir-block.{{[a-zA-Z0-9.]+}}):
|
||||
; CHECK-NEXT: successors: %[[BB_L1]](0x40000000),
|
||||
; CHECK: %[[BB_L2:bb.[0-9]+]](0x40000000)
|
||||
; CHECK: G_BRINDIRECT %{{[0-9]+}}(p0)
|
||||
;
|
||||
; Check basic block L2 is the return basic block
|
||||
; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (address-taken):
|
||||
; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (ir-block-address-taken %ir-block.{{[a-zA-Z0-9.]+}}):
|
||||
; CHECK-NEXT: RET_ReallyLR
|
||||
|
||||
@indirectbr.L = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@indirectbr, %L1), i8* blockaddress(@indirectbr, %L2), i8* null], align 8
|
||||
|
|
|
@ -25,20 +25,21 @@ registers:
|
|||
body: |
|
||||
; CHECK-LABEL: name: test_blockaddress
|
||||
; CHECK: bb.0 (%ir-block.0):
|
||||
; CHECK: [[BLOCK_ADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
|
||||
; CHECK: [[ADRP:%[0-9]+]]:gpr64(p0) = ADRP target-flags(aarch64-page) @addr
|
||||
; CHECK: [[ADD_LOW:%[0-9]+]]:_(p0) = G_ADD_LOW [[ADRP]](p0), target-flags(aarch64-pageoff, aarch64-nc) @addr
|
||||
; CHECK: G_STORE [[BLOCK_ADDR]](p0), [[ADD_LOW]](p0) :: (store (p0) into @addr)
|
||||
; CHECK: G_BRINDIRECT [[BLOCK_ADDR]](p0)
|
||||
; CHECK: bb.1.block (address-taken):
|
||||
; CHECK: RET_ReallyLR
|
||||
; CHECK-NEXT: [[BLOCK_ADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
|
||||
; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64(p0) = ADRP target-flags(aarch64-page) @addr
|
||||
; CHECK-NEXT: [[ADD_LOW:%[0-9]+]]:_(p0) = G_ADD_LOW [[ADRP]](p0), target-flags(aarch64-pageoff, aarch64-nc) @addr
|
||||
; CHECK-NEXT: G_STORE [[BLOCK_ADDR]](p0), [[ADD_LOW]](p0) :: (store (p0) into @addr)
|
||||
; CHECK-NEXT: G_BRINDIRECT [[BLOCK_ADDR]](p0)
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: bb.1.block (ir-block-address-taken %ir-block.block):
|
||||
; CHECK-NEXT: RET_ReallyLR
|
||||
bb.1 (%ir-block.0):
|
||||
%0:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
|
||||
%1:_(p0) = G_GLOBAL_VALUE @addr
|
||||
G_STORE %0(p0), %1(p0) :: (store (p0) into @addr)
|
||||
G_BRINDIRECT %0(p0)
|
||||
|
||||
bb.2.block (address-taken):
|
||||
bb.2.block (ir-block-address-taken %ir-block.block):
|
||||
RET_ReallyLR
|
||||
|
||||
...
|
||||
|
|
|
@ -30,32 +30,34 @@ registers:
|
|||
body: |
|
||||
; CHECK-LABEL: name: test_blockaddress
|
||||
; CHECK: bb.0 (%ir-block.0):
|
||||
; CHECK: [[MOVaddrBA:%[0-9]+]]:gpr64common = MOVaddrBA target-flags(aarch64-page) blockaddress(@test_blockaddress, %ir-block.block), target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block)
|
||||
; CHECK: [[MOVaddr:%[0-9]+]]:gpr64common = MOVaddr target-flags(aarch64-page) @addr, target-flags(aarch64-pageoff, aarch64-nc) @addr
|
||||
; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY [[MOVaddrBA]]
|
||||
; CHECK: STRXui [[COPY]], [[MOVaddr]], 0 :: (store (p0) into @addr)
|
||||
; CHECK: BR [[MOVaddrBA]]
|
||||
; CHECK: bb.1.block (address-taken):
|
||||
; CHECK-NEXT: [[MOVaddrBA:%[0-9]+]]:gpr64common = MOVaddrBA target-flags(aarch64-page) blockaddress(@test_blockaddress, %ir-block.block), target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block)
|
||||
; CHECK-NEXT: [[MOVaddr:%[0-9]+]]:gpr64common = MOVaddr target-flags(aarch64-page) @addr, target-flags(aarch64-pageoff, aarch64-nc) @addr
|
||||
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY [[MOVaddrBA]]
|
||||
; CHECK-NEXT: STRXui [[COPY]], [[MOVaddr]], 0 :: (store (p0) into @addr)
|
||||
; CHECK-NEXT: BR [[MOVaddrBA]]
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: bb.1.block (ir-block-address-taken %ir-block.block):
|
||||
; LARGE-LABEL: name: test_blockaddress
|
||||
; LARGE: bb.0 (%ir-block.0):
|
||||
; LARGE: [[MOVZXi:%[0-9]+]]:gpr64 = MOVZXi target-flags(aarch64-g0, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 0
|
||||
; LARGE: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[MOVZXi]], target-flags(aarch64-g1, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 16
|
||||
; LARGE: [[MOVKXi1:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi]], target-flags(aarch64-g2, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 32
|
||||
; LARGE: [[MOVKXi2:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi1]], target-flags(aarch64-g3) blockaddress(@test_blockaddress, %ir-block.block), 48
|
||||
; LARGE: [[MOVZXi1:%[0-9]+]]:gpr64 = MOVZXi target-flags(aarch64-g0, aarch64-nc) @addr, 0
|
||||
; LARGE: [[MOVKXi3:%[0-9]+]]:gpr64 = MOVKXi [[MOVZXi1]], target-flags(aarch64-g1, aarch64-nc) @addr, 16
|
||||
; LARGE: [[MOVKXi4:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi3]], target-flags(aarch64-g2, aarch64-nc) @addr, 32
|
||||
; LARGE: [[MOVKXi5:%[0-9]+]]:gpr64common = MOVKXi [[MOVKXi4]], target-flags(aarch64-g3) @addr, 48
|
||||
; LARGE: STRXui [[MOVKXi2]], [[MOVKXi5]], 0 :: (store (p0) into @addr)
|
||||
; LARGE: BR [[MOVKXi2]]
|
||||
; LARGE: bb.1.block (address-taken):
|
||||
; LARGE-NEXT: [[MOVZXi:%[0-9]+]]:gpr64 = MOVZXi target-flags(aarch64-g0, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 0
|
||||
; LARGE-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[MOVZXi]], target-flags(aarch64-g1, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 16
|
||||
; LARGE-NEXT: [[MOVKXi1:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi]], target-flags(aarch64-g2, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 32
|
||||
; LARGE-NEXT: [[MOVKXi2:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi1]], target-flags(aarch64-g3) blockaddress(@test_blockaddress, %ir-block.block), 48
|
||||
; LARGE-NEXT: [[MOVZXi1:%[0-9]+]]:gpr64 = MOVZXi target-flags(aarch64-g0, aarch64-nc) @addr, 0
|
||||
; LARGE-NEXT: [[MOVKXi3:%[0-9]+]]:gpr64 = MOVKXi [[MOVZXi1]], target-flags(aarch64-g1, aarch64-nc) @addr, 16
|
||||
; LARGE-NEXT: [[MOVKXi4:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi3]], target-flags(aarch64-g2, aarch64-nc) @addr, 32
|
||||
; LARGE-NEXT: [[MOVKXi5:%[0-9]+]]:gpr64common = MOVKXi [[MOVKXi4]], target-flags(aarch64-g3) @addr, 48
|
||||
; LARGE-NEXT: STRXui [[MOVKXi2]], [[MOVKXi5]], 0 :: (store (p0) into @addr)
|
||||
; LARGE-NEXT: BR [[MOVKXi2]]
|
||||
; LARGE-NEXT: {{ $}}
|
||||
; LARGE-NEXT: bb.1.block (ir-block-address-taken %ir-block.block):
|
||||
bb.1 (%ir-block.0):
|
||||
%0:gpr(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
|
||||
%1:gpr(p0) = G_GLOBAL_VALUE @addr
|
||||
G_STORE %0(p0), %1(p0) :: (store (p0) into @addr)
|
||||
G_BRINDIRECT %0(p0)
|
||||
|
||||
bb.2.block (address-taken):
|
||||
bb.2.block (ir-block-address-taken %ir-block.block):
|
||||
RET_ReallyLR
|
||||
|
||||
...
|
||||
|
|
|
@ -1,371 +0,0 @@
|
|||
# RUN: llc -run-pass=aarch64-branch-targets -mattr=+pauth %s -o - | FileCheck %s
|
||||
--- |
|
||||
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
|
||||
target triple = "aarch64-arm-none-eabi"
|
||||
|
||||
define hidden i32 @simple_external() "branch-target-enforcement"="true" {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define internal i32 @simple_internal() "branch-target-enforcement"="true" {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define hidden i32 @ptr_auth() "branch-target-enforcement"="true" {
|
||||
entry:
|
||||
tail call void asm sideeffect "", "~{lr}"()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define hidden i32 @ptr_auth_b() "branch-target-enforcement"="true" {
|
||||
entry:
|
||||
tail call void asm sideeffect "", "~{lr}"()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define hidden i32 @jump_table(i32 %a) "branch-target-enforcement"="true" {
|
||||
entry:
|
||||
switch i32 %a, label %sw.epilog [
|
||||
i32 1, label %sw.bb
|
||||
i32 2, label %sw.bb1
|
||||
i32 3, label %sw.bb2
|
||||
i32 4, label %sw.bb3
|
||||
i32 5, label %sw.bb4
|
||||
]
|
||||
|
||||
sw.bb: ; preds = %entry
|
||||
tail call void asm sideeffect "", ""()
|
||||
br label %sw.epilog
|
||||
|
||||
sw.bb1: ; preds = %entry
|
||||
tail call void asm sideeffect "", ""()
|
||||
br label %sw.epilog
|
||||
|
||||
sw.bb2: ; preds = %entry
|
||||
tail call void asm sideeffect "", ""()
|
||||
br label %sw.epilog
|
||||
|
||||
sw.bb3: ; preds = %entry
|
||||
tail call void asm sideeffect "", ""()
|
||||
br label %sw.epilog
|
||||
|
||||
sw.bb4: ; preds = %entry
|
||||
tail call void asm sideeffect "", ""()
|
||||
br label %sw.epilog
|
||||
|
||||
sw.epilog: ; preds = %entry, %sw.bb4, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
@label_address.addr = internal unnamed_addr global i8* blockaddress(@label_address, %return), align 8
|
||||
|
||||
define hidden i32 @label_address() "branch-target-enforcement"="true" {
|
||||
entry:
|
||||
%0 = load i8*, i8** @label_address.addr, align 8
|
||||
indirectbr i8* %0, [label %return, label %lab2]
|
||||
|
||||
lab2: ; preds = %entry
|
||||
br label %.split
|
||||
|
||||
return: ; preds = %entry
|
||||
br label %.split
|
||||
|
||||
.split: ; preds = %lab2, %return
|
||||
%merge = phi i8* [ blockaddress(@label_address, %lab2), %return ], [ blockaddress(@label_address, %return), %lab2 ]
|
||||
%merge2 = phi i32 [ 1, %return ], [ 2, %lab2 ]
|
||||
store i8* %merge, i8** @label_address.addr, align 8
|
||||
ret i32 %merge2
|
||||
}
|
||||
|
||||
define hidden i32 @label_address_entry() "branch-target-enforcement"="true" {
|
||||
entry:
|
||||
%0 = load i8*, i8** @label_address.addr, align 8
|
||||
indirectbr i8* %0, [label %return, label %lab2]
|
||||
|
||||
lab2: ; preds = %entry
|
||||
br label %.split
|
||||
|
||||
return: ; preds = %entry
|
||||
br label %.split
|
||||
|
||||
.split: ; preds = %lab2, %return
|
||||
%merge = phi i8* [ blockaddress(@label_address, %lab2), %return ], [ blockaddress(@label_address, %return), %lab2 ]
|
||||
%merge2 = phi i32 [ 1, %return ], [ 2, %lab2 ]
|
||||
store i8* %merge, i8** @label_address.addr, align 8
|
||||
ret i32 %merge2
|
||||
}
|
||||
|
||||
define hidden i32 @debug_ptr_auth() "branch-target-enforcement"="true" {
|
||||
entry:
|
||||
tail call void asm sideeffect "", "~{lr}"()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
...
|
||||
---
|
||||
# External function, could be addres-taken elsewhere so needs BTI JC.
|
||||
name: simple_external
|
||||
body: |
|
||||
bb.0.entry:
|
||||
; CHECK-LABEL: name: simple_external
|
||||
; CHECK: HINT 34
|
||||
; CHECK: RET
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
RET undef $lr, implicit killed $w0
|
||||
|
||||
---
|
||||
# Internal function, not address-taken in this module, however the compiler
|
||||
# cannot 100% ensure that later parts of the toolchain won't add indirect
|
||||
# jumps. E.g. a linker adding a thunk to extend the range of a direct jump.
|
||||
# Therefore, even this case needs a BTI.
|
||||
name: simple_internal
|
||||
body: |
|
||||
bb.0.entry:
|
||||
; CHECK-LABEL: name: simple_internal
|
||||
; CHECK: HINT 34
|
||||
; CHECK: RET
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
RET undef $lr, implicit killed $w0
|
||||
|
||||
---
|
||||
# Function starts with PACIASP, which implicitly acts as BTI JC, so no change
|
||||
# needed.
|
||||
name: ptr_auth
|
||||
stack:
|
||||
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
|
||||
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $lr
|
||||
|
||||
; CHECK-LABEL: name: ptr_auth
|
||||
; CHECK-NOT: HINT
|
||||
; CHECK: frame-setup PACIASP
|
||||
; CHECK-NOT: HINT
|
||||
; CHECK: RETAA
|
||||
frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
|
||||
early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
|
||||
INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
|
||||
RETAA implicit $sp, implicit $lr, implicit killed $w0
|
||||
|
||||
---
|
||||
# Function starts with PACIBSP, which implicitly acts as BTI JC, so no change
|
||||
# needed.
|
||||
name: ptr_auth_b
|
||||
stack:
|
||||
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
|
||||
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $lr
|
||||
|
||||
; CHECK-LABEL: name: ptr_auth_b
|
||||
; CHECK-NOT: HINT
|
||||
; CHECK: frame-setup PACIBSP
|
||||
; CHECK-NOT: HINT
|
||||
; CHECK: RETAB
|
||||
frame-setup PACIBSP implicit-def $lr, implicit killed $lr, implicit $sp
|
||||
early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
|
||||
INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
|
||||
RETAB implicit $sp, implicit $lr, implicit killed $w0
|
||||
|
||||
---
|
||||
# Function contains a jump table, so every target of the jump table must start
|
||||
# with BTI J.
|
||||
name: jump_table
|
||||
jumpTable:
|
||||
kind: block-address
|
||||
entries:
|
||||
- id: 0
|
||||
blocks: [ '%bb.2', '%bb.3', '%bb.4', '%bb.5', '%bb.6' ]
|
||||
body: |
|
||||
bb.0.entry:
|
||||
; CHECK-LABEL: name: jump_table
|
||||
; CHECK: HINT 34
|
||||
successors: %bb.7(0x15555555), %bb.1(0x6aaaaaab)
|
||||
liveins: $w0
|
||||
|
||||
renamable $w8 = SUBWri killed renamable $w0, 1, 0, implicit-def $x8
|
||||
dead $wzr = SUBSWri renamable $w8, 4, 0, implicit-def $nzcv
|
||||
Bcc 8, %bb.7, implicit $nzcv
|
||||
|
||||
bb.1.entry:
|
||||
; CHECK: bb.1.entry:
|
||||
; CHECK-NOT: HINT
|
||||
; CHECK: BR killed renamable $x8
|
||||
successors: %bb.2(0x1999999a), %bb.3(0x1999999a), %bb.4(0x1999999a), %bb.5(0x1999999a), %bb.6(0x1999999a)
|
||||
liveins: $x8
|
||||
|
||||
$x9 = ADRP target-flags(aarch64-page) %jump-table.0
|
||||
renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0, 0
|
||||
renamable $x8 = LDRXroX killed renamable $x9, killed renamable $x8, 0, 1 :: (load (s64) from jump-table)
|
||||
BR killed renamable $x8
|
||||
|
||||
bb.2.sw.bb:
|
||||
; CHECK: bb.2.sw.bb
|
||||
; CHECK-NEXT: HINT 36
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
INLINEASM &"", 1
|
||||
RET undef $lr, implicit killed $w0
|
||||
|
||||
bb.3.sw.bb1:
|
||||
; CHECK: bb.3.sw.bb1
|
||||
; CHECK-NEXT: HINT 36
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
INLINEASM &"", 1
|
||||
RET undef $lr, implicit killed $w0
|
||||
|
||||
bb.4.sw.bb2:
|
||||
; CHECK: bb.4.sw.bb2
|
||||
; CHECK-NEXT: HINT 36
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
INLINEASM &"", 1
|
||||
RET undef $lr, implicit killed $w0
|
||||
|
||||
bb.5.sw.bb3:
|
||||
; CHECK: bb.5.sw.bb3
|
||||
; CHECK-NEXT: HINT 36
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
INLINEASM &"", 1
|
||||
RET undef $lr, implicit killed $w0
|
||||
|
||||
bb.6.sw.bb4:
|
||||
; CHECK: bb.6.sw.bb4
|
||||
; CHECK-NEXT: successors: %bb.7(0x80000000)
|
||||
; CHECK-NEXT: {{ }}
|
||||
; CHECK-NEXT: HINT 36
|
||||
successors: %bb.7(0x80000000)
|
||||
|
||||
INLINEASM &"", 1
|
||||
|
||||
bb.7.sw.epilog:
|
||||
; CHECK: bb.7.sw.epilog:
|
||||
; CHECK-NOT: HINT
|
||||
; CHECK: RET
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
RET undef $lr, implicit killed $w0
|
||||
|
||||
---
|
||||
# Function takes address of basic blocks, so they must start with BTI J.
|
||||
name: label_address
|
||||
body: |
|
||||
bb.0.entry:
|
||||
; CHECK-LABEL: label_address
|
||||
; CHECK: bb.0.entry:
|
||||
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
; CHECK-NEXT: {{ }}
|
||||
; CHECK-NEXT: HINT 34
|
||||
; CHECK: BR killed renamable $x9
|
||||
successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
|
||||
renamable $x8 = ADRP target-flags(aarch64-page) @label_address.addr
|
||||
renamable $x9 = LDRXui renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (dereferenceable load (s64) from @label_address.addr)
|
||||
BR killed renamable $x9
|
||||
|
||||
bb.1.return (address-taken):
|
||||
; CHECK: bb.1.return (address-taken):
|
||||
; CHECK-NEXT: liveins:
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: HINT 36
|
||||
liveins: $x8
|
||||
|
||||
$x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.lab2)
|
||||
renamable $w0 = ORRWri $wzr, 0
|
||||
renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.lab2), 0
|
||||
STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store (s64) into @label_address.addr)
|
||||
RET undef $lr, implicit killed $w0
|
||||
|
||||
bb.2.lab2 (address-taken):
|
||||
; CHECK: bb.2.lab2 (address-taken):
|
||||
; CHECK-NEXT: liveins:
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: HINT 36
|
||||
liveins: $x8
|
||||
|
||||
$x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.return)
|
||||
renamable $w0 = ORRWri $wzr, 1984
|
||||
renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.return), 0
|
||||
STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store (s64) into @label_address.addr)
|
||||
RET undef $lr, implicit killed $w0
|
||||
|
||||
---
|
||||
# Function takes address of the entry block, so the entry block needs a BTI JC.
|
||||
name: label_address_entry
|
||||
stack:
|
||||
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
|
||||
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
body: |
|
||||
bb.0.entry (address-taken):
|
||||
; CHECK-LABEL: label_address_entry
|
||||
; CHECK: bb.0.entry (address-taken):
|
||||
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
; CHECK-NEXT: {{ }}
|
||||
; CHECK-NEXT: HINT 38
|
||||
; CHECK: BR killed renamable $x9
|
||||
successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
|
||||
renamable $x8 = ADRP target-flags(aarch64-page) @label_address.addr
|
||||
renamable $x9 = LDRXui renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (dereferenceable load (s64) from @label_address.addr)
|
||||
BR killed renamable $x9
|
||||
|
||||
bb.1.return (address-taken):
|
||||
; CHECK: bb.1.return (address-taken):
|
||||
; CHECK-NEXT: liveins:
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: HINT 36
|
||||
liveins: $x8
|
||||
frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
|
||||
frame-setup CFI_INSTRUCTION negate_ra_sign_state
|
||||
early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
|
||||
INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
|
||||
$x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.entry)
|
||||
renamable $w0 = ORRWri $wzr, 0
|
||||
renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.entry), 0
|
||||
STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store (s64) into @label_address.addr)
|
||||
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
|
||||
RETAA implicit $sp, implicit $lr, implicit killed $w0
|
||||
|
||||
bb.2.lab2:
|
||||
; CHECK: bb.2.lab2:
|
||||
; CHECK-NOT: HINT
|
||||
liveins: $x8
|
||||
|
||||
$x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.return)
|
||||
renamable $w0 = ORRWri $wzr, 1984
|
||||
renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.return), 0
|
||||
STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store (s64) into @label_address.addr)
|
||||
RET undef $lr, implicit killed $w0
|
||||
---
|
||||
# When PACIASP is the first real instruction in the functions then BTI should not be inserted.
|
||||
name: debug_ptr_auth
|
||||
stack:
|
||||
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
|
||||
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $lr
|
||||
|
||||
; CHECK-LABEL: name: debug_ptr_auth
|
||||
; CHECK-NOT: HINT
|
||||
; CHECK: frame-setup PACIASP
|
||||
; CHECK-NOT: HINT
|
||||
; CHECK: RETAA
|
||||
frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
|
||||
frame-setup CFI_INSTRUCTION negate_ra_sign_state
|
||||
early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
|
||||
INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
|
||||
RETAA implicit $sp, implicit $lr, implicit killed $w0
|
||||
|
||||
...
|
|
@ -65,11 +65,11 @@ body: |
|
|||
; ISBDSB-NEXT: isb
|
||||
; SB-NEXT: {{ sb$}}
|
||||
|
||||
bb.1.l2 (address-taken):
|
||||
bb.1.l2 (ir-block-address-taken %ir-block.l2):
|
||||
renamable $w0 = MOVZWi 1, 0
|
||||
RET undef $lr, implicit $w0
|
||||
|
||||
bb.2.return (address-taken):
|
||||
bb.2.return (ir-block-address-taken %ir-block.return):
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
RET undef $lr, implicit $w0
|
||||
...
|
||||
|
@ -90,11 +90,11 @@ body: |
|
|||
; ISBDSB-NEXT: isb
|
||||
; SB-NEXT: {{ sb$}}
|
||||
|
||||
bb.1.l2 (address-taken):
|
||||
bb.1.l2 (ir-block-address-taken %ir-block.l2):
|
||||
renamable $w0 = MOVZWi 1, 0
|
||||
RET undef $lr, implicit $w0
|
||||
|
||||
bb.2.return (address-taken):
|
||||
bb.2.return (ir-block-address-taken %ir-block.return):
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
RET undef $lr, implicit $w0
|
||||
...
|
||||
|
@ -115,11 +115,11 @@ body: |
|
|||
; ISBDSB-NEXT: isb
|
||||
; SB-NEXT: {{ sb$}}
|
||||
|
||||
bb.1.l2 (address-taken):
|
||||
bb.1.l2 (ir-block-address-taken %ir-block.l2):
|
||||
renamable $w0 = MOVZWi 1, 0
|
||||
RET undef $lr, implicit $w0
|
||||
|
||||
bb.2.return (address-taken):
|
||||
bb.2.return (ir-block-address-taken %ir-block.return):
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
RET undef $lr, implicit $w0
|
||||
...
|
||||
|
@ -140,11 +140,11 @@ body: |
|
|||
; ISBDSB-NEXT: isb
|
||||
; SB-NEXT: {{ sb$}}
|
||||
|
||||
bb.1.l2 (address-taken):
|
||||
bb.1.l2 (ir-block-address-taken %ir-block.l2):
|
||||
renamable $w0 = MOVZWi 1, 0
|
||||
RET undef $lr, implicit $w0
|
||||
|
||||
bb.2.return (address-taken):
|
||||
bb.2.return (ir-block-address-taken %ir-block.return):
|
||||
$w0 = ORRWrs $wzr, $wzr, 0
|
||||
RET undef $lr, implicit $w0
|
||||
...
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
--- |
|
||||
target triple = "thumbv7-unknown-linux-gnueabi"
|
||||
|
||||
define dso_local void @fn1() {
|
||||
define dso_local i8* @fn1() {
|
||||
entry:
|
||||
br label %l_yes
|
||||
l_yes:
|
||||
ret void
|
||||
ret i8* blockaddress(@fn1, %l_yes)
|
||||
}
|
||||
|
||||
declare dso_local i32 @fn2(...)
|
||||
|
@ -20,22 +22,25 @@ tracksRegLiveness: true
|
|||
body: |
|
||||
; CHECK-LABEL: name: fn1
|
||||
; CHECK: bb.0:
|
||||
; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
; CHECK: liveins: $r0, $r1, $r2, $r4, $lr
|
||||
; CHECK: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r4, killed $lr
|
||||
; CHECK: t2CMPri killed renamable $r2, 34, 14 /* CC::al */, $noreg, implicit-def $cpsr
|
||||
; CHECK: $r0 = t2MOVi 2, 1 /* CC::ne */, $cpsr, $noreg
|
||||
; CHECK: $r0 = t2MOVi 3, 0 /* CC::eq */, killed $cpsr, $noreg, implicit killed $r0
|
||||
; CHECK: tBL 14 /* CC::al */, $noreg, @fn2, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit killed $r1, implicit-def $sp, implicit-def dead $r0
|
||||
; CHECK: t2CMPri $sp, 34, 14 /* CC::al */, $noreg, implicit-def $cpsr
|
||||
; CHECK: t2Bcc %bb.2, 1 /* CC::ne */, $cpsr
|
||||
; CHECK: t2Bcc %bb.2, 2 /* CC::hs */, killed $cpsr
|
||||
; CHECK: t2B %bb.1, 14 /* CC::al */, $noreg
|
||||
; CHECK: bb.1:
|
||||
; CHECK: INLINEASM &"", 1
|
||||
; CHECK: $sp = t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r4, def $pc
|
||||
; CHECK: bb.2.l_yes (address-taken):
|
||||
; CHECK: $sp = t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r4, def $pc
|
||||
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
; CHECK-NEXT: liveins: $r0, $r1, $r2, $r4, $lr
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r4, killed $lr
|
||||
; CHECK-NEXT: t2CMPri killed renamable $r2, 34, 14 /* CC::al */, $noreg, implicit-def $cpsr
|
||||
; CHECK-NEXT: $r0 = t2MOVi 2, 1 /* CC::ne */, $cpsr, $noreg
|
||||
; CHECK-NEXT: $r0 = t2MOVi 3, 0 /* CC::eq */, killed $cpsr, $noreg, implicit killed $r0
|
||||
; CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @fn2, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit killed $r1, implicit-def $sp, implicit-def dead $r0
|
||||
; CHECK-NEXT: t2CMPri $sp, 34, 14 /* CC::al */, $noreg, implicit-def $cpsr
|
||||
; CHECK-NEXT: t2Bcc %bb.2, 1 /* CC::ne */, $cpsr
|
||||
; CHECK-NEXT: t2Bcc %bb.2, 2 /* CC::hs */, killed $cpsr
|
||||
; CHECK-NEXT: t2B %bb.1, 14 /* CC::al */, $noreg
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: bb.1:
|
||||
; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */
|
||||
; CHECK-NEXT: $sp = t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r4, def $pc
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: bb.2.l_yes (ir-block-address-taken %ir-block.l_yes):
|
||||
; CHECK-NEXT: $sp = t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r4, def $pc
|
||||
bb.0:
|
||||
successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
liveins: $r0, $r1, $r2, $r4, $lr
|
||||
|
@ -70,7 +75,7 @@ body: |
|
|||
INLINEASM &"", 1
|
||||
$sp = t2LDMIA_RET $sp, 14, $noreg, def $r4, def $pc
|
||||
|
||||
bb.4.l_yes (address-taken):
|
||||
bb.4.l_yes (ir-block-address-taken %ir-block.l_yes):
|
||||
$sp = t2LDMIA_RET $sp, 14, $noreg, def $r4, def $pc
|
||||
|
||||
...
|
||||
|
|
|
@ -553,7 +553,7 @@ body: |
|
|||
INLINEASM_BR &"b ${0:l}", 1, 13, blockaddress(@fn9, %ir-block.lab1)
|
||||
tBX_RET 14, $noreg, implicit $r2
|
||||
|
||||
bb.5.lab1 (address-taken):
|
||||
bb.5.lab1 (ir-block-address-taken %ir-block.lab1):
|
||||
liveins: $r0
|
||||
|
||||
renamable $r0, dead $cpsr = nsw tADDi8 killed renamable $r0, 5, 14, $noreg
|
||||
|
|
|
@ -107,7 +107,7 @@ body: |
|
|||
$r4 = A2_tfrsi 10
|
||||
J2_loop0r %bb.1, killed $r0, implicit-def $lc0, implicit-def $sa0, implicit-def $usr
|
||||
|
||||
bb.1 (address-taken):
|
||||
bb.1 (machine-block-address-taken):
|
||||
successors: %bb.2(0x80000000)
|
||||
liveins: $lc0:0x00000004, $r2:0x00000001, $r3:0x00000001, $r4:0x00000001, $sa0:0x00000004
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# CHECK: [[R0:%[0-9]+]]:intregs = A2_tfrsi 1920
|
||||
# CHECK: J2_loop0r %bb.1, [[R0]]
|
||||
#
|
||||
# CHECK: bb.1.b1 (address-taken):
|
||||
# CHECK: bb.1.b1 (machine-block-address-taken):
|
||||
# CHECK: ENDLOOP0 %bb.1
|
||||
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ define void @f0(i8* nocapture %a0, i32 %a1, i32 %a2) #0 {
|
|||
; CHECK-NEXT: loop0(.LBB0_1,#3)
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: .p2align 4
|
||||
; CHECK-NEXT: .Ltmp0: // Block address taken
|
||||
; CHECK-NEXT: .LBB0_1: // %b2
|
||||
; CHECK-NEXT: .LBB0_1: // Block address taken
|
||||
; CHECK-NEXT: // %b2
|
||||
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: {
|
||||
; CHECK-NEXT: nop
|
||||
|
@ -42,8 +42,8 @@ define void @f1(i8* nocapture %a0, i32 %a1, i32 %a2) #0 {
|
|||
; CHECK-NEXT: loop0(.LBB1_1,#2)
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: .p2align 4
|
||||
; CHECK-NEXT: .Ltmp1: // Block address taken
|
||||
; CHECK-NEXT: .LBB1_1: // %b2
|
||||
; CHECK-NEXT: .LBB1_1: // Block address taken
|
||||
; CHECK-NEXT: // %b2
|
||||
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: {
|
||||
; CHECK-NEXT: nop
|
||||
|
@ -76,8 +76,8 @@ define void @f2(i8* nocapture %a0, i32 %a1, i32 %a2) #0 {
|
|||
; CHECK-NEXT: loop0(.LBB2_1,#1)
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: .p2align 4
|
||||
; CHECK-NEXT: .Ltmp2: // Block address taken
|
||||
; CHECK-NEXT: .LBB2_1: // %b2
|
||||
; CHECK-NEXT: .LBB2_1: // Block address taken
|
||||
; CHECK-NEXT: // %b2
|
||||
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: {
|
||||
; CHECK-NEXT: nop
|
||||
|
@ -110,8 +110,8 @@ define void @f3(i8* nocapture %a0, i32 %a1, i32 %a2) #0 {
|
|||
; CHECK-NEXT: loop0(.LBB3_1,#4)
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: .p2align 4
|
||||
; CHECK-NEXT: .Ltmp3: // Block address taken
|
||||
; CHECK-NEXT: .LBB3_1: // %b2
|
||||
; CHECK-NEXT: .LBB3_1: // Block address taken
|
||||
; CHECK-NEXT: // %b2
|
||||
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: {
|
||||
; CHECK-NEXT: nop
|
||||
|
@ -144,8 +144,8 @@ define void @f4(i8* nocapture %a0, i32 %a1, i32 %a2) #0 {
|
|||
; CHECK-NEXT: loop0(.LBB4_1,#2)
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: .p2align 4
|
||||
; CHECK-NEXT: .Ltmp4: // Block address taken
|
||||
; CHECK-NEXT: .LBB4_1: // %b2
|
||||
; CHECK-NEXT: .LBB4_1: // Block address taken
|
||||
; CHECK-NEXT: // %b2
|
||||
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: {
|
||||
; CHECK-NEXT: nop
|
||||
|
@ -178,8 +178,8 @@ define void @f5(i8* nocapture %a0, i32 %a1, i32 %a2) #0 {
|
|||
; CHECK-NEXT: loop0(.LBB5_1,#2)
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: .p2align 4
|
||||
; CHECK-NEXT: .Ltmp5: // Block address taken
|
||||
; CHECK-NEXT: .LBB5_1: // %b2
|
||||
; CHECK-NEXT: .LBB5_1: // Block address taken
|
||||
; CHECK-NEXT: // %b2
|
||||
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: {
|
||||
; CHECK-NEXT: nop
|
||||
|
|
|
@ -132,7 +132,7 @@ body: |
|
|||
%14:intregs = COPY %10
|
||||
J2_loop0r %bb.3, %14, implicit-def $lc0, implicit-def $sa0, implicit-def $usr
|
||||
|
||||
bb.3.b2 (address-taken):
|
||||
bb.3.b2 (machine-block-address-taken):
|
||||
successors: %bb.3(0x7c000000), %bb.4(0x04000000)
|
||||
|
||||
%1:intregs = PHI %7, %bb.2, %5, %bb.3, post-instr-symbol <mcsymbol Stage-3_Cycle-0>
|
||||
|
|
|
@ -80,7 +80,7 @@ body: |
|
|||
%23:intregs = COPY %0
|
||||
J2_loop0r %bb.2, %23, implicit-def $lc0, implicit-def $sa0, implicit-def $usr
|
||||
|
||||
bb.2 (address-taken):
|
||||
bb.2 (machine-block-address-taken):
|
||||
successors: %bb.3, %bb.2
|
||||
|
||||
%3:intregs = PHI %2, %bb.1, %10, %bb.2
|
||||
|
|
|
@ -52,7 +52,7 @@ body: |
|
|||
%11:intregs = IMPLICIT_DEF
|
||||
J2_loop0i %bb.1, 6, implicit-def $lc0, implicit-def $sa0, implicit-def $usr
|
||||
|
||||
bb.1 (address-taken):
|
||||
bb.1 (machine-block-address-taken):
|
||||
successors: %bb.1, %bb.2
|
||||
|
||||
%0:intregs = PHI %11, %bb.0, %6, %bb.1
|
||||
|
|
|
@ -31,19 +31,19 @@ body: |
|
|||
# CHECK-LABEL: name: bar
|
||||
# CHECK: body:
|
||||
# CHECK-NEXT: bb.0.start (align 4):
|
||||
# CHECK: bb.1 (address-taken):
|
||||
# CHECK: bb.1 (machine-block-address-taken):
|
||||
name: bar
|
||||
body: |
|
||||
bb.0.start (align 4):
|
||||
bb.1 (address-taken):
|
||||
bb.1 (machine-block-address-taken):
|
||||
...
|
||||
---
|
||||
# CHECK-LABEL: name: test
|
||||
# CHECK: body:
|
||||
# CHECK-NEXT: bb.0.start (address-taken, align 4):
|
||||
# CHECK: bb.1 (address-taken, align 4):
|
||||
# CHECK-NEXT: bb.0.start (machine-block-address-taken, align 4):
|
||||
# CHECK: bb.1 (machine-block-address-taken, align 4):
|
||||
name: test
|
||||
body: |
|
||||
bb.0.start (align 4, address-taken):
|
||||
bb.1 (address-taken, align 4):
|
||||
bb.0.start (align 4, machine-block-address-taken):
|
||||
bb.1 (machine-block-address-taken, align 4):
|
||||
...
|
||||
|
|
|
@ -62,7 +62,7 @@ body: |
|
|||
MOV64mr $rip, 1, _, @addr, _, killed $rax
|
||||
JMP64m $rip, 1, _, @addr, _
|
||||
|
||||
bb.1.block (address-taken):
|
||||
bb.1.block (ir-block-address-taken %ir-block.block):
|
||||
RET64
|
||||
...
|
||||
---
|
||||
|
@ -76,7 +76,7 @@ body: |
|
|||
MOV64mr $rip, 1, _, @addr, _, killed $rax
|
||||
JMP64m $rip, 1, _, @addr, _
|
||||
|
||||
bb.1 (address-taken):
|
||||
bb.1 (%ir-block."quoted block", ir-block-address-taken %ir-block."quoted block"):
|
||||
RET64
|
||||
...
|
||||
---
|
||||
|
@ -103,7 +103,7 @@ body: |
|
|||
MOV64mr $rip, 1, _, @addr, _, killed $rax
|
||||
JMP64m $rip, 1, _, @addr, _
|
||||
|
||||
bb.1 (address-taken):
|
||||
bb.1 (%ir-block.0, ir-block-address-taken %ir-block.0):
|
||||
RET64
|
||||
...
|
||||
---
|
||||
|
@ -116,6 +116,6 @@ body: |
|
|||
MOV64mr $rip, 1, _, @addr, _, killed $rax
|
||||
JMP64m $rip, 1, _, @addr, _
|
||||
|
||||
bb.1.block (address-taken):
|
||||
bb.1.block (ir-block-address-taken %ir-block.block):
|
||||
RET64
|
||||
...
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# RUN: not llc -march=x86-64 -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
|
||||
#
|
||||
|
||||
--- |
|
||||
|
||||
|
@ -25,6 +26,6 @@ body: |
|
|||
MOV64mr $rip, 1, _, @addr, _, killed $rax
|
||||
JMP64m $rip, 1, _, @addr, _
|
||||
|
||||
bb.1.block (address-taken):
|
||||
bb.1.block (ir-block-address-taken %ir-block.block):
|
||||
RET64
|
||||
...
|
||||
|
|
|
@ -25,6 +25,6 @@ body: |
|
|||
MOV64mr $rip, 1, _, @addr, _, killed $rax
|
||||
JMP64m $rip, 1, _, @addr, _
|
||||
|
||||
bb.1.block (address-taken):
|
||||
bb.1.block:
|
||||
RET64
|
||||
...
|
||||
|
|
|
@ -25,6 +25,6 @@ body: |
|
|||
MOV64mr $rip, 1, _, @addr, _, killed $rax
|
||||
JMP64m $rip, 1, _, @addr, _
|
||||
|
||||
bb.1.block (address-taken):
|
||||
bb.1.block:
|
||||
RET64
|
||||
...
|
||||
|
|
|
@ -25,6 +25,6 @@ body: |
|
|||
MOV64mr $rip, 1, _, @addr, _, killed $rax
|
||||
JMP64m $rip, 1, _, @addr, _
|
||||
|
||||
bb.1.block (address-taken):
|
||||
bb.1.block (ir-block-address-taken %ir-block.block):
|
||||
RET64
|
||||
...
|
||||
|
|
|
@ -24,6 +24,6 @@ body: |
|
|||
MOV64mr $rip, 1, _, @addr, _, killed $rax
|
||||
JMP64m $rip, 1, _, @addr, _
|
||||
|
||||
bb.1 (address-taken):
|
||||
bb.1:
|
||||
RET64
|
||||
...
|
||||
|
|
|
@ -57,7 +57,7 @@ body: |
|
|||
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY killed $rdi
|
||||
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64 = COPY killed [[COPY1]]
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: bb.1.loop (address-taken, inlineasm-br-indirect-target):
|
||||
; CHECK-NEXT: bb.1.loop (ir-block-address-taken %ir-block.loop, inlineasm-br-indirect-target):
|
||||
; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000)
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr64 = COPY killed [[COPY2]]
|
||||
|
@ -78,7 +78,7 @@ body: |
|
|||
%3:gr64 = COPY killed $rsi
|
||||
%2:gr64 = COPY killed $rdi
|
||||
|
||||
bb.1.loop (address-taken, inlineasm-br-indirect-target):
|
||||
bb.1.loop (ir-block-address-taken %ir-block.loop, inlineasm-br-indirect-target):
|
||||
successors: %bb.2(0x80000000), %bb.1(0x00000000)
|
||||
|
||||
%0:gr64 = PHI %2, %bb.0, %1, %bb.1
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
|
||||
; Check the second INLINEASM_BR target block is preceded by the block with the
|
||||
; second INLINEASM_BR.
|
||||
; CHECK: bb.2 (%ir-block.7, address-taken, inlineasm-br-indirect-target):
|
||||
; CHECK: bb.2 (%ir-block.7, machine-block-address-taken, ir-block-address-taken %ir-block.7, inlineasm-br-indirect-target):
|
||||
; CHECK-NEXT: predecessors: %bb.1
|
||||
|
||||
; Check the first INLINEASM_BR target block is predecessed by the block with
|
||||
; the first INLINEASM_BR.
|
||||
; CHECK: bb.4 (%ir-block.11, address-taken, inlineasm-br-indirect-target):
|
||||
; CHECK: bb.4 (%ir-block.11, machine-block-address-taken, ir-block-address-taken %ir-block.11, inlineasm-br-indirect-target):
|
||||
; CHECK-NEXT: predecessors: %bb.0
|
||||
|
||||
@.str = private unnamed_addr constant [26 x i8] c"inline asm#1 returned %d\0A\00", align 1
|
||||
|
|
|
@ -38,7 +38,7 @@ define ptr @test1(ptr %arg1, ptr %arg2) {
|
|||
; CHECK-NEXT: INLINEASM_BR &"#$0 $1 $2", 9 /* sideeffect mayload attdialect */, 13 /* imm */, 42, 13 /* imm */, 0, 13 /* imm */, blockaddress(@test1, %ir-block.bb17.i.i.i), 12 /* clobber */, implicit-def early-clobber $df, 12 /* clobber */, implicit-def early-clobber $fpsw, 12 /* clobber */, implicit-def early-clobber $eflags
|
||||
; CHECK-NEXT: JMP_1 %bb.5
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: bb.4.bb17.i.i.i (address-taken, inlineasm-br-indirect-target):
|
||||
; CHECK-NEXT: bb.4.bb17.i.i.i (machine-block-address-taken, ir-block-address-taken %ir-block.bb17.i.i.i, inlineasm-br-indirect-target):
|
||||
; CHECK-NEXT: successors: %bb.5(0x80000000)
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: {{ $}}
|
||||
|
|
|
@ -168,7 +168,7 @@ body: |
|
|||
TEST8rr killed renamable $r8b, renamable $r8b, implicit-def $eflags
|
||||
JCC_1 %bb.6, 5, implicit $eflags
|
||||
|
||||
bb.8.return (address-taken):
|
||||
bb.8.return (machine-block-address-taken):
|
||||
$eax = MOV32rm $rbp, 1, $noreg, -12, $noreg :: (load (s32) from %stack.0)
|
||||
SEH_Epilogue
|
||||
$rsp = frame-destroy ADD64ri8 $rsp, 48, implicit-def dead $eflags
|
||||
|
|
|
@ -34,5 +34,5 @@ body: |
|
|||
RET64 $al, debug-location !10
|
||||
bb.1:
|
||||
successors:
|
||||
bb.25.if.else.i103.i (address-taken):
|
||||
bb.25.if.else.i103.i (machine-block-address-taken):
|
||||
JMP_1 %bb.28
|
||||
|
|
|
@ -29,4 +29,4 @@ body: |
|
|||
bb.2:
|
||||
successors:
|
||||
TRAP
|
||||
bb.21.do.body.i129.i (address-taken):
|
||||
bb.21.do.body.i129.i (machine-block-address-taken):
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# RESULT: bb.0.entry:
|
||||
# RESULT: %{{[0-9]+}}:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
|
||||
|
||||
# RESULT: bb.1 (address-taken, align 8):
|
||||
# RESULT: bb.1 (ir-block-address-taken %ir-block.exitblock, align 8):
|
||||
# RESULT: bb.2 (landing-pad, align 16):
|
||||
# RESULT: bb.3 (inlineasm-br-indirect-target):
|
||||
# RESULT: bb.4 (ehfunclet-entry):
|
||||
|
@ -19,6 +19,7 @@
|
|||
# RESULT-NEXT: successors: %bb.9(0x66666666), %bb.10(0x1999999a)
|
||||
# RESULT: bb.9:
|
||||
# RESULT: bb.10.exitblock:
|
||||
# RESULT: bb.11 (machine-block-address-taken):
|
||||
|
||||
--- |
|
||||
define void @func(i32 %size) {
|
||||
|
@ -48,7 +49,7 @@ body: |
|
|||
S_NOP 0
|
||||
%0:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
|
||||
|
||||
bb.1 (address-taken, align 8):
|
||||
bb.1 (ir-block-address-taken %ir-block.exitblock, align 8):
|
||||
|
||||
bb.2 (landing-pad, align 16):
|
||||
|
||||
|
@ -69,4 +70,6 @@ body: |
|
|||
|
||||
bb.10.exitblock:
|
||||
S_ENDPGM 0, implicit %0
|
||||
|
||||
bb.11 (machine-block-address-taken):
|
||||
...
|
||||
|
|
|
@ -206,8 +206,10 @@ static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF,
|
|||
DstMF->CreateMachineBasicBlock(SrcMBB.getBasicBlock());
|
||||
Src2DstMBB[&SrcMBB] = DstMBB;
|
||||
|
||||
if (SrcMBB.hasAddressTaken())
|
||||
DstMBB->setHasAddressTaken();
|
||||
if (SrcMBB.isIRBlockAddressTaken())
|
||||
DstMBB->setAddressTakenIRBlock(SrcMBB.getAddressTakenIRBlock());
|
||||
if (SrcMBB.isMachineBlockAddressTaken())
|
||||
DstMBB->setMachineBlockAddressTaken();
|
||||
|
||||
// FIXME: This is not serialized
|
||||
if (SrcMBB.hasLabelMustBeEmitted())
|
||||
|
|
Loading…
Reference in New Issue