Skip to content

Commit cfd2c5c

Browse files
committed
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
1 parent d9198f6 commit cfd2c5c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+237
-527
lines changed

llvm/include/llvm/CodeGen/MachineBasicBlock.h

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,13 @@ class MachineBasicBlock
143143
/// Indicate that this basic block is entered via an exception handler.
144144
bool IsEHPad = false;
145145

146-
/// Indicate that this basic block is potentially the target of an indirect
147-
/// branch.
148-
bool AddressTaken = false;
146+
/// Indicate that this MachineBasicBlock is referenced somewhere other than
147+
/// as predecessor/successor, a terminator MachineInstr, or a jump table.
148+
bool MachineBlockAddressTaken = false;
149+
150+
/// If this MachineBasicBlock corresponds to an IR-level "blockaddress"
151+
/// constant, this contains a pointer to that block.
152+
BasicBlock *AddressTakenIRBlock = nullptr;
149153

150154
/// Indicate that this basic block needs its symbol be emitted regardless of
151155
/// whether the flow just falls-through to it.
@@ -216,12 +220,35 @@ class MachineBasicBlock
216220
/// Return a formatted string to identify this block and its parent function.
217221
std::string getFullName() const;
218222

219-
/// Test whether this block is potentially the target of an indirect branch.
220-
bool hasAddressTaken() const { return AddressTaken; }
223+
/// Test whether this block is used as as something other than the target
224+
/// of a terminator, exception-handling target, or jump table. This is
225+
/// either the result of an IR-level "blockaddress", or some form
226+
/// of target-specific branch lowering.
227+
bool hasAddressTaken() const {
228+
return MachineBlockAddressTaken || AddressTakenIRBlock;
229+
}
230+
231+
/// Test whether this block is used as something other than the target of a
232+
/// terminator, exception-handling target, jump table, or IR blockaddress.
233+
/// For example, its address might be loaded into a register, or
234+
/// stored in some branch table that isn't part of MachineJumpTableInfo.
235+
bool isMachineBlockAddressTaken() const { return MachineBlockAddressTaken; }
236+
237+
/// Test whether this block is the target of an IR BlockAddress. (There can
238+
/// more than one MBB associated with an IR BB where the address is taken.)
239+
bool isIRBlockAddressTaken() const { return AddressTakenIRBlock; }
240+
241+
/// Retrieves the BasicBlock which corresponds to this MachineBasicBlock.
242+
BasicBlock *getAddressTakenIRBlock() const { return AddressTakenIRBlock; }
243+
244+
/// Set this block to indicate that its address is used as something other
245+
/// than the target of a terminator, exception-handling target, jump table,
246+
/// or IR-level "blockaddress".
247+
void setMachineBlockAddressTaken() { MachineBlockAddressTaken = true; }
221248

222-
/// Set this block to reflect that it potentially is the target of an indirect
223-
/// branch.
224-
void setHasAddressTaken() { AddressTaken = true; }
249+
/// Set this block to reflect that it corresponds to an IR-level basic block
250+
/// with a BlockAddress.
251+
void setAddressTakenIRBlock(BasicBlock *BB) { AddressTakenIRBlock = BB; }
225252

226253
/// Test whether this block must have its label emitted.
227254
bool hasLabelMustBeEmitted() const { return LabelMustBeEmitted; }

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3545,21 +3545,21 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
35453545
// reference the block. It is possible that there is more than one label
35463546
// here, because multiple LLVM BB's may have been RAUW'd to this block after
35473547
// the references were generated.
3548-
const BasicBlock *BB = MBB.getBasicBlock();
3549-
if (MBB.hasAddressTaken()) {
3548+
if (MBB.isIRBlockAddressTaken()) {
35503549
if (isVerbose())
35513550
OutStreamer->AddComment("Block address taken");
35523551

3553-
// MBBs can have their address taken as part of CodeGen without having
3554-
// their corresponding BB's address taken in IR
3555-
if (BB && BB->hasAddressTaken())
3556-
for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB))
3557-
OutStreamer->emitLabel(Sym);
3552+
BasicBlock *BB = MBB.getAddressTakenIRBlock();
3553+
assert(BB && BB->hasAddressTaken() && "Missing BB");
3554+
for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB))
3555+
OutStreamer->emitLabel(Sym);
3556+
} else if (isVerbose() && MBB.isMachineBlockAddressTaken()) {
3557+
OutStreamer->AddComment("Block address taken");
35583558
}
35593559

