Skip to content

Commit 9a05a89

Browse files
[speculative-execution] Hoists debug values unnecessarily. (#85782)
After https://reviews.llvm.org/D81730: `SpeculativeExecutionPass::considerHoistingFromTo` hoists instructions, including debug intrinsics, as long as none of their used values are instructions that appear prior in the block that are not being hoisted. This behaviour has been duplicated for DPValues to get rid of a binary difference. The correct solution is not hoist these debug values at all, whichever format they're in.
1 parent a88a4da commit 9a05a89

File tree

2 files changed

+25
-28
lines changed

2 files changed

+25
-28
lines changed

llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,31 @@ static InstructionCost ComputeSpeculationCost(const Instruction *I,
260260
}
261261
}
262262

263+
// Do not hoist any debug info intrinsics.
264+
// ...
265+
// if (cond) {
266+
// x = y * z;
267+
// foo();
268+
// }
269+
// ...
270+
// -------- Which then becomes:
271+
// ...
272+
// if.then:
273+
// %x = mul i32 %y, %z
274+
// call void @llvm.dbg.value(%x, !"x", !DIExpression())
275+
// call void foo()
276+
//
277+
// SpeculativeExecution might decide to hoist the 'y * z' calculation
278+
// out of the 'if' block, because it is more efficient that way, so the
279+
// '%x = mul i32 %y, %z' moves to the block above. But it might also
280+
// decide to hoist the 'llvm.dbg.value' call.
281+
// This is incorrect, because even if we've moved the calculation of
282+
// 'y * z', we should not see the value of 'x' change unless we
283+
// actually go inside the 'if' block.
284+
263285
bool SpeculativeExecutionPass::considerHoistingFromTo(
264286
BasicBlock &FromBlock, BasicBlock &ToBlock) {
265287
SmallPtrSet<const Instruction *, 8> NotHoisted;
266-
SmallDenseMap<const Instruction *, SmallVector<DbgVariableRecord *>>
267-
DbgVariableRecordsToHoist;
268288
auto HasNoUnhoistedInstr = [&NotHoisted](auto Values) {
269289
for (const Value *V : Values) {
270290
if (const auto *I = dyn_cast_or_null<Instruction>(V))
@@ -275,15 +295,8 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
275295
};
276296
auto AllPrecedingUsesFromBlockHoisted =
277297
[&HasNoUnhoistedInstr](const User *U) {
278-
// Debug variable has special operand to check it's not hoisted.
279-
if (const auto *DVI = dyn_cast<DbgVariableIntrinsic>(U))
280-
return HasNoUnhoistedInstr(DVI->location_ops());
281-
282-
// Usially debug label intrinsic corresponds to label in LLVM IR. In
283-
// these cases we should not move it here.
284-
// TODO: Possible special processing needed to detect it is related to a
285-
// hoisted instruction.
286-
if (isa<DbgLabelInst>(U))
298+
// Do not hoist any debug info intrinsics.
299+
if (isa<DbgInfoIntrinsic>(U))
287300
return false;
288301

289302
return HasNoUnhoistedInstr(U->operand_values());
@@ -292,12 +305,6 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
292305
InstructionCost TotalSpeculationCost = 0;
293306
unsigned NotHoistedInstCount = 0;
294307
for (const auto &I : FromBlock) {
295-
// Make note of any DbgVariableRecords that need hoisting. DbgLabelRecords
296-
// get left behind just like llvm.dbg.labels.
297-
for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
298-
if (HasNoUnhoistedInstr(DVR.location_ops()))
299-
DbgVariableRecordsToHoist[DVR.getInstruction()].push_back(&DVR);
300-
}
301308
const InstructionCost Cost = ComputeSpeculationCost(&I, *TTI);
302309
if (Cost.isValid() && isSafeToSpeculativelyExecute(&I) &&
303310
AllPrecedingUsesFromBlockHoisted(&I)) {
@@ -315,16 +322,6 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
315322
}
316323

317324
for (auto I = FromBlock.begin(); I != FromBlock.end();) {
318-
// If any DbgVariableRecords attached to this instruction should be hoisted,
319-
// hoist them now - they will end up attached to either the next hoisted
320-
// instruction or the ToBlock terminator.
321-
if (DbgVariableRecordsToHoist.contains(&*I)) {
322-
for (auto *DVR : DbgVariableRecordsToHoist[&*I]) {
323-
DVR->removeFromParent();
324-
ToBlock.insertDbgRecordBefore(DVR,
325-
ToBlock.getTerminator()->getIterator());
326-
}
327-
}
328325
// We have to increment I before moving Current as moving Current
329326
// changes the list that I is iterating through.
330327
auto Current = I;

llvm/test/Transforms/SpeculativeExecution/PR46267.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ define void @f(i32 %i) {
3131
entry:
3232
; CHECK-LABEL: @f(
3333
; CHECK: %a2 = add i32 %i, 0
34-
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %a2
3534
br i1 undef, label %land.rhs, label %land.end
3635

3736
land.rhs: ; preds = %entry
@@ -42,6 +41,7 @@ land.rhs: ; preds = %entry
4241
; CHECK-NEXT: %a0 = load i32, ptr undef, align 1
4342
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %a0
4443
; CHECK-NEXT: call void @llvm.dbg.label
44+
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %a2
4545
call void @llvm.dbg.label(metadata !11), !dbg !10
4646
%y = alloca i32, align 4
4747
call void @llvm.dbg.declare(metadata ptr %y, metadata !14, metadata !DIExpression()), !dbg !10

0 commit comments

Comments
 (0)