[PATCH] D104628: Fix a not debug invariant issue in GlobalOpt/GlobalStatus

Markus Lavin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 21 03:18:04 PDT 2021


markus created this revision.
markus added reviewers: dblaikie, jmorse.
Herald added a subscriber: hiraditya.
markus requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Analysis in `analyzeGlobalAux` aborts if the value is no longer of pointer type. This check for pointer type disregards if there are actually any SSA graph uses or not and thus opens up for a debug use via metadata to affect the outcome fo the analysis and eventually if transformation is applied or not.

This patch addresses that by only aborting analysis if there are any undesirable SSA graph uses.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D104628

Files:
  llvm/lib/Transforms/Utils/GlobalStatus.cpp
  llvm/test/Transforms/GlobalOpt/dbg-ptrtoint-use.ll


Index: llvm/test/Transforms/GlobalOpt/dbg-ptrtoint-use.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/GlobalOpt/dbg-ptrtoint-use.ll
@@ -0,0 +1,72 @@
+; RUN: opt -S -globalopt < %s | FileCheck %s
+
+; This test stems from C input as follows where a llvm.dbg.value contain a
+; ptrtoint of something ultimately referencing @f. Verify that presence of this
+; ptrtoint does not inhibit transformation of @f into a constant symbol.
+;
+; static int f[32] = {1,2,3,4,5,6,7};
+; int g(int idx) {
+;   int h = (int)&f[14];
+;   return f[idx];
+; }
+
+; CHECK: @f = internal unnamed_addr constant %const.array
+; CHECK-NOT: call void @llvm.dbg.value(metadata i16 ptrtoint
+; CHECK: call void @llvm.dbg.value(metadata ![[MID:[0-9]+]],
+; CHECK: ![[MID]] = !{}
+
+%const.array = type <{ i16, i16, i16, i16, i16, i16, i16, [25 x i16] }>
+
+ at f = internal global %const.array <{ i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, [25 x i16] zeroinitializer }>, align 1, !dbg !0
+
+; Function Attrs: nounwind
+define dso_local i16 @g(i16 %idx) #0 !dbg !16 {
+entry:
+  call void @llvm.dbg.value(metadata i16 %idx, metadata !20, metadata !DIExpression()), !dbg !22
+  call void @llvm.dbg.value(metadata i16 ptrtoint (i16* getelementptr inbounds ([32 x i16], [32 x i16]* bitcast (%const.array* @f to [32 x i16]*), i32 0, i32 14) to i16), metadata !21, metadata !DIExpression()), !dbg !22
+  %idxprom = sext i16 %idx to i32, !dbg !23
+  %arrayidx = getelementptr inbounds [32 x i16], [32 x i16]* bitcast (%const.array* @f to [32 x i16]*), i32 0, i32 %idxprom, !dbg !23
+  %0 = load i16, i16* %arrayidx, align 1, !dbg !23, !tbaa !24
+  ret i16 %0, !dbg !28
+}
+
+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="phoenixV" }
+attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
+attributes #2 = { argmemonly nofree nosync nounwind willreturn }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!11, !12, !13, !14}
+!llvm.ident = !{!15}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "f", scope: !2, file: !3, line: 1, type: !8, isLocal: true, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 13.0.0 (FlexC)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !7, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "dummy.c", directory: "/tmp")
+!4 = !{}
+!5 = !{!6}
+!6 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
+!7 = !{!0}
+!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 512, elements: !9)
+!9 = !{!10}
+!10 = !DISubrange(count: 32)
+!11 = !{i32 7, !"Dwarf Version", i32 4}
+!12 = !{i32 2, !"Debug Info Version", i32 3}
+!13 = !{i32 1, !"wchar_size", i32 1}
+!14 = !{i32 7, !"frame-pointer", i32 2}
+!15 = !{!"clang version 13.0.0"}
+!16 = distinct !DISubprogram(name: "g", scope: !3, file: !3, line: 2, type: !17, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !19)
+!17 = !DISubroutineType(types: !18)
+!18 = !{!6, !6}
+!19 = !{!20, !21}
+!20 = !DILocalVariable(name: "idx", arg: 1, scope: !16, file: !3, line: 2, type: !6)
+!21 = !DILocalVariable(name: "h", scope: !16, file: !3, line: 3, type: !6)
+!22 = !DILocation(line: 0, scope: !16)
+!23 = !DILocation(line: 4, column: 10, scope: !16)
+!24 = !{!25, !25, i64 0}
+!25 = !{!"int", !26, i64 0}
+!26 = !{!"omnipotent char", !27, i64 0}
+!27 = !{!"Simple C/C++ TBAA"}
+!28 = !DILocation(line: 4, column: 3, scope: !16)
Index: llvm/lib/Transforms/Utils/GlobalStatus.cpp
===================================================================
--- llvm/lib/Transforms/Utils/GlobalStatus.cpp
+++ llvm/lib/Transforms/Utils/GlobalStatus.cpp
@@ -69,8 +69,10 @@
       GS.HasNonInstructionUser = true;
 
       // If the result of the constantexpr isn't pointer type, then we won't
-      // know to expect it in various places.  Just reject early.
-      if (!isa<PointerType>(CE->getType()))
+      // know to expect it in various places. Just reject early, but only if
+      // there is at least one non-metadata use (to be invariant on debug
+      // info).
+      if (!isa<PointerType>(CE->getType()) && !CE->use_empty())
         return true;
 
       // FIXME: Do we need to add constexpr selects to VisitedUsers?


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104628.353314.patch
Type: text/x-patch
Size: 4696 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210621/bf2fcf70/attachment.bin>


More information about the llvm-commits mailing list