Skip to content

Commit

Permalink
[indvars] Missing variables at Og:
Browse files Browse the repository at this point in the history
https://bugs.llvm.org/show_bug.cgi?id=51735
llvm#51077

In the given test case:

 4 ...
 5 void bar() {
 6   int End = 777;
 7   int Index = 27;
 8   char Var = 1;
 9   for (; Index < End; ++Index)
10     ;
11   nop(Index);
12 }
13 ...

Missing local variable 'Index' after loop 'Induction Variable Elimination'.
When adding a breakpoint at line 11, LLDB does not have information on
the variable. But it has info on 'Var' and 'End'.
  • Loading branch information
CarlosAlbertoEnciso committed Jan 16, 2024
1 parent 3ac9fe6 commit 91ee412
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 0 deletions.
25 changes: 25 additions & 0 deletions llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
Expand Down Expand Up @@ -1931,6 +1932,30 @@ bool IndVarSimplify::run(Loop *L) {
}
}

// The loop exit values have been updated; insert the debug location
// for the induction variable with its final value.
if (PHINode *IndVar = L->getInductionVariable(*SE)) {
const SCEV *IndVarSCEV = SE->getSCEVAtScope(IndVar, L->getParentLoop());
if (IndVarSCEV->getSCEVType() == SCEVTypes::scConstant) {
Value *FinalIVValue = cast<SCEVConstant>(IndVarSCEV)->getValue();
SmallVector<DbgVariableIntrinsic *> DbgUsers;
SmallVector<DbgVariableIntrinsic *> DbgUsersCloned;
findDbgUsers(DbgUsers, IndVar);
for (auto &DebugUser : DbgUsers) {
auto *Cloned = cast<DbgVariableIntrinsic>(DebugUser->clone());
Cloned->replaceVariableLocationOp(static_cast<unsigned>(0),
FinalIVValue);
DbgUsersCloned.push_back(Cloned);
}

SmallVector<BasicBlock *> ExitBlocks;
L->getExitBlocks(ExitBlocks);
for (BasicBlock *Exit : ExitBlocks)
for (auto &DebugUser : DbgUsersCloned)
DebugUser->insertBefore(Exit->getFirstNonPHI());
}
}

// Eliminate redundant IV cycles.
NumElimIV += Rewriter.replaceCongruentIVs(L, DT, DeadInsts, TTI);

Expand Down
115 changes: 115 additions & 0 deletions llvm/test/Transforms/LoopSimplify/pr51735-1.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
; RUN: opt -passes=indvars -S -o - < %s | FileCheck %s

; Missing local variable 'Index' after loop 'Induction Variable Elimination'.
; When adding a breakpoint at line 11, LLDB does not have information on
; the variable. But it has info on 'Var' and 'End'.

; 1 __attribute__((optnone)) int nop(int Param) {
; 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(Index);
; 12 }
; 13
; 14 int main () {
; 15 bar();
; 16 }

; CHECK: for.cond: {{.*}}
; CHECK: call void @llvm.dbg.value(metadata i32 poison, metadata ![[DBG:[0-9]+]], {{.*}}
; CHECK: call void @llvm.dbg.value(metadata i32 poison, metadata ![[DBG:[0-9]+]], {{.*}}
; CHECK: br i1 false, label %for.cond, label %for.end, {{.*}}
; CHECK: for.end: {{.*}}
; CHECK: call void @llvm.dbg.value(metadata i32 777, metadata ![[DBG:[0-9]+]], {{.*}}
; CHECK: %call = tail call noundef i32 @_Z3nopi(i32 noundef 777), {{.*}}
; CHECK-DAG: ![[DBG]] = !DILocalVariable(name: "Index"{{.*}})

define dso_local noundef i32 @_Z3nopi(i32 noundef %Param) local_unnamed_addr #0 !dbg !10 {
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 !15, metadata !DIExpression()), !dbg !16
ret i32 0, !dbg !17
}

define dso_local void @_Z3barv() local_unnamed_addr #2 !dbg !18 {
entry:
call void @llvm.dbg.value(metadata i32 777, metadata !21, metadata !DIExpression()), !dbg !22
call void @llvm.dbg.value(metadata i32 27, metadata !23, metadata !DIExpression()), !dbg !22
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 ], [ %inc, %for.cond ], !dbg !22
call void @llvm.dbg.value(metadata i32 %Index.0, metadata !23, metadata !DIExpression()), !dbg !22
%cmp = icmp ult i32 %Index.0, 777, !dbg !26
%inc = add nuw nsw i32 %Index.0, 1, !dbg !29
call void @llvm.dbg.value(metadata i32 %inc, metadata !23, metadata !DIExpression()), !dbg !22
br i1 %cmp, label %for.cond, label %for.end, !dbg !30, !llvm.loop !31

