mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 21:53:12 +08:00
Revert "[indvars] Missing variables at Og: (#69920)"
This reverts commit 739fa1c84b.
This introduces a layering violation by using IR in Support headers.
This commit is contained in:
@@ -44,8 +44,6 @@
|
||||
#include "llvm/ADT/PostOrderIterator.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SetOperations.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/GenericDomTree.h"
|
||||
|
||||
@@ -77,13 +75,6 @@ template <class BlockT, class LoopT> class LoopBase {
|
||||
const LoopBase<BlockT, LoopT> &
|
||||
operator=(const LoopBase<BlockT, LoopT> &) = delete;
|
||||
|
||||
// Induction variable exit value and its debug users, preserved by the
|
||||
// 'indvars' pass, when it detects that the loop can be deleted and the
|
||||
// there are no PHIs to be rewritten.
|
||||
// For now, we only preserve single induction variables.
|
||||
Value *IndVarFinalValue = nullptr;
|
||||
SmallVector<WeakVH> IndVarDebugUsers;
|
||||
|
||||
public:
|
||||
/// Return the nesting level of this loop. An outer-most loop has depth 1,
|
||||
/// for consistency with loop depth values used for basic blocks, where depth
|
||||
@@ -260,21 +251,6 @@ public:
|
||||
[&](BlockT *Pred) { return contains(Pred); });
|
||||
}
|
||||
|
||||
/// Preserve the induction variable exit value and its debug users by the
|
||||
/// 'indvars' pass if the loop can deleted. Those debug users will be used
|
||||
/// by the 'loop-delete' pass.
|
||||
void preserveDebugInductionVariableInfo(
|
||||
Value *FinalValue, SmallVector<DbgVariableIntrinsic *> DbgUsers) {
|
||||
IndVarFinalValue = FinalValue;
|
||||
for (DbgVariableIntrinsic *DebugUser : DbgUsers)
|
||||
IndVarDebugUsers.push_back(DebugUser);
|
||||
}
|
||||
|
||||
Value *getDebugInductionVariableFinalValue() { return IndVarFinalValue; }
|
||||
SmallVector<WeakVH> &getDebugInductionVariableDebugUsers() {
|
||||
return IndVarDebugUsers;
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// APIs for simple analysis of the loop.
|
||||
//
|
||||
|
||||
@@ -468,12 +468,6 @@ int rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI,
|
||||
ReplaceExitVal ReplaceExitValue,
|
||||
SmallVector<WeakTrackingVH, 16> &DeadInsts);
|
||||
|
||||
/// Assign exit values to variables that use this loop variable during the loop.
|
||||
void addDebugValuesToIncomingValue(BasicBlock *Successor, Value *IndVar,
|
||||
PHINode *PN);
|
||||
void addDebugValuesToLoopVariable(BasicBlock *Successor, Value *ExitValue,
|
||||
PHINode *PN);
|
||||
|
||||
/// Set weights for \p UnrolledLoop and \p RemainderLoop based on weights for
|
||||
/// \p OrigLoop and the following distribution of \p OrigLoop iteration among \p
|
||||
/// UnrolledLoop and \p RemainderLoop. \p UnrolledLoop receives weights that
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/IR/DIBuilder.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
@@ -609,17 +608,6 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
|
||||
llvm::SmallVector<DbgVariableRecord *, 4> DeadDbgVariableRecords;
|
||||
|
||||
if (ExitBlock) {
|
||||
if (ExitBlock->phis().empty()) {
|
||||
// As the loop is deleted, replace the debug users with the preserved
|
||||
// induction variable final value recorded by the 'indvar' pass.
|
||||
Value *FinalValue = L->getDebugInductionVariableFinalValue();
|
||||
SmallVector<WeakVH> &DbgUsers = L->getDebugInductionVariableDebugUsers();
|
||||
for (WeakVH &DebugUser : DbgUsers)
|
||||
if (DebugUser)
|
||||
cast<DbgVariableIntrinsic>(DebugUser)->replaceVariableLocationOp(
|
||||
0u, FinalValue);
|
||||
}
|
||||
|
||||
// Given LCSSA form is satisfied, we should not have users of instructions
|
||||
// within the dead loop outside of the loop. However, LCSSA doesn't take
|
||||
// unreachable uses into account. We handle them here.
|
||||
@@ -1413,36 +1401,6 @@ static bool checkIsIndPhi(PHINode *Phi, Loop *L, ScalarEvolution *SE,
|
||||
return InductionDescriptor::isInductionPHI(Phi, L, SE, ID);
|
||||
}
|
||||
|
||||
void llvm::addDebugValuesToIncomingValue(BasicBlock *Successor, Value *IndVar,
|
||||
PHINode *PN) {
|
||||
SmallVector<DbgVariableIntrinsic *> DbgUsers;
|
||||
findDbgUsers(DbgUsers, IndVar);
|
||||
for (auto *DebugUser : DbgUsers) {
|
||||
// Skip debug-users with variadic variable locations; they will not,
|
||||
// get updated, which is fine as that is the existing behaviour.
|
||||
if (DebugUser->hasArgList())
|
||||
continue;
|
||||
auto *Cloned = cast<DbgVariableIntrinsic>(DebugUser->clone());
|
||||
Cloned->replaceVariableLocationOp(0u, PN);
|
||||
Cloned->insertBefore(*Successor, Successor->getFirstNonPHIIt());
|
||||
}
|
||||
}
|
||||
|
||||
void llvm::addDebugValuesToLoopVariable(BasicBlock *Successor, Value *ExitValue,
|
||||
PHINode *PN) {
|
||||
SmallVector<DbgVariableIntrinsic *> DbgUsers;
|
||||
findDbgUsers(DbgUsers, PN);
|
||||
for (auto *DebugUser : DbgUsers) {
|
||||
// Skip debug-users with variadic variable locations; they will not,
|
||||
// get updated, which is fine as that is the existing behaviour.
|
||||
if (DebugUser->hasArgList())
|
||||
continue;
|
||||
auto *Cloned = cast<DbgVariableIntrinsic>(DebugUser->clone());
|
||||
Cloned->replaceVariableLocationOp(0u, ExitValue);
|
||||
Cloned->insertBefore(*Successor, Successor->getFirstNonPHIIt());
|
||||
}
|
||||
}
|
||||
|
||||
int llvm::rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI,
|
||||
ScalarEvolution *SE,
|
||||
const TargetTransformInfo *TTI,
|
||||
@@ -1584,10 +1542,6 @@ int llvm::rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI,
|
||||
(isa<PHINode>(Inst) || isa<LandingPadInst>(Inst)) ?
|
||||
&*Inst->getParent()->getFirstInsertionPt() : Inst;
|
||||
RewritePhiSet.emplace_back(PN, i, ExitValue, InsertPt, HighCost);
|
||||
|
||||
// Add debug values for the candidate PHINode incoming value.
|
||||
if (BasicBlock *Successor = ExitBB->getSingleSuccessor())
|
||||
addDebugValuesToIncomingValue(Successor, PN->getIncomingValue(i), PN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1646,30 +1600,11 @@ int llvm::rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI,
|
||||
// Replace PN with ExitVal if that is legal and does not break LCSSA.
|
||||
if (PN->getNumIncomingValues() == 1 &&
|
||||
LI->replacementPreservesLCSSAForm(PN, ExitVal)) {
|
||||
addDebugValuesToLoopVariable(PN->getParent(), ExitVal, PN);
|
||||
PN->replaceAllUsesWith(ExitVal);
|
||||
PN->eraseFromParent();
|
||||
}
|
||||
}
|
||||
|
||||
// If the loop can be deleted and there are no PHIs to be rewritten (there
|
||||
// are no loop live-out values), record debug variables corresponding to the
|
||||
// induction variable with their constant exit-values. Those values will be
|
||||
// inserted by the 'deletion loop' logic.
|
||||
if (LoopCanBeDel && RewritePhiSet.empty()) {
|
||||
if (auto *IndVar = L->getInductionVariable(*SE)) {
|
||||
const SCEV *PNSCEV = SE->getSCEVAtScope(IndVar, L->getParentLoop());
|
||||
if (auto *Const = dyn_cast<SCEVConstant>(PNSCEV)) {
|
||||
Value *FinalIVValue = Const->getValue();
|
||||
if (L->getUniqueExitBlock()) {
|
||||
SmallVector<DbgVariableIntrinsic *> DbgUsers;
|
||||
findDbgUsers(DbgUsers, IndVar);
|
||||
L->preserveDebugInductionVariableInfo(FinalIVValue, DbgUsers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The insertion point instruction may have been deleted; clear it out
|
||||
// so that the rewriter doesn't trip over it later.
|
||||
Rewriter.clearInsertPoint();
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
; RUN: opt -passes="loop(indvars)" \
|
||||
; RUN: --experimental-debuginfo-iterators=false -S -o - < %s | \
|
||||
; RUN: FileCheck --check-prefix=CHECK %s
|
||||
; RUN: opt -passes="loop(indvars,loop-deletion)" \
|
||||
; RUN: --experimental-debuginfo-iterators=false -S -o - < %s | \
|
||||
; RUN: FileCheck --check-prefix=CHECK %s
|
||||
|
||||
; Make sure that when we delete the loop, that the variable Index has
|
||||
; the 777 value.
|
||||
|
||||
; As this test case does fire the 'indvars' transformation, the debug values
|
||||
; are added to the 'for.end' exit block. No debug values are preserved by the
|
||||
; pass to be used by the 'loop-deletion' pass.
|
||||
|
||||
; CHECK: for.cond:
|
||||
; CHECK: call void @llvm.dbg.value(metadata i32 %[[SSA_INDEX_0:.+]], metadata ![[DBG:[0-9]+]], {{.*}}
|
||||
|
||||
; CHECK: for.extra:
|
||||
; CHECK: %[[SSA_CALL_0:.+]] = call noundef i32 @"?nop@@YAHH@Z"(i32 noundef %[[SSA_INDEX_0]]), {{.*}}
|
||||
; CHECK: br i1 %[[SSA_CMP_0:.+]], label %for.cond, label %if.else, {{.*}}
|
||||
|
||||
; CHECK: if.then:
|
||||
; CHECK: call void @llvm.dbg.value(metadata i32 777, metadata ![[DBG]], {{.*}}
|
||||
; CHECK: call void @llvm.dbg.value(metadata i32 %[[SSA_VAR_1:.+]], metadata ![[VAR:[0-9]+]], {{.*}}
|
||||
; CHECK: br label %for.end, {{.*}}
|
||||
|
||||
; CHECK: if.else:
|
||||
; CHECK: call void @llvm.dbg.value(metadata i32 %[[SSA_VAR_2:.+]], metadata ![[VAR:[0-9]+]], {{.*}}
|
||||
; CHECK: br label %for.end, {{.*}}
|
||||
|
||||
; CHECK: for.end:
|
||||
; CHECK: call void @llvm.dbg.value(metadata i32 777, metadata ![[DBG]], {{.*}}
|
||||
|
||||
; CHECK-DAG: ![[DBG]] = !DILocalVariable(name: "Index"{{.*}})
|
||||
; CHECK-DAG: ![[VAR]] = !DILocalVariable(name: "Var"{{.*}})
|
||||
|
||||
define dso_local noundef i32 @"?nop@@YAHH@Z"(i32 noundef %Param) !dbg !11 {
|
||||
entry:
|
||||
%Param.addr = alloca i32, align 4
|
||||
store i32 %Param, ptr %Param.addr, align 4
|
||||
call void @llvm.dbg.declare(metadata ptr %Param.addr, metadata !32, metadata !DIExpression()), !dbg !35
|
||||
ret i32 0, !dbg !36
|
||||
}
|
||||
|
||||
define dso_local void @_Z3barv() local_unnamed_addr #1 !dbg !12 {
|
||||
entry:
|
||||
call void @llvm.dbg.value(metadata i32 777, metadata !16, metadata !DIExpression()), !dbg !17
|
||||
call void @llvm.dbg.value(metadata i32 27, metadata !18, metadata !DIExpression()), !dbg !17
|
||||
call void @llvm.dbg.value(metadata i32 1, metadata !19, metadata !DIExpression()), !dbg !17
|
||||
call void @llvm.dbg.value(metadata i32 1, metadata !30, metadata !DIExpression()), !dbg !17
|
||||
br label %for.cond, !dbg !20
|
||||
|
||||
for.cond: ; preds = %for.cond, %entry
|
||||
%Index.0 = phi i32 [ 27, %entry ], [ %inc, %for.extra ], !dbg !17
|
||||
call void @llvm.dbg.value(metadata i32 %Index.0, metadata !18, metadata !DIExpression()), !dbg !17
|
||||
%cmp = icmp ult i32 %Index.0, 777, !dbg !21
|
||||
%inc = add nuw nsw i32 %Index.0, 1, !dbg !24
|
||||
call void @llvm.dbg.value(metadata i32 %inc, metadata !18, metadata !DIExpression()), !dbg !17
|
||||
br i1 %cmp, label %for.extra, label %if.then, !dbg !25, !llvm.loop !26
|
||||
|
||||
for.extra:
|
||||
%call.0 = call noundef i32 @"?nop@@YAHH@Z"(i32 noundef %Index.0), !dbg !21
|
||||
%cmp.0 = icmp ult i32 %Index.0, %call.0, !dbg !21
|
||||
br i1 %cmp.0, label %for.cond, label %if.else, !dbg !25, !llvm.loop !26
|
||||
|
||||
if.then: ; preds = %for.cond
|
||||
%Var.1 = add nsw i32 %Index.0, 1, !dbg !20
|
||||
call void @llvm.dbg.value(metadata i32 %Var.1, metadata !19, metadata !DIExpression()), !dbg !20
|
||||
br label %for.end, !dbg !20
|
||||
|
||||
if.else:
|
||||
%Var.2 = add nsw i32 %Index.0, 2, !dbg !20
|
||||
call void @llvm.dbg.value(metadata i32 %Var.2, metadata !19, metadata !DIExpression()), !dbg !20
|
||||
br label %for.end, !dbg !20
|
||||
|
||||
for.end: ; preds = %if.else, %if.then
|
||||
%Zeta.0 = phi i32 [ %Var.1, %if.then ], [ %Var.2, %if.else ], !dbg !20
|
||||
call void @llvm.dbg.value(metadata i32 %Zeta.0, metadata !30, metadata !DIExpression()), !dbg !20
|
||||
%Var.3 = add nsw i32 %Index.0, 1, !dbg !20
|
||||
call void @llvm.dbg.value(metadata i32 %Var.3, metadata !19, metadata !DIExpression()), !dbg !20
|
||||
%call = call noundef i32 @"?nop@@YAHH@Z"(i32 noundef %Index.0), !dbg !37
|
||||
ret void, !dbg !29
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.value(metadata, metadata, metadata)
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
|
||||
!llvm.ident = !{!9}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
|
||||
!1 = !DIFile(filename: "test.cpp", directory: "")
|
||||
!2 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!4 = !{i32 1, !"wchar_size", i32 4}
|
||||
!5 = !{i32 8, !"PIC Level", i32 2}
|
||||
!6 = !{i32 7, !"PIE Level", i32 2}
|
||||
!7 = !{i32 7, !"uwtable", i32 2}
|
||||
!8 = !{i32 7, !"frame-pointer", i32 2}
|
||||
!9 = !{!"clang version 18.0.0"}
|
||||
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!11 = distinct !DISubprogram(name: "nop", linkageName: "?nop@@YAHH@Z", scope: !1, file: !1, line: 1, type: !33, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !31)
|
||||
!12 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 5, type: !13, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !15)
|
||||
!13 = !DISubroutineType(types: !14)
|
||||
!14 = !{null}
|
||||
!15 = !{}
|
||||
!16 = !DILocalVariable(name: "End", scope: !12, file: !1, line: 6, type: !10)
|
||||
!17 = !DILocation(line: 0, scope: !12)
|
||||
!18 = !DILocalVariable(name: "Index", scope: !12, file: !1, line: 7, type: !10)
|
||||
!19 = !DILocalVariable(name: "Var", scope: !12, file: !1, line: 8, type: !10)
|
||||
!20 = !DILocation(line: 9, column: 3, scope: !12)
|
||||
!21 = !DILocation(line: 9, column: 16, scope: !22)
|
||||
!22 = distinct !DILexicalBlock(scope: !23, file: !1, line: 9, column: 3)
|
||||
!23 = distinct !DILexicalBlock(scope: !12, file: !1, line: 9, column: 3)
|
||||
!24 = !DILocation(line: 9, column: 23, scope: !22)
|
||||
!25 = !DILocation(line: 9, column: 3, scope: !23)
|
||||
!26 = distinct !{!26, !25, !27, !28}
|
||||
!27 = !DILocation(line: 10, column: 5, scope: !23)
|
||||
!28 = !{!"llvm.loop.mustprogress"}
|
||||
!29 = !DILocation(line: 12, column: 1, scope: !12)
|
||||
!30 = !DILocalVariable(name: "Zeta", scope: !12, file: !1, line: 8, type: !10)
|
||||
!31 = !{!32}
|
||||
!32 = !DILocalVariable(name: "Param", arg: 1, scope: !11, file: !1, line: 1, type: !10)
|
||||
!33 = !DISubroutineType(types: !34)
|
||||
!34 = !{!10, !10}
|
||||
!35 = !DILocation(line: 1, scope: !11)
|
||||
!36 = !DILocation(line: 2, scope: !11)
|
||||
!37 = !DILocation(line: 20, scope: !12)
|
||||
@@ -1,128 +0,0 @@
|
||||
; RUN: opt -passes="loop(indvars)" \
|
||||
; RUN: --experimental-debuginfo-iterators=false -S -o - < %s | \
|
||||
; RUN: FileCheck --implicit-check-not="call void @llvm.dbg" \
|
||||
; RUN: --check-prefix=ALL-CHECK --check-prefix=PRE-CHECK %s
|
||||
; RUN: opt -passes="loop(indvars,loop-deletion)" \
|
||||
; RUN: --experimental-debuginfo-iterators=false -S -o - < %s | \
|
||||
; RUN: FileCheck --implicit-check-not="call void @llvm.dbg" \
|
||||
; RUN: --check-prefix=ALL-CHECK --check-prefix=POST-CHECK %s
|
||||
|
||||
; Check what happens to a modified but otherwise unused variable in a loop
|
||||
; that gets deleted. The assignment in the loop is 'forgotten' by LLVM and
|
||||
; doesn't appear in the debugging information. This behaviour is suboptimal,
|
||||
; but we want to know if it changes
|
||||
|
||||
; For all cases, LLDB shows
|
||||
; Var = <no location, value may have been optimized out>
|
||||
|
||||
; 1 __attribute__((optnone)) int nop() {
|
||||
; 2 return 0;
|
||||
; 3 }
|
||||
; 4
|
||||
; 5 void bar() {
|
||||
; 6 int End = 777;
|
||||
; 7 int Index = 27;
|
||||
; 8 char Var = 1;
|
||||
; 9 for (; Index < End; ++Index) {
|
||||
; 10 if (Index == 666) {
|
||||
; 11 ++Var;
|
||||
; 12 }
|
||||
; 13 }
|
||||
; 14 nop();
|
||||
; 15 }
|
||||
|
||||
; ALL-CHECK: entry:
|
||||
; ALL-CHECK: call void @llvm.dbg.value(metadata i32 1, metadata ![[DBG:[0-9]+]], {{.*}}
|
||||
|
||||
; Only the 'indvars' pass is executed.
|
||||
; PRE-CHECK: for.cond:
|
||||
; PRE-CHECK: call void @llvm.dbg.value(metadata i32 %[[SSA_VAR_0:.+]], metadata ![[DBG]], {{.*}}
|
||||
; PRE-CHECK: call void @llvm.dbg.value(metadata !DIArgList{{.*}}
|
||||
|
||||
; PRE-CHECK: for.body:
|
||||
; PRE-CHECK: {{.*}} = icmp eq i32 %[[SSA_INDEX_0:.+]], 666
|
||||
; PRE-CHECK: {{.*}} = add nsw i32 %[[SSA_VAR_0]], 1
|
||||
; PRE-CHECK: {{.*}} = select i1 {{.*}}, i32 {{.*}}, i32 %[[SSA_VAR_0]]
|
||||
; PRE-CHECK: call void @llvm.dbg.value(metadata i32 {{.*}}, metadata ![[DBG]], {{.*}}
|
||||
; PRE-CHECK: br label %for.cond
|
||||
|
||||
; PRE-CHECK: for.end:
|
||||
; PRE-CHECK: ret void
|
||||
; PRE-CHECK-DAG: ![[DBG]] = !DILocalVariable(name: "Var"{{.*}})
|
||||
|
||||
; The 'indvars' and 'loop-deletion' passes are executed.
|
||||
; POST-CHECK: for.end:
|
||||
; POST-CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata ![[DBG:[0-9]+]], {{.*}}
|
||||
; POST-CHECK: ret void
|
||||
; POST-CHECK-DAG: ![[DBG]] = !DILocalVariable(name: "Var"{{.*}})
|
||||
|
||||
define dso_local void @_Z3barv() local_unnamed_addr !dbg !18 {
|
||||
entry:
|
||||
call void @llvm.dbg.value(metadata i32 1, metadata !24, metadata !DIExpression()), !dbg !22
|
||||
br label %for.cond, !dbg !25
|
||||
|
||||
for.cond: ; preds = %for.cond, %entry
|
||||
%Index.0 = phi i32 [ 27, %entry ], [ %inc2, %for.body ], !dbg !22
|
||||
%Var.0 = phi i32 [ 1, %entry ], [ %spec.select, %for.body ], !dbg !22
|
||||
call void @llvm.dbg.value(metadata i32 %Var.0, metadata !24, metadata !DIExpression()), !dbg !22
|
||||
%cmp = icmp ult i32 %Index.0, 777, !dbg !26
|
||||
call void @llvm.dbg.value(metadata !DIArgList(i32 poison, i32 %Index.0), metadata !24, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 666, DW_OP_eq, DW_OP_LLVM_convert, 1, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned, DW_OP_plus, DW_OP_stack_value)), !dbg !22
|
||||
%inc2 = add nuw nsw i32 %Index.0, 1, !dbg !29
|
||||
br i1 %cmp, label %for.body, label %for.end, !dbg !30, !llvm.loop !31
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
%cmp1 = icmp eq i32 %Index.0, 666, !dbg !30
|
||||
%inc = add nsw i32 %Var.0, 1
|
||||
%spec.select = select i1 %cmp1, i32 %inc, i32 %Var.0, !dbg !32
|
||||
call void @llvm.dbg.value(metadata i32 %spec.select, metadata !24, metadata !DIExpression()), !dbg !22
|
||||
br label %for.cond, !dbg !34, !llvm.loop !35
|
||||
|
||||
for.end: ; preds = %for.cond
|
||||
ret void, !dbg !35
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.value(metadata, metadata, metadata)
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
|
||||
!llvm.ident = !{!9}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
|
||||
!1 = !DIFile(filename: "test-b.cpp", directory: "")
|
||||
!2 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!4 = !{i32 1, !"wchar_size", i32 4}
|
||||
!5 = !{i32 8, !"PIC Level", i32 2}
|
||||
!6 = !{i32 7, !"PIE Level", i32 2}
|
||||
!7 = !{i32 7, !"uwtable", i32 2}
|
||||
!8 = !{i32 7, !"frame-pointer", i32 2}
|
||||
!9 = !{!"clang version 19.0.0"}
|
||||
!10 = distinct !DISubprogram(name: "nop", linkageName: "_Z3nopi", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14)
|
||||
!11 = !DISubroutineType(types: !12)
|
||||
!12 = !{!13, !13}
|
||||
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!14 = !{}
|
||||
!15 = !DILocalVariable(name: "Param", arg: 1, scope: !10, file: !1, line: 1, type: !13)
|
||||
!16 = !DILocation(line: 1, column: 38, scope: !10)
|
||||
!17 = !DILocation(line: 2, column: 3, scope: !10)
|
||||
!18 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 5, type: !19, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14)
|
||||
!19 = !DISubroutineType(types: !20)
|
||||
!20 = !{null}
|
||||
!22 = !DILocation(line: 0, scope: !18)
|
||||
!24 = !DILocalVariable(name: "Var", scope: !18, file: !1, line: 8, type: !13)
|
||||
!25 = !DILocation(line: 9, column: 3, scope: !18)
|
||||
!26 = !DILocation(line: 9, column: 16, scope: !27)
|
||||
!27 = distinct !DILexicalBlock(scope: !28, file: !1, line: 9, column: 3)
|
||||
!28 = distinct !DILexicalBlock(scope: !18, file: !1, line: 9, column: 3)
|
||||
!29 = !DILocation(line: 9, column: 23, scope: !27)
|
||||
!30 = !DILocation(line: 9, column: 3, scope: !28)
|
||||
!31 = distinct !{!31, !30, !32, !33}
|
||||
!32 = !DILocation(line: 11, column: 9, scope: !28)
|
||||
!33 = !{!"llvm.loop.mustprogress"}
|
||||
!34 = !DILocation(line: 12, column: 3, scope: !18)
|
||||
!35 = !DILocation(line: 13, column: 1, scope: !18)
|
||||
!36 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !37, scopeLine: 15, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
|
||||
!37 = !DISubroutineType(types: !38)
|
||||
!38 = !{!13}
|
||||
!39 = !DILocation(line: 16, column: 3, scope: !36)
|
||||
!40 = !DILocation(line: 17, column: 1, scope: !36)
|
||||
@@ -1,131 +0,0 @@
|
||||
; RUN: opt -passes="loop(indvars)" \
|
||||
; RUN: --experimental-debuginfo-iterators=false -S -o - < %s | \
|
||||
; RUN: FileCheck --implicit-check-not="call void @llvm.dbg" \
|
||||
; RUN: --check-prefix=ALL-CHECK --check-prefix=PRE-CHECK %s
|
||||
; RUN: opt -passes="loop(indvars,loop-deletion)" \
|
||||
; RUN: --experimental-debuginfo-iterators=false -S -o - < %s | \
|
||||
; RUN: FileCheck --implicit-check-not="call void @llvm.dbg" \
|
||||
; RUN: --check-prefix=ALL-CHECK --check-prefix=POST-CHECK %s
|
||||
|
||||
; Check what happens to a modified but otherwise unused variable in a loop
|
||||
; that gets deleted. The assignment in the loop is 'forgotten' by LLVM and
|
||||
; doesn't appear in the debugging information. This behaviour is suboptimal,
|
||||
; but we want to know if it changes
|
||||
|
||||
; For all cases, LLDB shows
|
||||
; Var = <no location, value may have been optimized out>
|
||||
|
||||
; 1 __attribute__((optnone)) int nop() {
|
||||
; 2 return 0;
|
||||
; 3 }
|
||||
; 4
|
||||
; 5 void bar() {
|
||||
; 6 int End = 777;
|
||||
; 7 int Index = 27;
|
||||
; 8 char Var = 1;
|
||||
; 9 for (; Index < End; ++Index) {
|
||||
; 10 if (Index == 666) {
|
||||
; 11 Var = 555;
|
||||
; 12 }
|
||||
; 13 }
|
||||
; 14 nop();
|
||||
; 15 }
|
||||
|
||||
; ALL-CHECK: entry:
|
||||
; ALL-CHECK: call void @llvm.dbg.value(metadata i32 1, metadata ![[DBG:[0-9]+]], {{.*}}
|
||||
|
||||
; Only the 'indvars' pass is executed.
|
||||
; PRE-CHECK: if.then:
|
||||
; PRE-CHECK: call void @llvm.dbg.value(metadata i32 555, metadata ![[DBG]], {{.*}}
|
||||
|
||||
; PRE-CHECK: for.inc:
|
||||
; PRE-CHECK: %[[SSA_VAR_0:.+]] = phi i32 [ 1, %for.body ], [ 555, %if.then ]
|
||||
; PRE-CHECK: call void @llvm.dbg.value(metadata i32 %[[SSA_VAR_0]], metadata ![[DBG]], {{.*}}
|
||||
; PRE-CHECK: {{.*}} = add nuw nsw i32 %[[SSA_INDEX_0:.+]], 1
|
||||
; PRE-CHECK: br label %for.cond
|
||||
|
||||
; PRE-CHECK: for.end:
|
||||
; PRE-CHECK: ret void
|
||||
; PRE-CHECK-DAG: ![[DBG]] = !DILocalVariable(name: "Var"{{.*}})
|
||||
|
||||
; The 'indvars' and 'loop-deletion' passes are executed.
|
||||
; POST-CHECK: for.end:
|
||||
; POST-CHECK: call void @llvm.dbg.value(metadata i32 555, metadata ![[DBG]], {{.*}}
|
||||
; POST-CHECK: ret void
|
||||
; POST-CHECK-DAG: ![[DBG]] = !DILocalVariable(name: "Var"{{.*}})
|
||||
|
||||
define dso_local void @_Z3barv() local_unnamed_addr !dbg !18 {
|
||||
entry:
|
||||
call void @llvm.dbg.value(metadata i32 1, metadata !24, metadata !DIExpression()), !dbg !22
|
||||
br label %for.cond, !dbg !25
|
||||
|
||||
for.cond: ; preds = %for.inc, %entry
|
||||
%Index.0 = phi i32 [ 27, %entry ], [ %inc, %for.inc ], !dbg !22
|
||||
%cmp = icmp ult i32 %Index.0, 777, !dbg !26
|
||||
br i1 %cmp, label %for.body, label %for.end, !dbg !30, !llvm.loop !29
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
%cmp1 = icmp eq i32 %Index.0, 666, !dbg !30
|
||||
br i1 %cmp1, label %if.then, label %for.inc, !dbg !32
|
||||
|
||||
if.then: ; preds = %for.body
|
||||
call void @llvm.dbg.value(metadata i32 555, metadata !24, metadata !DIExpression()), !dbg !22
|
||||
br label %for.inc, !dbg !34, !llvm.loop !32
|
||||
|
||||
for.inc: ; preds = %for.body, %if.then
|
||||
%Var.0 = phi i32 [ 1, %for.body ], [ 555, %if.then ], !dbg !22
|
||||
call void @llvm.dbg.value(metadata i32 %Var.0, metadata !24, metadata !DIExpression()), !dbg !22
|
||||
%inc = add nuw nsw i32 %Index.0, 1, !dbg !29
|
||||
br label %for.cond, !dbg !34, !llvm.loop !35
|
||||
|
||||
for.end: ; preds = %for.cond
|
||||
ret void, !dbg !35
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.value(metadata, metadata, metadata)
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
|
||||
!llvm.ident = !{!9}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
|
||||
!1 = !DIFile(filename: "test-c.cpp", directory: "")
|
||||
!2 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!4 = !{i32 1, !"wchar_size", i32 4}
|
||||
!5 = !{i32 8, !"PIC Level", i32 2}
|
||||
!6 = !{i32 7, !"PIE Level", i32 2}
|
||||
!7 = !{i32 7, !"uwtable", i32 2}
|
||||
!8 = !{i32 7, !"frame-pointer", i32 2}
|
||||
!9 = !{!"clang version 19.0.0"}
|
||||
!10 = distinct !DISubprogram(name: "nop", linkageName: "_Z3nopi", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14)
|
||||
!11 = !DISubroutineType(types: !12)
|
||||
!12 = !{!13, !13}
|
||||
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!14 = !{}
|
||||
!15 = !DILocalVariable(name: "Param", arg: 1, scope: !10, file: !1, line: 1, type: !13)
|
||||
!16 = !DILocation(line: 1, column: 38, scope: !10)
|
||||
!17 = !DILocation(line: 2, column: 3, scope: !10)
|
||||
!18 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 5, type: !19, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14)
|
||||
!19 = !DISubroutineType(types: !20)
|
||||
!20 = !{null}
|
||||
!21 = !DILocalVariable(name: "End", scope: !18, file: !1, line: 6, type: !13)
|
||||
!22 = !DILocation(line: 0, scope: !18)
|
||||
!23 = !DILocalVariable(name: "Index", scope: !18, file: !1, line: 7, type: !13)
|
||||
!24 = !DILocalVariable(name: "Var", scope: !18, file: !1, line: 8, type: !13)
|
||||
!25 = !DILocation(line: 9, column: 3, scope: !18)
|
||||
!26 = !DILocation(line: 9, column: 16, scope: !27)
|
||||
!27 = distinct !DILexicalBlock(scope: !28, file: !1, line: 9, column: 3)
|
||||
!28 = distinct !DILexicalBlock(scope: !18, file: !1, line: 9, column: 3)
|
||||
!29 = !DILocation(line: 9, column: 23, scope: !27)
|
||||
!30 = !DILocation(line: 9, column: 3, scope: !28)
|
||||
!31 = distinct !{!31, !30, !32, !33}
|
||||
!32 = !DILocation(line: 11, column: 13, scope: !28)
|
||||
!33 = !{!"llvm.loop.mustprogress"}
|
||||
!34 = !DILocation(line: 12, column: 3, scope: !18)
|
||||
!35 = !DILocation(line: 13, column: 1, scope: !18)
|
||||
!36 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !37, scopeLine: 15, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
|
||||
!37 = !DISubroutineType(types: !38)
|
||||
!38 = !{!13}
|
||||
!39 = !DILocation(line: 16, column: 3, scope: !36)
|
||||
!40 = !DILocation(line: 17, column: 1, scope: !36)
|
||||
@@ -1,104 +0,0 @@
|
||||
; RUN: opt -passes="loop(indvars)" \
|
||||
; RUN: --experimental-debuginfo-iterators=false -S -o - < %s | \
|
||||
; RUN: FileCheck --check-prefix=PRE-CHECK %s
|
||||
; RUN: opt -passes="loop(indvars,loop-deletion)" \
|
||||
; RUN: --experimental-debuginfo-iterators=false -S -o - < %s | \
|
||||
; RUN: FileCheck --check-prefix=POST-CHECK %s
|
||||
|
||||
; Make sure that when we delete the loop in the code below, that the variable
|
||||
; Index has the 777 value.
|
||||
|
||||
; 1 __attribute__((optnone)) int nop() {
|
||||
; 2 return 0;
|
||||
; 3 }
|
||||
; 4
|
||||
; 5 void bar() {
|
||||
; 6 int End = 777;
|
||||
; 7 int Index = 27;
|
||||
; 8 char Var = 1;
|
||||
; 9 for (; Index < End; ++Index)
|
||||
; 10 ;
|
||||
; 11 nop();
|
||||
; 12 }
|
||||
; 13
|
||||
; 14 int main () {
|
||||
; 15 bar();
|
||||
; 16 }
|
||||
|
||||
; Only the 'indvars' pass is executed.
|
||||
; As this test case does not fire the 'indvars' transformation, no debug values
|
||||
; are preserved and or added.
|
||||
|
||||
; PRE-CHECK: for.cond:
|
||||
; PRE-CHECK: call void @llvm.dbg.value(metadata i32 poison, metadata ![[DBG_1:[0-9]+]], {{.*}}
|
||||
; PRE-CHECK: call void @llvm.dbg.value(metadata i32 poison, metadata ![[DBG_1]], {{.*}}
|
||||
; PRE-CHECK: br i1 false, label %for.cond, label %for.end
|
||||
|
||||
; PRE-CHECK: for.end:
|
||||
; PRE-CHECK-NOT: call void @llvm.dbg.value
|
||||
; PRE-CHECK: ret void
|
||||
; PRE-CHECK-DAG: ![[DBG_1]] = !DILocalVariable(name: "Index"{{.*}})
|
||||
|
||||
; The 'indvars' and 'loop-deletion' passes are executed.
|
||||
; The loop is deleted and the debug values collected by 'indvars' are used by
|
||||
; 'loop-deletion' to add the induction variable debug value.
|
||||
|
||||
; POST-CHECK: for.end:
|
||||
; POST-CHECK: call void @llvm.dbg.value(metadata i32 777, metadata ![[DBG_2:[0-9]+]], {{.*}}
|
||||
; POST-CHECK: ret void
|
||||
; POST-CHECK-DAG: ![[DBG_2]] = !DILocalVariable(name: "Index"{{.*}})
|
||||
|
||||
define dso_local void @_Z3barv() local_unnamed_addr #1 !dbg !15 {
|
||||
entry:
|
||||
call void @llvm.dbg.value(metadata i32 777, metadata !19, metadata !DIExpression()), !dbg !20
|
||||
call void @llvm.dbg.value(metadata i32 27, metadata !21, metadata !DIExpression()), !dbg !20
|
||||
call void @llvm.dbg.value(metadata i32 1, metadata !22, metadata !DIExpression()), !dbg !20
|
||||
br label %for.cond, !dbg !23
|
||||
|
||||
for.cond: ; preds = %for.cond, %entry
|
||||
%Index.0 = phi i32 [ 27, %entry ], [ %inc, %for.cond ], !dbg !20
|
||||
call void @llvm.dbg.value(metadata i32 %Index.0, metadata !21, metadata !DIExpression()), !dbg !20
|
||||
%cmp = icmp ult i32 %Index.0, 777, !dbg !24
|
||||
%inc = add nuw nsw i32 %Index.0, 1, !dbg !27
|
||||
call void @llvm.dbg.value(metadata i32 %inc, metadata !21, metadata !DIExpression()), !dbg !20
|
||||
br i1 %cmp, label %for.cond, label %for.end, !dbg !28, !llvm.loop !29
|
||||
|
||||
for.end: ; preds = %for.cond
|
||||
ret void, !dbg !33
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.value(metadata, metadata, metadata)
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
|
||||
!llvm.ident = !{!9}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
|
||||
!1 = !DIFile(filename: "test.cpp", directory: "")
|
||||
!2 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!4 = !{i32 1, !"wchar_size", i32 4}
|
||||
!5 = !{i32 8, !"PIC Level", i32 2}
|
||||
!6 = !{i32 7, !"PIE Level", i32 2}
|
||||
!7 = !{i32 7, !"uwtable", i32 2}
|
||||
!8 = !{i32 7, !"frame-pointer", i32 2}
|
||||
!9 = !{!"clang version 18.0.0"}
|
||||
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!15 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 5, type: !16, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18)
|
||||
!16 = !DISubroutineType(types: !17)
|
||||
!17 = !{null}
|
||||
!18 = !{}
|
||||
!19 = !DILocalVariable(name: "End", scope: !15, file: !1, line: 6, type: !13)
|
||||
!20 = !DILocation(line: 0, scope: !15)
|
||||
!21 = !DILocalVariable(name: "Index", scope: !15, file: !1, line: 7, type: !13)
|
||||
!22 = !DILocalVariable(name: "Var", scope: !15, file: !1, line: 8, type: !13)
|
||||
!23 = !DILocation(line: 9, column: 3, scope: !15)
|
||||
!24 = !DILocation(line: 9, column: 16, scope: !25)
|
||||
!25 = distinct !DILexicalBlock(scope: !26, file: !1, line: 9, column: 3)
|
||||
!26 = distinct !DILexicalBlock(scope: !15, file: !1, line: 9, column: 3)
|
||||
!27 = !DILocation(line: 9, column: 23, scope: !25)
|
||||
!28 = !DILocation(line: 9, column: 3, scope: !26)
|
||||
!29 = distinct !{!29, !28, !30, !31}
|
||||
!30 = !DILocation(line: 10, column: 5, scope: !26)
|
||||
!31 = !{!"llvm.loop.mustprogress"}
|
||||
!33 = !DILocation(line: 12, column: 1, scope: !15)
|
||||
Reference in New Issue
Block a user