<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/105571>105571</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [DebugInfo] Assertion failure `!NodePtr->isKnownSentinel()' when fixing up debug info
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            debuginfo
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          jonathonpenix
      </td>
    </tr>
</table>

<pre>
    I'm seeing a failed assert '!NodePtr->isKnownSentinel()' when debug info is being handled as part of the BasicBlock `splice()` API. I think we are able to dereference an `end()` iterator (`Dest`) here under certain circumstances:

https://github.com/llvm/llvm-project/blob/47e0212f00f707a4bb92714afe9c748116887d62/llvm/lib/IR/BasicBlock.cpp#L974

I was originally seeing this with a pass that is not upstream, but please see below for a unittest that should demonstrate the issue using only upstream LLVM. I tested this using LLVM at f7bbc40b0736cc417f57cd039b098b504cf6a71f and apologies in advance if there is just something wrong in my test!

Test in commit form: https://github.com/jonathonpenix/llvm-project/commit/fab9bba951263ee4b51a1749e43112d70fd068f5

Test in text-form:
```
diff --git a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
index 91a0745a0cc7..108e4b1f8ad8 100644
--- a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
+++ b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
@@ -1525,4 +1525,103 @@ TEST(BasicBlockDbgInfoTest, DbgMoveToEnd) {
 EXPECT_FALSE(Ret->hasDbgRecords());
 }