for.end: ; preds = %for.cond
%Index.0.lcssa = phi i32 [ %Index.0, %for.cond ], !dbg !22
%call = tail call noundef i32 @_Z3nopi(i32 noundef %Index.0.lcssa), !dbg !34
ret void, !dbg !35
}

define dso_local noundef i32 @main() local_unnamed_addr #3 !dbg !36 {
entry:
call void @_Z3barv(), !dbg !39
ret i32 0, !dbg !40
}

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 version 18.0.0 (https://github.com/llvm/llvm-project.git 18c2eb2bf02bd7666523aa566e45d62053b7db80)", 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 = 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: 10, column: 5, scope: !28)
!33 = !{!"llvm.loop.mustprogress"}
!34 = !DILocation(line: 11, column: 3, scope: !18)
!35 = !DILocation(line: 12, column: 1, scope: !18)
!36 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !37, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
!37 = !DISubroutineType(types: !38)
!38 = !{!13}
!39 = !DILocation(line: 15, column: 3, scope: !36)
!40 = !DILocation(line: 16, column: 1, scope: !36)
106 changes: 106 additions & 0 deletions llvm/test/Transforms/LoopSimplify/pr51735.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
; RUN: opt -passes=indvars -S -o - < %s | FileCheck %s

; Missing local variable 'Index' after loop 'Induction Variable Elimination'.
; When adding a breakpoint at line 11, LLDB does not have information on
; the variable. But it has info on 'Var' and 'End'.

; 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 }

; CHECK: for.cond: {{.*}}
; CHECK: call void @llvm.dbg.value(metadata i32 poison, metadata ![[DBG:[0-9]+]], {{.*}}
; CHECK: call void @llvm.dbg.value(metadata i32 poison, metadata ![[DBG:[0-9]+]], {{.*}}
; CHECK: br i1 false, label %for.cond, label %for.end, {{.*}}
; CHECK: for.end: {{.*}}
; CHECK: call void @llvm.dbg.value(metadata i32 777, metadata ![[DBG:[0-9]+]], {{.*}}
; CHECK: %call = tail call noundef i32 @_Z3nopv(), {{.*}}
; CHECK-DAG: ![[DBG]] = !DILocalVariable(name: "Index"{{.*}})

define dso_local noundef i32 @_Z3nopv() local_unnamed_addr #0 !dbg !10 {
entry:
ret i32 0, !dbg !14
}

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
%call = tail call noundef i32 @_Z3nopv(), !dbg !32
ret void, !dbg !33
}

define dso_local noundef i32 @main() local_unnamed_addr #2 !dbg !34 {
entry:
call void @_Z3barv(), !dbg !35
ret i32 0, !dbg !36
}

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 version 18.0.0 (https://github.com/llvm/llvm-project.git 18c2eb2bf02bd7666523aa566e45d62053b7db80)", 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 = distinct !DISubprogram(name: "nop", linkageName: "_Z3nopv", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
!11 = !DISubroutineType(types: !12)
!12 = !{!13}
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!14 = !DILocation(line: 2, column: 3, scope: !10)
!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"}
!32 = !DILocation(line: 11, column: 3, scope: !15)
!33 = !DILocation(line: 12, column: 1, scope: !15)
!34 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !11, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
!35 = !DILocation(line: 15, column: 3, scope: !34)
!36 = !DILocation(line: 16, column: 1, scope: !34)

0 comments on commit 91ee412

Please sign in to comment.