llvm-project/llvm/test/Transforms/GlobalOpt/dbg-intrinsic-loopanalysis.ll
Mikael Holmen 51d4c7ceea [GlobalOpt] Fix debug variance problem in hasOnlyColdCalls
hasOnlyColdCalls skipped over calls to intrinsics, but it did so after
checking the linkage of the called function. This meant that the presence
of a call to a debug intrinsic could affect the outcome of the
optimization.

In my original reproducer (for an out of tree target) it was particularly
interesting, because the actual IR after GlobalOpt was not different with
debug instrinsics present, so -print-after-all printouts didn't show
anything there.

However, without debuginfo, GlobalOpt went further and ran
BlockFrequencyAnalysis and (more importanly) LoopAnalysis, and later on in
the pipeline, instcombine behaved in different ways when LoopInfo was
present.

So a call to a dbg.declare prevented running LoopAnalysis in
GlobalOpt, which later prevented InstCombine from doing an optimization.

The dbg-intrinsic-loopanalysis.ll testcase tries to expose this.

Then I also noted that adding a dbg.declare actually made the existing
testcase colccc_coldsites.ll generate different code, so I modified that
to now test it behaves the same way with and without the dbg.declare.

Reviewed By: nikic, fhahn

Differential Revision: https://reviews.llvm.org/D133193
2022-09-02 12:29:44 +02:00

47 lines
2.1 KiB
LLVM

; RUN: opt -passes="globalopt" < %s -o /dev/null -debug-pass-manager 2>&1 | FileCheck %s
; RUN: opt -strip-debug -S < %s | opt -passes="globalopt" -o /dev/null -debug-pass-manager 2>&1 | FileCheck %s
; Make sure that the call to dbg.declare does not prevent running BlockFrequency
; and (especially) Loop Analysis.
; Later passes (e.g. instcombine) may behave in different ways depending on if
; LoopInfo is available or not. Therefore, letting GlobalOpt run or not run
; LoopAnalysis depending on the presence of a dbg.declare may make the compiler
; generate different code with and without debug info.
; CHECK: Running pass: GlobalOptPass on [module]
; CHECK: Running analysis: BlockFrequencyAnalysis on h
; CHECK: Running analysis: LoopAnalysis on h
define i16 @h(ptr %k) {
entry:
call void @llvm.dbg.declare(metadata ptr %k, metadata !1, metadata !DIExpression()), !dbg !22
%call = call i16 @gaz()
ret i16 %call
}
; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
define internal i16 @gaz() {
entry:
ret i16 0
}
attributes #0 = { nocallback nofree nosync nounwind readnone speculatable willreturn }
!llvm.dbg.cu = !{!17}
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = !DILocalVariable(name: "k", arg: 1, scope: !2, file: !3, line: 13, type: !19)
!2 = distinct !DISubprogram(name: "h", scope: !3, file: !3, line: 13, type: !4, scopeLine: 13, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !17, retainedNodes: !21)
!3 = !DIFile(filename: "foo2.c", directory: "/bar")
!4 = !DISubroutineType(types: !5)
!5 = !{!19}
!17 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 16", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !18, globals: !20, splitDebugInlining: false, nameTableKind: None)
!18 = !{!19}
!19 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
!20 = !{}
!21 = !{!1}
!22 = !DILocation(line: 13, column: 27, scope: !2)