+// This fails with an assert: "Assertion `!NodePtr->isKnownSentinel()' failed."
+//
+// Original C source:
+//
+// int foo(int fd) { return fd; }
+// int (* arr[2])(int fd) = { foo };
+// int bar(int id, int arg) {
+//  int ret = arr[id](arg);
+//  return ret;
+// }
+//
+// Build command used: clang --target=armv7m-none-eabi -Oz -g -mcpu=cortex-m3 -mthumb -mabi=aapcs -c comm_reduce.c -emit-llvm
+TEST(BasicBlockDbgInfoTest, DbgKnownSentinelCrash) {
+  LLVMContext C;
+  std::unique_ptr<Module> M = parseIR(C, R"---(
+    @arr = dso_local local_unnamed_addr global [2 x ptr] [ptr @foo, ptr null], align 4, !dbg !0
+
+    ; Function Attrs: minsize mustprogress nofree norecurse nosync nounwind optsize willreturn memory(none)
+    define dso_local noundef i32 @foo(i32 noundef returned %fd) #0 !dbg !19 {
+    entry:
+        #dbg_value(i32 %fd, !21, !DIExpression(), !22)
+      ret i32 %fd, !dbg !23
+    }
+
+ ; Function Attrs: minsize nounwind optsize
+    define dso_local i32 @bar(i32 noundef %id, i32 noundef %arg) local_unnamed_addr #1 !dbg !24 {
+ entry:
+        #dbg_value(i32 %id, !28, !DIExpression(), !31)
+ #dbg_value(i32 %arg, !29, !DIExpression(), !31)
+      %arrayidx = getelementptr inbounds [2 x ptr], ptr @arr, i32 0, i32 %id, !dbg !32
+ %0 = load ptr, ptr %arrayidx, align 4, !dbg !32, !tbaa !33
+      %call = tail call i32 %0(i32 noundef %arg) #2, !dbg !32
+        #dbg_value(i32 %call, !30, !DIExpression(), !31)
+      ret i32 %call, !dbg !37
+ }
+
+    attributes #0 = { minsize mustprogress nofree norecurse nosync nounwind optsize willreturn memory(none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+armv7-m,+hwdiv,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
+    attributes #1 = { minsize nounwind optsize "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+armv7-m,+hwdiv,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
+    attributes #2 = { minsize nounwind optsize }
+
+ !llvm.dbg.cu = !{!2}
+    !llvm.module.flags = !{!12, !13, !14, !15, !16, !17}
+
+    !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+    !1 = distinct !DIGlobalVariable(name: "arr", scope: !2, file: !3, line: 3, type: !5, isLocal: false, isDefinition: true)
+    !2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
+ !3 = !DIFile(filename: "t.c", directory: "/")
+    !4 = !{!0}
+ !5 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 64, elements: !10)
+    !6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32)
+    !7 = !DISubroutineType(types: !8)
+    !8 = !{!9, !9}
+    !9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+    !10 = !{!11}
+    !11 = !DISubrange(count: 2)
+ !12 = !{i32 7, !"Dwarf Version", i32 5}
+    !13 = !{i32 2, !"Debug Info Version", i32 3}
+    !14 = !{i32 1, !"wchar_size", i32 4}
+ !15 = !{i32 1, !"min_enum_size", i32 4}
+    !16 = !{i32 7, !"frame-pointer", i32 2}
+    !17 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
+    !19 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 1, type: !7, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !20)
+ !20 = !{!21}
+    !21 = !DILocalVariable(name: "fd", arg: 1, scope: !19, file: !3, line: 1, type: !9)
+    !22 = !DILocation(line: 0, scope: !19)
+    !23 = !DILocation(line: 1, column: 19, scope: !19)
+    !24 = distinct !DISubprogram(name: "bar", scope: !3, file: !3, line: 5, type: !25, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !27)
+    !25 = !DISubroutineType(types: !26)
+    !26 = !{!9, !9, !9}
+    !27 = !{!28, !29, !30}
+    !28 = !DILocalVariable(name: "id", arg: 1, scope: !24, file: !3, line: 5, type: !9)
+    !29 = !DILocalVariable(name: "arg", arg: 2, scope: !24, file: !3, line: 5, type: !9)
+    !30 = !DILocalVariable(name: "ret", scope: !24, file: !3, line: 6, type: !9)
+    !31 = !DILocation(line: 0, scope: !24)
+    !32 = !DILocation(line: 6, column: 12, scope: !24)
+    !33 = !{!34, !34, i64 0}
+    !34 = !{!"any pointer", !35, i64 0}
+    !35 = !{!"omnipotent char", !36, i64 0}
+    !36 = !{!"Simple C/C++ TBAA"}
+    !37 = !DILocation(line: 7, column: 2, scope: !24)
+ )---");
+  ASSERT_TRUE(M);
+
+  Function *F = M->getFunction("bar");
+  BasicBlock &BB = F->getEntryBlock();
+
+ // Find %call
+  auto I = std::prev(BB.end(), 2);
+
+  BasicBlock *NewBB = BasicBlock::Create(C, "NewBB", F);
+  BasicBlock *NewBB2 = BasicBlock::Create(C, "NewBB2", F);
+
+  NewBB->splice(NewBB->end(), &BB, std::next(I), BB.end());
+  NewBB2->splice(NewBB2->end(), &BB, I, BB.end());
+
+  llvm::dbgs() << "Didn't crash!\n";
+ ASSERT_TRUE(true);
+}
+
 } // End anonymous namespace.
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWltzozq2_jXKyypSILCxH_LgS7wrNd29uzqZPectJWCBtRskjiRy2b_-lISwsU3SyZ46VfMwqZQRIH3ronUTEtOaVwLxhszWZLa9Yp3ZS3XzpxTM7KVoUfCXq0wWrzd3hKYNaEQuKmBQMl5jAUxrVAYITQmNvskCvxsVkPiW638I-SzuURgusCZ0QeiS0BSe9yigwKyrgItSAteQOcg9E0WPCC1TBmQJZo-wZprn61rmP4HMQ93WPEePNg9h9f3uGu7A7Ln4Cc8ITCGwrEYwEgpUWKJCkSMwYUejKI5DuUHFjFRgH83DLWpD5iGhS9ijQuhEgQpyVIZxATlXeddow0SOmsQrEm5J6H_3xrTuGd0Ruqu42XfZdS4bQnd1_TRcglbJPzE3hO6yWmaE7pIUQxrRMgzLNExZkmVLmkYJK3GZp8kiiuaLRVrM6QiH23F3PwjdHdVynbctofGXZZqMubqDZ6ZBKl5xwer6dZg5s-canrnZA4OWaQ1mz4ydBSENdK02CllD6AayzkBbI9Noh0KGtXyGUipg0AluDGrTj9V72dUFFNhIoY1iBt3Eca07hE5bolLUrwdw-PLlj69u1lAbLHqO-n72DTADZZpleRJmYRrP8zyJ0nKW5kUYL7NwuchmYZKXc5ZGJTBRAGtlLSuOGrgAVjzZOQLurEdZNuDPThvQskFrJhU8Kyms8UHz6lggNBor7sEKZqdcNg03VuKGxCt4Z5ZPnOVyunsgQncly5ZZxpaziM5jxCSbRSxKkyUmcRTRIg3LIpwvytkUNwZfTOB58e_nof93twUvSwiCihtgR4sZZkpf2s02q-5EKS0Ba0KQ_Z1RPW0uCnyBZcTCNJmxMM_T6-soXGCSReWCFQuIwnCeePMMguDvcejFpuv-_99hmCQhSUIIohmdEbpJgNC1b0dhDP71w-39A6GLSSzrIdus-iqf8EHe2riyBJKue3i4_Z_vt5uHx93qy_0toYsfaGxM3DO9zaofmEtV6CEiLkk8jCLpdjz1TkxrbPBgPcQG3MFzhY-71jAJpSt3w6ULch-Mw338viaUnlE7J_67DyGwAS07lePRAt8awoX1G0nowrUG5YBC0ylhH8TrkbQn4xyHK2BKkdmaktnW8TsGircOrJTSYQzqO4XJmPKjeGHnyraYqk6m6TjCvVZoHHhPmheO9qIfNEFlkEahmXh7Kd15j3XH68JFGRvEOo2Fnc28ZqKCIDBMVRZ4y1TzlDaBkAIDZBmH4Pe_IKggaPK2I_E2l8rgS9DEEDRm3zUZBA3LuB3J2lxDkDsajwqLLsfrHAJsuAmc4wwcfcDQT6xoo5jen6sSXPTeSGFDFWzGOgHQxkpH4lUn-P92-NgaReLNV1l0NZL4Fr46zbdMabT-u9hYsj8IpUEQWIs4IoH1TqaUG1Bo-VjLnNXgfh87IViDxSMrCgVVLTNWgzUjeAFLcba1d61RFsMZ6MY-B9HVtZvtDbCaVwIS2yQ0KrLKXsLj3J0wEq9h14nced7KGGXzAzRcaP4XQtNp0ypZKdQ2uZYKEYRUmHdK25Z-FTkI2YlnLgqQrXGjnnlde8NqsJHqldCFnXtrg2PaBZZc4EgBFqnAEnhMD9It7M3wokfFAgideU-icTiSMjqfTwAURr2O_R38H6FxkVWPT6zu0NPxsE5vNPKN7d3tS2s1wKUYYk_fg55L5BwKzpE8bzQ-1fzYuw4v3p-Pc1W_r06vRh9GRmokdOYjyulDH1wm7JDQOBqLkpyq-ZM65gcdL36l4zg60fE0nuO7B1x-EtBzOWNKsVdevDiXrNBgjQ0KYz2Li8yqSJ964eB3vScPygyHxlhKr7SYjuWYhY5ULVnhEAe4IytvunJM_b3JGHMP4kuBclbXjoJhvAZ35_kKL61hyCr0AD3B87tTagkMGg7_zhyMHGeENbCRjlQ36TcAwIxRPOsMah8VfJL9fwtmtmwpFWswaCUXBpUtROItodQJYGWhQgZGsbblogoaZvaHLkZZ9bk-2rD8py22DeZGqiDryhJV4Bx86L7wffucGti8Obw6ZM_TLiUy0ynUh36Erl0iDuzSiND1_rngT33TJd2gkQUSugmYHbQJsjKa22teYN6Gh1Z0aNFDKz60kkNrdmgdUVLXUnl_eW2NTV9B4awuKKSdnsI1dWsvZRtYjhfjdtEzNbo97TvcDd2iednUfXOe9FeFlROw7Op66OiUYRHsDV807urWuJugeUJ_uS4dukBr0JugZXlmuG0p5hC166_3zAn0VLaHa8_WU9mryl69IL55fH9oJcP12DMZ90xsi574w6UbRBducGHh_7Xi_1rxf7gV0w9Y8XQ5RSO7Srgusuo673oUGtnahUb0nObQuXEl_XVZs0qfDomG9BjFQ2PIzdFsaMyHRvpmqrL1-IC8vfvNFfl_MMVZVuNJznxiql8fR64axZd2uJ9KrstzIr33F1wbLnIzRc1mM9agX4S7SsbJqHPZ-qe90CWvh3sne82Fu3c35vXQ2amB6y-2hrSPSlZr7J9tbYHKbWVrX_Sh44JlOsHyRjYtr_GfghtCF3Z12bHKEdz-6_HL6ttvj5teP-dMWk_scvQ6o142rn9vDW_4X_1ytWdkA6oThjf4ByrtWXSFDDbcKfkfXLjuu66ut5h1ruTs12fa03S2oNuaG9fhTtRccFGdqMFq-8FqfsD7dr4ysswfjWPH3SRZyUYTZa5zL0zBlYu3rwcZd-RyYWKZOzXl8MT67cQdaVp9S80NPth5pQvDKq_sh9Vvj64-fXRTTjeQMd1361XgjN_F_HgFLlSBL6UHJUXhBHPzI_EtKv6ExSRpn6HeIp6OicdTSkiPdO67TMnOcHGQ8rXFgcnFxNjFqQKHYnY5EUaWRzLug4SnMJpALszgaSN-N4Ail4W3me2_HlcPt49uc6OY8u7wLDpFE6z4GHAQmYnKspLLTrhPb_Tc9rwH9qi2Ik-9oITS7TNTJQwe4r0ppjCbIhyf4dARjts7uROlnACLp8CSM7DoCPac75l6HOoMD5Kcm_fRvi8RGi4eUXTN-yCek_nb6rkoozzOVKY5muIljttaCrgoZdDvbVn_sRVY_tOahgeO-sg1Ab2ciKH3XeYWP6w5NUT3keUi5MfvhfzoLOSnh9Ffxj1c_nR2fLerWfVdSSPtqAJIuvEPV3W9YXWtt6hzxTMs-gi6Ow69_25vjqnDD-4fH-M43bgdnXHGUmgYF1h8k8XBr2l4bu70zInolBPRkRO5zDadPsvCq9Kupwc1jNXaB42P6nUqo1N6yonp0_8AEU5RvASJ3wVxfOSy7hqXBXumfw2afMLq3Depz1nd7Ew7bqfj1Oxm_7Fml04pbPbBZETnU6Pnb6Wjt9MSTc9sfXH-2SwOp4YtPmT9_FfWT5PPzO-kjS0_xIn7nDVm5bKk_bdZicMPsaLQTFXU75Kff4R89Lk4YClegrwfTOZncWBSjEvQ-NTI4mGF1Df4PIEpI4vP6lM7jeIVTpOp7Td7F2V2gSIbwVtpUBiwhcIIaf4u0vwC6Z43bY2wIXS38fu3D-vVyiJOjE_f1W16qttfqZbQpdtFomf7eACr-_vbHw-PDz_-eUvo4uv5Pt-x42FXgdDVzvH2NSDxbYVmeOOWkYfQfEZnfIaFztdrh7DzCLfCqFf30i9FJ1nwm4Y7u2wfPvMeCbDOSLhzsIedtlbhE6GL9fr6eOyFbuCcu7fYXH3DZ8_p8XmPvFHIDA67dIRS19Ubx-596XtY-glc-gbwiILrZ9V5OB50eHIiu1O-s5ZBSQJf7LL4znc4VdaZHD03l2To23TufgE6Qncbso6nIqv86QAg8YbEThVbXghCUwN5v_cakdnGFf5jFk_tefhIMKZ38VEFSLodjOtWFMCEFK-N7LRbbOuW5Xh9dt7kqriJi2W8ZFd4E6U0ofM0TmdX-5s4YcswSxM6nxU0YukyiTK2SBZ5uMzyebq84jc0pEm4sFVQuIxn10ijYkbnWRwuinlBI5KE2DBeX7tvSVJVV-4U0U0UzmZpdFWzDGvtjqr5Qt_W-VYLs-2VunHnbrKu0iQJa66NPsIYbmp3xs1_XCglmW3heG6iZLzuFH7i_IQ7x1byFy4q6NrRibarTtU3nz4T5uTUhO68qE839P8CAAD__zPhC-k">