[llvm] [CallSiteSplitting] Don't copy !llvm.loop metadata to split block (PR #138974)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 7 14:46:10 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Bill Schmidt (wjschmidt)

<details>
<summary>Changes</summary>

The call-site splitting pass uses the utility function DuplicateInstructionsInSplitBetween to split predecessor blocks. This utility copies branch metadata from the predecessor block's terminator to the split block terminator.  When the predecessor is a loop latch, this results in !llvm.loop metadata being added to a non-latching branch.  This patch detects the situation and erases the offending metadata.

---
Full diff: https://github.com/llvm/llvm-project/pull/138974.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp (+6) 
- (added) llvm/test/Transforms/CallSiteSplitting/loop-metadata.ll (+44) 


``````````diff
diff --git a/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp b/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp
index 2e955e061111f..4f11f3de469cf 100644
--- a/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp
+++ b/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp
@@ -328,6 +328,12 @@ static void splitCallSite(CallBase &CB,
         DTU);
     assert(SplitBlock && "Unexpected new basic block split.");
 
+    // The split block shouldn't inherit !llvm.loop metadata.
+    Instruction *SplitTerm = SplitBlock->getTerminator();
+    SplitTerm->eraseMetadataIf([](unsigned MDKind, MDNode *Node) {
+      return MDKind == LLVMContext::MD_loop;
+    });
+
     auto *NewCI =
         cast<CallBase>(&*std::prev(SplitBlock->getTerminator()->getIterator()));
     addConditions(*NewCI, Preds[i].second);
diff --git a/llvm/test/Transforms/CallSiteSplitting/loop-metadata.ll b/llvm/test/Transforms/CallSiteSplitting/loop-metadata.ll
new file mode 100644
index 0000000000000..ae680be669804
--- /dev/null
+++ b/llvm/test/Transforms/CallSiteSplitting/loop-metadata.ll
@@ -0,0 +1,44 @@
+; Verify that we don't add incorrect llvm.loop metadata to a
+; non-latching branch.
+
+; RUN: opt -passes=callsite-splitting -S < %s 2>&1 | FileCheck %s
+
+; CHECK-NOT: br label %x{{.*}}, !llvm.loop !0
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define internal void @foo(i1 %0, i1 %1, i1 %2) {
+  br i1 %0, label %x1, label %x2
+
+x1:
+  br label %x16
+
+x2:
+  br label %x16
+
+x16:
+  %x17 = phi i32 [ 0, %x1 ], [ 1, %x2 ]
+  br i1 %1, label %x55, label %x46
+
+x46:
+  %x47 = icmp eq i32 %x17, 0
+  br i1 %x47, label %x49, label %x48
+
+x48:
+  br i1 %2, label %x49, label %x48, !llvm.loop !0
+
+x49:
+  %x50 = tail call fastcc i32 @func1(i32 noundef %x17)
+  br label %x55
+
+x55:
+  ret void
+}
+
+define internal fastcc i32 @func1(i32 noundef %0) unnamed_addr {
+  ret i32 13
+}
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.mustprogress"}

``````````

</details>


https://github.com/llvm/llvm-project/pull/138974


More information about the llvm-commits mailing list