[llvm] 76740fb - [Assignment Tracking][SROA] Handle createFragmentExpression failure

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 5 03:20:50 PDT 2023


Author: OCHyams
Date: 2023-04-05T11:20:32+01:00
New Revision: 76740fb40ebb44ae47bc0396c7a177a296adc9f7

URL: https://github.com/llvm/llvm-project/commit/76740fb40ebb44ae47bc0396c7a177a296adc9f7
DIFF: https://github.com/llvm/llvm-project/commit/76740fb40ebb44ae47bc0396c7a177a296adc9f7.diff

LOG: [Assignment Tracking][SROA] Handle createFragmentExpression failure

createFragmentExpression will fail if it determines that the expression cannot
be split over fragments. Handle this case in SROA. Similarly to D147312 this
should be a rare occurrence as the `dbg.assign` will usually reference the
`Value` being stored without modifying it with a `DIExpression`.

Reviewed By: jmorse

Differential Revision: https://reviews.llvm.org/D147431

Added: 
    llvm/test/DebugInfo/Generic/assignment-tracking/sroa/fail-fragment.ll

Modified: 
    llvm/lib/Transforms/Scalar/SROA.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index 388272168a3ae..5eb7ae063a171 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -225,6 +225,7 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit,
     LLVM_DEBUG(dbgs() << "      existing dbg.assign is: " << *DbgAssign
                       << "\n");
     auto *Expr = DbgAssign->getExpression();
+    bool SetKillLocation = false;
 
     if (IsSplit) {
       std::optional<DIExpression::FragmentInfo> BaseFragment = std::nullopt;
@@ -252,11 +253,19 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit,
           // relative fragment too?
           NewFragment->OffsetInBits -= CurrentFragment->OffsetInBits;
         }
-
-        auto E = DIExpression::createFragmentExpression(
-            Expr, NewFragment->OffsetInBits, NewFragment->SizeInBits);
-        assert(E && "Failed to create fragment expr!");
-        Expr = *E;
+        // Add the new fragment info to the existing expression if possible.
+        if (auto E = DIExpression::createFragmentExpression(
+                Expr, NewFragment->OffsetInBits, NewFragment->SizeInBits)) {
+          Expr = *E;
+        } else {
+          // Otherwise, add the new fragment info to an empty expression and
+          // discard the value component of this dbg.assign as the value cannot
+          // be computed with the new fragment.
+          Expr = *DIExpression::createFragmentExpression(
+              DIExpression::get(Expr->getContext(), std::nullopt),
+              NewFragment->OffsetInBits, NewFragment->SizeInBits);
+          SetKillLocation = true;
+        }
       }
     }
 
@@ -281,7 +290,8 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit,
     // This should be a very rare situation as it requires the value being
     // stored to 
diff er from the dbg.assign (i.e., the value has been
     // represented 
diff erently in the debug intrinsic for some reason).
-    if (DbgAssign->hasArgList() && Value)
+    SetKillLocation |= DbgAssign->hasArgList() && Value;
+    if (SetKillLocation)
       NewAssign->setKillLocation();
 
     // We could use more precision here at the cost of some additional (code)

diff  --git a/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/fail-fragment.ll b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/fail-fragment.ll
new file mode 100644
index 0000000000000..5aa9ce3a32ff9
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/fail-fragment.ll
@@ -0,0 +1,65 @@
+; RUN: opt -passes=sroa -S %s -o - \
+; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
+
+;; Check that a dbg.assign for a promoted variable becomes a kill location if
+;; it used a fragment that can't be split (the first check directive below).
+;; NOTE: If createFragmentExpression gets smarter it may be necessary to create
+;; a new test case.
+
+; CHECK: if.then:
+; CHECK: dbg.value(metadata i32 poison, metadata ![[#]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32))
+;; FIXME: The value below should be poison. See https://reviews.llvm.org/D147431#4245260.
+; CHECK: dbg.value(metadata i32 %{{.*}}, metadata ![[#]], metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32))
+
+; CHECK: if.else:
+; CHECK: dbg.value(metadata i32 2, metadata ![[#]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32))
+; CHECK: dbg.value(metadata i32 0, metadata ![[#]], metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32))
+
+; CHECK: end:
+; CHECK: dbg.value(metadata i32 %{{.*}}, metadata ![[#]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32))
+
+declare i64 @get_i64()
+
+define internal fastcc i64 @fun() !dbg !18 {
+entry:
+  %codepoint = alloca i64, align 4, !DIAssignID !27
+  call void @llvm.dbg.assign(metadata i1 poison, metadata !15, metadata !DIExpression(), metadata !27, metadata ptr %codepoint, metadata !DIExpression()), !dbg !26
+   %0 = call i64 @get_i64() #2
+   %1 = add i64 %0, 1
+   %cmp = icmp ugt i64 %1, 100
+   br i1 %cmp, label %if.then, label %if.else
+
+if.then:
+  store i64 %1, ptr %codepoint, align 4, !DIAssignID !25
+  call void @llvm.dbg.assign(metadata i64 %1, metadata !15, metadata !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value), metadata !25, metadata ptr %codepoint, metadata !DIExpression()), !dbg !26
+  br label %end
+
+if.else:
+  store i64 2, ptr %codepoint, align 4, !DIAssignID !28
+  call void @llvm.dbg.assign(metadata i32 2, metadata !15, metadata !DIExpression(), metadata !28, metadata ptr %codepoint, metadata !DIExpression()), !dbg !26
+  br label %end
+
+end:
+  %r = load i32, ptr %codepoint
+  %rr = zext i32 %r to i64
+  ret i64 %rr
+}
+
+declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!13, !14}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 17.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, imports: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "reduce.cpp", directory: "/")
+!2 = !{}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+!14 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
+!15 = !DILocalVariable(name: "codepoint", scope: !18, file: !1, line: 10, type: !24)
+!18 = distinct !DISubprogram(name: "fun", linkageName: "fun", scope: !1, file: !1, line: 4, type: !19, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+!19 = distinct !DISubroutineType(types: !2)
+!24 = !DIBasicType(name: "long unsigned int", size: 64, encoding: DW_ATE_unsigned)
+!25 = distinct !DIAssignID()
+!26 = !DILocation(line: 0, scope: !18)
+!27 = distinct !DIAssignID()
+!28 = distinct !DIAssignID()


        


More information about the llvm-commits mailing list