From f7d90ad57bef473e72119c0251e12e1915121b45 Mon Sep 17 00:00:00 2001 From: Andrew Litteken Date: Sun, 13 Mar 2022 23:45:29 -0500 Subject: [PATCH] [IROutliner] Make sure that loop debug info is stripped. As pointed out in https://github.com/llvm/llvm-project/issues/54155#issuecomment-1057465479, there was a crash when loop info was being outlined. It was not being properly stripped and adjusted, so would point to the wrong location. This uses similar logic found in the CodeExtractor to adjust the loop debug info. Reviewer: fhahn, paquette Differential Revision: https://reviews.llvm.org/D120869 --- llvm/lib/Transforms/IPO/IROutliner.cpp | 15 ++++- .../IROutliner/outlining-strip-loop-info.ll | 78 ++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/IROutliner/outlining-strip-loop-info.ll diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index a7b77ee..51e1f99 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -16,8 +16,9 @@ #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/Attributes.h" -#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DIBuilder.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/PassManager.h" @@ -679,6 +680,18 @@ static void moveFunctionData(Function &Old, Function &New, if (!isa(&Val)) { // Remove the debug information for outlined functions. Val.setDebugLoc(DebugLoc()); + + // Loop info metadata may contain line locations. Update them to have no + // value in the new subprogram since the outlined code could be from + // several locations. + auto updateLoopInfoLoc = [&New](Metadata *MD) -> Metadata * { + if (DISubprogram *SP = New.getSubprogram()) + if (auto *Loc = dyn_cast_or_null(MD)) + return DILocation::get(New.getContext(), Loc->getLine(), + Loc->getColumn(), SP, nullptr); + return MD; + }; + updateLoopMetadataDebugLocations(Val, updateLoopInfoLoc); continue; } diff --git a/llvm/test/Transforms/IROutliner/outlining-strip-loop-info.ll b/llvm/test/Transforms/IROutliner/outlining-strip-loop-info.ll new file mode 100644 index 0000000..53b798f --- /dev/null +++ b/llvm/test/Transforms/IROutliner/outlining-strip-loop-info.ll @@ -0,0 +1,78 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs +; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s + +; Make sure that we strip loop debug info from instructions that are outlined as +; well as regular debug info. + +define void @ham(i64 %arg0, i64 %arg1) !dbg !1 { +bb0: + br label %bb1 +bb1: + %phi = phi i64 [ 0, %bb0 ], [ %arg1, %bb1 ] + %icmp = icmp ult i64 %phi, %arg0 + br i1 %icmp, label %bb1, label %bb2, !dbg !7, !llvm.loop !11 + +bb2: + ret void +} + +define void @wombat(i64 %arg0, i64 %arg1) !dbg !13 { +bb0: + br label %bb1 +bb1: + %phi = phi i64 [ 0, %bb0 ], [ %arg1, %bb1 ] + %icmp = icmp ult i64 %phi, %arg0 + br i1 %icmp, label %bb1, label %bb2 + +bb2: + ret void +} + +!llvm.module.flags = !{!0} +!llvm.dbg.cu = !{} + +!0 = !{i32 2, !"Debug Info Version", i32 3} +!1 = distinct !DISubprogram(name: "ham", scope: !2, file: !2, line: 160, type: !3, scopeLine: 161, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !5) +!2 = !DIFile(filename: "file", directory: "dir") +!3 = !DISubroutineType(types: !4) +!4 = !{} +!5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !6, producer: "ver", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None, sysroot: "sysroot", sdk: "sdk") +!6 = !DIFile(filename: "file", directory: "dir") +!7 = !DILocation(line: 354, column: 13, scope: !8, inlinedAt: !10) +!8 = distinct !DISubprogram(name: "baz", scope: !9, file: !9, line: 345, type: !3, scopeLine: 346, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !5) +!9 = !DIFile(filename: "file", directory: "dir") +!10 = distinct !DILocation(line: 164, column: 15, scope: !1) +!11 = distinct !{!11, !7, !12} +!12 = !DILocation(line: 355, column: 37, scope: !8, inlinedAt: !10) +!13 = distinct !DISubprogram(name: "wombat", scope: !2, file: !2, line: 172, type: !3, scopeLine: 173, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !5) +!14 = distinct !DISubprogram(name: "bar", scope: !15, file: !15, line: 219, type: !3, scopeLine: 220, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !5) +!15 = !DIFile(filename: "file", directory: "dir") + +; CHECK-LABEL: @ham( +; CHECK-NEXT: bb0: +; CHECK-NEXT: call void @outlined_ir_func_0(i64 [[ARG1:%.*]], i64 [[ARG0:%.*]]), !dbg [[DBG6:![0-9]+]] +; CHECK-NEXT: br label [[BB2:%.*]] +; CHECK: bb2: +; CHECK-NEXT: ret void +; +; +; CHECK-LABEL: @wombat( +; CHECK-NEXT: bb0: +; CHECK-NEXT: call void @outlined_ir_func_0(i64 [[ARG1:%.*]], i64 [[ARG0:%.*]]), !dbg [[DBG10:![0-9]+]] +; CHECK-NEXT: br label [[BB2:%.*]] +; CHECK: bb2: +; CHECK-NEXT: ret void +; +; +; CHECK-LABEL: define internal void @outlined_ir_func_0( +; CHECK-NEXT: newFuncRoot: +; CHECK-NEXT: br label [[BB0_TO_OUTLINE:%.*]] +; CHECK: bb0_to_outline: +; CHECK-NEXT: br label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ 0, [[BB0_TO_OUTLINE]] ], [ [[TMP0:%.*]], [[BB1]] ] +; CHECK-NEXT: [[ICMP:%.*]] = icmp ult i64 [[PHI]], [[TMP1:%.*]] +; CHECK-NEXT: br i1 [[ICMP]], label [[BB1]], label [[BB2_EXITSTUB:%.*]], !llvm.loop [[LOOP12:![0-9]+]] +; CHECK: bb2.exitStub: +; CHECK-NEXT: ret void +; -- 2.7.4