diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -828,6 +828,13 @@ return; } + if (auto *II = dyn_cast(this)) { + if (!IntrinsicInst::mayLowerToFunctionCall(II->getIntrinsicID())) { + setDebugLoc(DebugLoc()); + return; + } + } + // Set a line 0 location for calls to preserve scope information in case // inlining occurs. DISubprogram *SP = getFunction()->getSubprogram(); diff --git a/llvm/test/DebugInfo/Generic/licm-hoist-intrinsic-debug-loc.ll b/llvm/test/DebugInfo/Generic/licm-hoist-intrinsic-debug-loc.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/licm-hoist-intrinsic-debug-loc.ll @@ -0,0 +1,86 @@ +; RUN: opt -S -licm %s | FileCheck %s +; +; LICM should null out debug locations when it hoists intrinsics that won't lower to functions out of a loop. +; CHECK: define dso_local float @foo +; CHECK-NEXT: bb: +; CHECK: call float @llvm.fma.f32(float %arg4, float %arg5, float 0.000000e+00){{$}} +; CHECK: loop: +; +; Generated with +; clang -S -emit-llvm -ffp-contract=off -Xclang -disable-O0-optnone -g -gline-tables-only -o - source.c | \ +; opt -S -mem2reg -simplifycfg -loop-simplify -loop-rotate -instnamer > generated.ll +; +; float foo(float* a, float b, float c, unsigned n) { +; float z = 0.0; +; for (unsigned i = 0; i < n; ++i) { +; z += a[i] * __builtin_fmaf(b, c, 0.0); +; } +; return z; +; } + +; Function Attrs: noinline nounwind uwtable +define dso_local float @foo(float* noundef %arg, float noundef %arg4, float noundef %arg5, i32 noundef %arg6) #0 !dbg !10 { +bb: + %i = icmp ult i32 0, %arg6, !dbg !13 + br i1 %i, label %.lr.ph, label %bb16, !dbg !14 + +.lr.ph: ; preds = %bb + br label %loop, !dbg !14 + +loop: ; preds = %.lr.ph, %loop + %.03 = phi i32 [ 0, %.lr.ph ], [ %i14, %loop ] + %.012 = phi float [ 0.000000e+00, %.lr.ph ], [ %i13, %loop ] + %i8 = zext i32 %.03 to i64, !dbg !15 + %i9 = getelementptr inbounds float, float* %arg, i64 %i8, !dbg !15 + %i10 = load float, float* %i9, align 4, !dbg !15 + %i11 = call float @llvm.fma.f32(float %arg4, float %arg5, float 0.000000e+00), !dbg !16 + %i12 = fmul float %i10, %i11, !dbg !17 + %i13 = fadd float %.012, %i12, !dbg !18 + %i14 = add i32 %.03, 1, !dbg !19 + %i15 = icmp ult i32 %i14, %arg6, !dbg !13 + br i1 %i15, label %loop, label %._crit_edge, !dbg !14, !llvm.loop !20 + +._crit_edge: ; preds = %loop + %split = phi float [ %i13, %loop ] + br label %bb16, !dbg !14 + +bb16: ; preds = %._crit_edge, %bb + %.01.lcssa = phi float [ %split, %._crit_edge ], [ 0.000000e+00, %bb ], !dbg !23 + ret float %.01.lcssa, !dbg !24 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.fma.f32(float, float, float) #1 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "source.c", directory: "/home/llvm-project/llvm/test/DebugInfo/Generic") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"PIC Level", i32 2} +!6 = !{i32 7, !"PIE Level", i32 2} +!7 = !{i32 7, !"uwtable", i32 1} +!8 = !{i32 7, !"frame-pointer", i32 2} +!9 = !{!"clang version 14"} +!10 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12) +!11 = !DISubroutineType(types: !12) +!12 = !{} +!13 = !DILocation(line: 3, column: 26, scope: !10) +!14 = !DILocation(line: 3, column: 3, scope: !10) +!15 = !DILocation(line: 4, column: 10, scope: !10) +!16 = !DILocation(line: 4, column: 17, scope: !10) +!17 = !DILocation(line: 4, column: 15, scope: !10) +!18 = !DILocation(line: 4, column: 7, scope: !10) +!19 = !DILocation(line: 3, column: 31, scope: !10) +!20 = distinct !{!20, !14, !21, !22} +!21 = !DILocation(line: 5, column: 3, scope: !10) +!22 = !{!"llvm.loop.mustprogress"} +!23 = !DILocation(line: 0, scope: !10) +!24 = !DILocation(line: 6, column: 3, scope: !10)