35603560
// Print some verbose block comments.
35613561
if (isVerbose()) {
3562-
if (BB) {
3562+
if (const BasicBlock *BB = MBB.getBasicBlock()) {
35633563
if (BB->hasName()) {
35643564
BB->printAsOperand(OutStreamer->getCommentOS(),
35653565
/*PrintType=*/false, BB->getModule());

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3437,7 +3437,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
34373437
MF->push_back(MBB);
34383438

34393439
if (BB.hasAddressTaken())
3440-
MBB->setHasAddressTaken();
3440+
MBB->setAddressTakenIRBlock(const_cast<BasicBlock *>(&BB));
34413441

34423442
if (!HasMustTailInVarArgFn)
34433443
HasMustTailInVarArgFn = checkForMustTailInVarArgFn(IsVarArg, BB);

llvm/lib/CodeGen/MIRParser/MILexer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
258258
.Case("call-entry", MIToken::kw_call_entry)
259259
.Case("custom", MIToken::kw_custom)
260260
.Case("liveout", MIToken::kw_liveout)
261-
.Case("address-taken", MIToken::kw_address_taken)
262261
.Case("landing-pad", MIToken::kw_landing_pad)
263262
.Case("inlineasm-br-indirect-target",
264263
MIToken::kw_inlineasm_br_indirect_target)
@@ -275,6 +274,8 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
275274
.Case("unknown-size", MIToken::kw_unknown_size)
276275
.Case("unknown-address", MIToken::kw_unknown_address)
277276
.Case("distinct", MIToken::kw_distinct)
277+
.Case("ir-block-address-taken", MIToken::kw_ir_block_address_taken)
278+
.Case("machine-block-address-taken", MIToken::kw_machine_block_address_taken)
278279
.Default(MIToken::Identifier);
279280
}
280281

llvm/lib/CodeGen/MIRParser/MILexer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ struct MIToken {
114114
kw_call_entry,
115115
kw_custom,
116116
kw_liveout,
117-
kw_address_taken,
118117
kw_landing_pad,
119118
kw_inlineasm_br_indirect_target,
120119
kw_ehfunclet_entry,
@@ -129,6 +128,8 @@ struct MIToken {
129128
kw_bbsections,
130129
kw_unknown_size,
131130
kw_unknown_address,
131+
kw_ir_block_address_taken,
132+
kw_machine_block_address_taken,
132133

133134
// Metadata types.
134135
kw_distinct,

llvm/lib/CodeGen/MIRParser/MIParser.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ class MIParser {
495495
MachineOperand &Dest,
496496
Optional<unsigned> &TiedDefIdx);
497497
bool parseOffset(int64_t &Offset);
498+
bool parseIRBlockAddressTaken(BasicBlock *&BB);
498499
bool parseAlignment(uint64_t &Alignment);
499500
bool parseAddrspace(unsigned &Addrspace);
500501
bool parseSectionID(Optional<MBBSectionID> &SID);
@@ -669,7 +670,8 @@ bool MIParser::parseBasicBlockDefinition(
669670
auto Loc = Token.location();
670671
auto Name = Token.stringValue();
671672
lex();
672-
bool HasAddressTaken = false;
673+
bool MachineBlockAddressTaken = false;
674+
BasicBlock *AddressTakenIRBlock = nullptr;
673675
bool IsLandingPad = false;
674676
bool IsInlineAsmBrIndirectTarget = false;
675677
bool IsEHFuncletEntry = false;
@@ -680,10 +682,14 @@ bool MIParser::parseBasicBlockDefinition(
680682
do {
681683
// TODO: Report an error when multiple same attributes are specified.
682684
switch (Token.kind()) {
683-
case MIToken::kw_address_taken:
684-
HasAddressTaken = true;
685+
case MIToken::kw_machine_block_address_taken:
686+
MachineBlockAddressTaken = true;
685687
lex();
686688
break;
689+
case MIToken::kw_ir_block_address_taken:
690+
if (parseIRBlockAddressTaken(AddressTakenIRBlock))
691+
return true;
692+
break;
687693
case MIToken::kw_landing_pad:
688694
IsLandingPad = true;
689695
lex();
@@ -701,6 +707,7 @@ bool MIParser::parseBasicBlockDefinition(
701707
return true;
702708
break;
703709
case MIToken::IRBlock:
710+
case MIToken::NamedIRBlock:
704711
// TODO: Report an error when both name and ir block are specified.
705712
if (parseIRBlock(BB, MF.getFunction()))
706713
return true;
@@ -736,8 +743,10 @@ bool MIParser::parseBasicBlockDefinition(
736743
Twine(ID));
737744
if (Alignment)
738745
MBB->setAlignment(Align(Alignment));
739-
if (HasAddressTaken)
740-
MBB->setHasAddressTaken();
746+
if (MachineBlockAddressTaken)
747+
MBB->setMachineBlockAddressTaken();
748+
if (AddressTakenIRBlock)
749+
MBB->setAddressTakenIRBlock(AddressTakenIRBlock);
741750
MBB->setIsEHPad(IsLandingPad);
742751
MBB->setIsInlineAsmBrIndirectTarget(IsInlineAsmBrIndirectTarget);
743752
MBB->setIsEHFuncletEntry(IsEHFuncletEntry);
@@ -2918,6 +2927,19 @@ bool MIParser::parseOffset(int64_t &Offset) {
29182927
return false;
29192928
}
29202929

2930+
bool MIParser::parseIRBlockAddressTaken(BasicBlock *&BB) {
2931+
assert(Token.is(MIToken::kw_ir_block_address_taken));
2932+
lex();
2933+
if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
2934+
return error("expected basic block after 'ir_block_address_taken'");
2935+
2936+
if (parseIRBlock(BB, MF.getFunction()))
2937+
return true;
2938+
2939+
lex();
2940+
return false;
2941+
}
2942+
29212943
bool MIParser::parseAlignment(uint64_t &Alignment) {
29222944
assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign));
29232945
lex();

llvm/lib/CodeGen/MachineBasicBlock.cpp

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -476,36 +476,50 @@ void MachineBasicBlock::printName(raw_ostream &os, unsigned printNameFlags,
476476
os << "bb." << getNumber();
477477
bool hasAttributes = false;
478478

479+
auto PrintBBRef = [&](const BasicBlock *bb) {
480+
os << "%ir-block.";
481+
if (bb->hasName()) {
482+
os << bb->getName();
483+
} else {
484+
int slot = -1;
485+
486+
if (moduleSlotTracker) {
487+
slot = moduleSlotTracker->getLocalSlot(bb);
488+
} else if (bb->getParent()) {
489+
ModuleSlotTracker tmpTracker(bb->getModule(), false);
490+
tmpTracker.incorporateFunction(*bb->getParent());
491+
slot = tmpTracker.getLocalSlot(bb);
492+
}
493+
494+
if (slot == -1)
495+
os << "<ir-block badref>";
496+
else
497+
os << slot;
498+
}
499+
};
500+
479501
if (printNameFlags & PrintNameIr) {
480502
if (const auto *bb = getBasicBlock()) {
481503
if (bb->hasName()) {
482504
os << '.' << bb->getName();
483505
} else {
484506
hasAttributes = true;
485507
os << " (";
486-
487-
int slot = -1;
488-
489-
if (moduleSlotTracker) {
490-
slot = moduleSlotTracker->getLocalSlot(bb);
491-
} else if (bb->getParent()) {
492-
ModuleSlotTracker tmpTracker(bb->getModule(), false);
493-
tmpTracker.incorporateFunction(*bb->getParent());
494-
slot = tmpTracker.getLocalSlot(bb);
495-
}
496-
497-
if (slot == -1)
498-
os << "<ir-block badref>";
499-
else
500-
os << (Twine("%ir-block.") + Twine(slot)).str();
508+
PrintBBRef(bb);
501509
}
502510
}
503511
}
504512

505513
if (printNameFlags & PrintNameAttributes) {
506-
if (hasAddressTaken()) {
514+
if (isMachineBlockAddressTaken()) {
515+
os << (hasAttributes ? ", " : " (");
516+
os << "machine-block-address-taken";
517+
hasAttributes = true;
518+
}
519+
if (isIRBlockAddressTaken()) {
507520
os << (hasAttributes ? ", " : " (");
508-
os << "address-taken";
521+
os << "ir-block-address-taken ";
522+
PrintBBRef(getAddressTakenIRBlock());
509523
hasAttributes = true;
510524
}
511525
if (isEHPad()) {

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,13 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
632632
}
633633
}
634634

635+
if (MBB->isIRBlockAddressTaken()) {
636+
if (!MBB->getAddressTakenIRBlock()->hasAddressTaken())
637+
report("ir-block-address-taken is associated with basic block not used by "
638+
"a blockaddress.",
639+
MBB);
640+
}
641+
635642
// Count the number of landing pad successors.
636643
SmallPtrSet<const MachineBasicBlock*, 4> LandingPadSuccs;
637644
for (const auto *succ : MBB->successors()) {

llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
270270
// be multiple MachineBasicBlocks corresponding to one BasicBlock, and only
271271
// the first one should be marked.
272272
if (BB.hasAddressTaken())
273-
MBB->setHasAddressTaken();
273+
MBB->setAddressTakenIRBlock(const_cast<BasicBlock *>(&BB));
274274

275275
// Mark landing pad blocks.
276276
if (BB.isEHPad())

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3007,7 +3007,7 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) {
30073007
BasicBlock *Dest = I.getIndirectDest(i);
30083008
MachineBasicBlock *Target = FuncInfo.MBBMap[Dest];
30093009
Target->setIsInlineAsmBrIndirectTarget();
3010-
Target->setHasAddressTaken();
3010+
Target->setMachineBlockAddressTaken();
30113011
// Don't add duplicate machine successors.
30123012
if (Dests.insert(Dest).second)
30133013
addSuccessorWithProb(CallBrMBB, Target, BranchProbability::getZero());

llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,13 +1263,8 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L,
12631263
.addMBB(LoopStart).addImm(CountImm);
12641264
}
12651265

1266-
// Make sure the loop start always has a reference in the CFG. We need
1267-
// to create a BlockAddress operand to get this mechanism to work both the
1268-
// MachineBasicBlock and BasicBlock objects need the flag set.
1269-
LoopStart->setHasAddressTaken();
1270-
// This line is needed to set the hasAddressTaken flag on the BasicBlock
1271-
// object.
1272-
BlockAddress::get(const_cast<BasicBlock *>(LoopStart->getBasicBlock()));
1266+
// Make sure the loop start always has a reference in the CFG.
1267+
LoopStart->setMachineBlockAddressTaken();
12731268

12741269
// Replace the loop branch with an endloop instruction.
12751270
DebugLoc LastIDL = LastI->getDebugLoc();

llvm/lib/Target/VE/VEISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2214,7 +2214,7 @@ VETargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
22142214
MF->insert(I, MainMBB);
22152215
MF->insert(I, SinkMBB);
22162216
MF->push_back(RestoreMBB);
2217-
RestoreMBB->setHasAddressTaken();
2217+
RestoreMBB->setMachineBlockAddressTaken();
22182218

22192219
// Transfer the remainder of BB and its successor edges to SinkMBB.
22202220
SinkMBB->splice(SinkMBB->begin(), MBB,

llvm/lib/Target/X86/X86FrameLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2777,7 +2777,7 @@ void X86FrameLowering::emitCatchRetReturnValue(MachineBasicBlock &MBB,
27772777

27782778
// Record that we've taken the address of CatchRetTarget and no longer just
27792779
// reference it in a terminator.
2780-
CatchRetTarget->setHasAddressTaken();
2780+
CatchRetTarget->setMachineBlockAddressTaken();
27812781
}
27822782

27832783
bool X86FrameLowering::restoreCalleeSavedRegisters(

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35640,7 +35640,7 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
3564035640
MF->insert(I, mainMBB);
3564135641
MF->insert(I, sinkMBB);
3564235642
MF->push_back(restoreMBB);
35643-
restoreMBB->setHasAddressTaken();
35643+
restoreMBB->setMachineBlockAddressTaken();
3564435644

3564535645
MachineInstrBuilder MIB;
3564635646

llvm/lib/Target/X86/X86IndirectThunks.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,11 @@ void RetpolineThunkInserter::populateThunk(MachineFunction &MF) {
234234
BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::PAUSE));
235235
BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::LFENCE));
236236
BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::JMP_1)).addMBB(CaptureSpec);
237-
CaptureSpec->setHasAddressTaken();
237+
CaptureSpec->setMachineBlockAddressTaken();
238238
CaptureSpec->addSuccessor(CaptureSpec);
239239

240240
CallTarget->addLiveIn(ThunkReg);
241-
CallTarget->setHasAddressTaken();
241+
CallTarget->setMachineBlockAddressTaken();
242242
CallTarget->setAlignment(Align(16));
243243

244244
// Insert return address clobber

llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ X86SpeculativeLoadHardeningPass::tracePredStateThroughIndirectBranches(
11451145
// Insert a comparison of the incoming target register with this block's
11461146
// address. This also requires us to mark the block as having its address
11471147
// taken explicitly.
1148-
MBB.setHasAddressTaken();
1148+
MBB.setMachineBlockAddressTaken();
11491149
auto InsertPt = MBB.SkipPHIsLabelsAndDebug(MBB.begin());
11501150
if (MF.getTarget().getCodeModel() == CodeModel::Small &&
11511151
!Subtarget->isPositionIndependent()) {

llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,13 @@ false:
137137
; CHECK-NEXT: successors: %[[BB_L1:bb.[0-9]+]](0x80000000)
138138
;
139139
; Check basic block L1 has 2 successors: BBL1 and BBL2
140-
; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (address-taken):
140+
; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (ir-block-address-taken %ir-block.{{[a-zA-Z0-9.]+}}):
141141
; CHECK-NEXT: successors: %[[BB_L1]](0x40000000),
142142
; CHECK: %[[BB_L2:bb.[0-9]+]](0x40000000)
143143
; CHECK: G_BRINDIRECT %{{[0-9]+}}(p0)
144144
;
145145
; Check basic block L2 is the return basic block
146-
; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (address-taken):
146+
; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (ir-block-address-taken %ir-block.{{[a-zA-Z0-9.]+}}):
147147
; CHECK-NEXT: RET_ReallyLR
148148

149149
@indirectbr.L = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@indirectbr, %L1), i8* blockaddress(@indirectbr, %L2), i8* null], align 8

0 commit comments

Comments
 (0)