diff --git a/llvm/test/DebugInfo/X86/machine-function-splitter.ll b/llvm/test/DebugInfo/X86/machine-function-splitter.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/machine-function-splitter.ll @@ -0,0 +1,166 @@ +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -split-machine-functions -filetype=obj %s -o %t +; RUN: llvm-dwarfdump --debug-line %t | FileCheck %s + +;; Check the line numbers are correct for split function foo (hot) +; CHECK: {{.*}} 3 0 1 0 0 is_stmt +; CHECK-NEXT: {{.*}} 4 9 1 0 0 is_stmt prologue_end +; CHECK-NEXT: {{.*}} 4 7 1 0 0 +; CHECK-NEXT: {{.*}} 5 14 1 0 0 is_stmt +; CHECK-NEXT: {{.*}} 9 1 1 0 0 is_stmt + +;; Check the line numbers are correct for split function foo (cold) +; CHECK: {{.*}} 7 14 1 0 0 is_stmt +; CHECK-NEXT: {{.*}} 7 19 1 0 0 +; CHECK-NEXT: {{.*}} 9 1 1 0 0 is_stmt +; CHECK-NEXT: {{.*}} 9 1 1 0 0 is_stmt end_sequence + +;; Generated from the following source and commands: +;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +;; 1 #include +;; 2 +;; 3 __attribute__((noinline)) int foo(int i) { +;; 4 if (i % 100) { +;; 5 return i + 1; +;; 6 } else { +;; 7 return i * 10 % 3; +;; 8 } +;; 9 } +;; 10 +;; 11 +;; 12 int main(int argc, char *argv[]) { +;; 13 int total = 0; +;; 14 for (int i = 0; i < 1000; ++i) { +;; 15 total += foo(i); +;; 16 } +;; 17 printf("%d\n", total); +;; 18 } +;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +;; clang -fprofile-generate -O2 split_functions.c +;; ./a.out > /dev/null +;; llvm-profdata merge -o default.profdata default_*.profraw +;; clang -fprofile-use -O2 -gmlt -S -emit-llvm split_functions.c +;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +; ModuleID = 'split_functions.c' +source_filename = "split_functions.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 + +; Function Attrs: inlinehint noinline norecurse nounwind readnone uwtable +define dso_local i32 @foo(i32 %i) local_unnamed_addr #0 !dbg !40 !prof !42 { +entry: + %rem = srem i32 %i, 100, !dbg !43 + %tobool.not = icmp eq i32 %rem, 0, !dbg !43 + br i1 %tobool.not, label %if.else, label %if.then, !dbg !44, !prof !45 + +if.then: ; preds = %entry + %add = add nsw i32 %i, 1, !dbg !46 + br label %return, !dbg !47 + +if.else: ; preds = %entry + %mul = mul nsw i32 %i, 10, !dbg !48 + %rem1 = srem i32 %mul, 3, !dbg !49 + br label %return, !dbg !50 + +return: ; preds = %if.else, %if.then + %retval.0 = phi i32 [ %add, %if.then ], [ %rem1, %if.else ], !dbg !51 + ret i32 %retval.0, !dbg !52 +} + +; Function Attrs: nofree nounwind uwtable +define dso_local i32 @main(i32 %argc, i8** nocapture readnone %argv) local_unnamed_addr #1 !dbg !53 !prof !54 { +entry: + br label %for.body, !dbg !55 + +for.cond.cleanup: ; preds = %for.body + %call1 = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %add), !dbg !56 + ret i32 0, !dbg !57 + +for.body: ; preds = %entry, %for.body + %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %total.07 = phi i32 [ 0, %entry ], [ %add, %for.body ] + %call = tail call i32 @foo(i32 %i.08), !dbg !58 + %add = add nsw i32 %call, %total.07, !dbg !59 + %inc = add nuw nsw i32 %i.08, 1, !dbg !60 + %exitcond.not = icmp eq i32 %inc, 1000, !dbg !61 + br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !dbg !55, !prof !62, !llvm.loop !63 +} + +; Function Attrs: nofree nounwind +declare dso_local noundef i32 @printf(i8* nocapture noundef readonly, ...) local_unnamed_addr #2 + +attributes #0 = { inlinehint noinline norecurse nounwind readnone uwtable "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nofree nounwind uwtable "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nofree nounwind "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6, !35} +!llvm.ident = !{!39} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0 (git@github.com:llvm/llvm-project.git c9d6fe6f7d84f5b1a0bdbe502ebc3c8035722fdb)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "split_functions.c", directory: "/usr/local/google/home/snehasishk/working/llvm-project/build") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{i32 1, !"ProfileSummary", !7} +!7 = !{!8, !9, !10, !11, !12, !13, !14, !15, !16, !17} +!8 = !{!"ProfileFormat", !"InstrProf"} +!9 = !{!"TotalCount", i64 2001} +!10 = !{!"MaxCount", i64 1000} +!11 = !{!"MaxInternalCount", i64 10} +!12 = !{!"MaxFunctionCount", i64 1000} +!13 = !{!"NumCounts", i64 4} +!14 = !{!"NumFunctions", i64 2} +!15 = !{!"IsPartialProfile", i64 0} +!16 = !{!"PartialProfileRatio", double 0.000000e+00} +!17 = !{!"DetailedSummary", !18} +!18 = !{!19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34} +!19 = !{i32 10000, i64 1000, i32 1} +!20 = !{i32 100000, i64 1000, i32 1} +!21 = !{i32 200000, i64 1000, i32 1} +!22 = !{i32 300000, i64 1000, i32 1} +!23 = !{i32 400000, i64 1000, i32 1} +!24 = !{i32 500000, i64 1000, i32 1} +!25 = !{i32 600000, i64 990, i32 2} +!26 = !{i32 700000, i64 990, i32 2} +!27 = !{i32 800000, i64 990, i32 2} +!28 = !{i32 900000, i64 990, i32 2} +!29 = !{i32 950000, i64 990, i32 2} +!30 = !{i32 990000, i64 990, i32 2} +!31 = !{i32 999000, i64 10, i32 3} +!32 = !{i32 999900, i64 10, i32 3} +!33 = !{i32 999990, i64 10, i32 3} +!34 = !{i32 999999, i64 10, i32 3} +!35 = !{i32 5, !"CG Profile", !36} +!36 = !{!37, !38} +!37 = !{i32 (i32, i8**)* @main, i32 (i8*, ...)* @printf, i64 1} +!38 = !{i32 (i32, i8**)* @main, i32 (i32)* @foo, i64 1001} +!39 = !{!"clang version 12.0.0 (git@github.com:llvm/llvm-project.git c9d6fe6f7d84f5b1a0bdbe502ebc3c8035722fdb)"} +!40 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !41, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!41 = !DISubroutineType(types: !2) +!42 = !{!"function_entry_count", i64 1000} +!43 = !DILocation(line: 4, column: 9, scope: !40) +!44 = !DILocation(line: 4, column: 7, scope: !40) +!45 = !{!"branch_weights", i32 10, i32 990} +!46 = !DILocation(line: 5, column: 14, scope: !40) +!47 = !DILocation(line: 5, column: 5, scope: !40) +!48 = !DILocation(line: 7, column: 14, scope: !40) +!49 = !DILocation(line: 7, column: 19, scope: !40) +!50 = !DILocation(line: 7, column: 5, scope: !40) +!51 = !DILocation(line: 0, scope: !40) +!52 = !DILocation(line: 9, column: 1, scope: !40) +!53 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 12, type: !41, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!54 = !{!"function_entry_count", i64 1} +!55 = !DILocation(line: 14, column: 3, scope: !53) +!56 = !DILocation(line: 17, column: 3, scope: !53) +!57 = !DILocation(line: 18, column: 1, scope: !53) +!58 = !DILocation(line: 15, column: 14, scope: !53) +!59 = !DILocation(line: 15, column: 11, scope: !53) +!60 = !DILocation(line: 14, column: 29, scope: !53) +!61 = !DILocation(line: 14, column: 21, scope: !53) +!62 = !{!"branch_weights", i32 1, i32 1000} +!63 = distinct !{!63, !55, !64} +!64 = !DILocation(line: 16, column: 3, scope: !53)