Skip to content

Commit ab44621

Browse files
committed
[RemoveDIs][DebugInfo] Reject intrinsic->record upgrades for old-format modules
Fixes issue noted at: llvm#86274 When loading bitcode lazily, we may request debug intrinsics be upgraded to debug records during the module parsing phase; later on we perform this upgrade when materializing the module functions. If we change the module's debug info format between parsing and materializing however, then the requested upgrade is no longer correct and leads to an assertion. This patch fixes the issue by adding an extra check in the autoupgrader to see if the upgrade is no longer suitable, and either exit-out or fall back to the correct intrinsic->intrinsic upgrade if one is required. Adding this check in the autoupgrader is technically not optimal, since we could run the check a single time in a higher up call, but there's no way (that I can see) to do so without leaking through abstractions and making the bitcode/linking/materializing steps more complicated and brittle, and the check isn't particularly expensive.
1 parent 29c7d1a commit ab44621

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

llvm/include/llvm/IR/AutoUpgrade.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ namespace llvm {
3636
/// for upgrading, and returns true if it requires upgrading. It may return
3737
/// null in NewFn if the all calls to the original intrinsic function
3838
/// should be transformed to non-function-call instructions.
39-
bool UpgradeIntrinsicFunction(Function *F, Function *&NewFn);
39+
bool UpgradeIntrinsicFunction(Function *F, Function *&NewFn,
40+
bool CanUpgradeDebugIntrinsicsToRecords = true);
4041

4142
/// This is the complement to the above, replacing a specific call to an
4243
/// intrinsic function with a call to the specified new function.

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,8 @@ static Intrinsic::ID shouldUpgradeNVPTXBF16Intrinsic(StringRef Name) {
983983
return Intrinsic::not_intrinsic;
984984
}
985985

986-
static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
986+
static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn,
987+
bool CanUpgradeDebugIntrinsicsToRecords) {
987988
assert(F && "Illegal to upgrade a non-existent Function.");
988989

989990
StringRef Name = F->getName();
@@ -1057,7 +1058,8 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
10571058
case 'd':
10581059
if (Name.consume_front("dbg.")) {
10591060
// Mark debug intrinsics for upgrade to new debug format.
1060-
if (F->getParent()->IsNewDbgInfoFormat) {
1061+
if (CanUpgradeDebugIntrinsicsToRecords &&
1062+
F->getParent()->IsNewDbgInfoFormat) {
10611063
if (Name == "addr" || Name == "value" || Name == "assign" ||
10621064
Name == "declare" || Name == "label") {
10631065
// There's no function to replace these with.
@@ -1413,9 +1415,11 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
14131415
return false;
14141416
}
14151417

1416-
bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
1418+
bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn,
1419+
bool CanUpgradeDebugIntrinsicsToRecords) {
14171420
NewFn = nullptr;
1418-
bool Upgraded = upgradeIntrinsicFunction1(F, NewFn);
1421+
bool Upgraded =
1422+
upgradeIntrinsicFunction1(F, NewFn, CanUpgradeDebugIntrinsicsToRecords);
14191423
assert(F != NewFn && "Intrinsic function upgraded to the same function");
14201424

14211425
// Upgrade intrinsic attributes. This does not change the function.
@@ -2412,6 +2416,7 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
24122416
Builder.SetInsertPoint(CI->getParent(), CI->getIterator());
24132417

24142418
if (!NewFn) {
2419+
bool ShouldRemove = true;
24152420
// Get the Function's name.
24162421
StringRef Name = F->getName();
24172422

@@ -4262,16 +4267,28 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
42624267
Rep = upgradeARMIntrinsicCall(Name, CI, F, Builder);
42634268
} else if (IsAMDGCN) {
42644269
Rep = upgradeAMDGCNIntrinsicCall(Name, CI, F, Builder);
4265-
} else if (IsDbg && CI->getModule()->IsNewDbgInfoFormat) {
4266-
upgradeDbgIntrinsicToDbgRecord(Name, CI);
4270+
} else if (IsDbg) {
4271+
// We might have decided we don't want the new format after all since
4272+
// requesting the upgrade; skip the conversion if that is the case, and
4273+
// check here to see if the intrinsic needs to be upgraded normally.
4274+
if (!CI->getModule()->IsNewDbgInfoFormat) {
4275+
ShouldRemove = false;
4276+
bool NeedsUpgrade = upgradeIntrinsicFunction1(CI->getCalledFunction(), NewFn, false);
4277+
if (!NeedsUpgrade)
4278+
return;
4279+
} else {
4280+
upgradeDbgIntrinsicToDbgRecord(Name, CI);
4281+
}
42674282
} else {
42684283
llvm_unreachable("Unknown function for CallBase upgrade.");
42694284
}
42704285

42714286
if (Rep)
42724287
CI->replaceAllUsesWith(Rep);
4273-
CI->eraseFromParent();
4274-
return;
4288+
if (ShouldRemove) {
4289+
CI->eraseFromParent();
4290+
return;
4291+
}
42754292
}
42764293

42774294
const auto &DefaultCase = [&]() -> void {

0 commit comments

Comments
 (0)