[llvm] [IPSCCP] Don't replace with constant if Value is noalias ptr or derivatives (PR #154522)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 22 12:11:49 PDT 2025


https://github.com/choikwa updated https://github.com/llvm/llvm-project/pull/154522

>From 86ad532a7df8572b56b4fbf43b7dccf0b507b299 Mon Sep 17 00:00:00 2001
From: Kevin Choi <kevin.choi at amd.com>
Date: Wed, 20 Aug 2025 07:09:42 -0500
Subject: [PATCH 1/2] [IPSCCP] Don't replace with constant if Value is noalias
 ptr or derivatives

This was motivated from looking at composable kernel benchmark where IPSCCP was observed replacing noalias ptr's and their derivatives with a global alias.
Doing so would lose the noalias information and target backend was more pessimistic, emitting unneeded WAITCNT instructions.
---
 llvm/lib/Transforms/Utils/SCCPSolver.cpp | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 84485176ad4ff..3c06452a91f36 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -62,6 +62,21 @@ bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
   Constant *Const = getConstantOrNull(V);
   if (!Const)
     return false;
+
+  // Don't replace noalias arg or derivatives
+  if (isa<PointerType>(V->getType())) {
+    SmallVector<const Value *, 4> Objects;
+    getUnderlyingObjects(V, Objects, nullptr);
+
+    for (const auto Obj : Objects) {
+      if (const auto *Arg = dyn_cast<Argument>(Obj)) {
+        if (isa<PointerType>(Arg->getType()) &&
+            Arg->hasNoAliasAttr())
+          return false;
+      }
+    }
+  }
+
   // Replacing `musttail` instructions with constant breaks `musttail` invariant
   // unless the call itself can be removed.
   // Calls with "clang.arc.attachedcall" implicitly use the return value and

>From e765ee88d2ad50b42cd11391d7ca1bc053841485 Mon Sep 17 00:00:00 2001
From: Kevin Choi <kevin.choi at amd.com>
Date: Fri, 22 Aug 2025 14:08:27 -0500
Subject: [PATCH 2/2] Add testcase that looks for alias.scope on store

---
 .../Transforms/SCCP/ipsccp-noalias-check.ll   | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 llvm/test/Transforms/SCCP/ipsccp-noalias-check.ll

diff --git a/llvm/test/Transforms/SCCP/ipsccp-noalias-check.ll b/llvm/test/Transforms/SCCP/ipsccp-noalias-check.ll
new file mode 100644
index 0000000000000..fd9c43d407cce
--- /dev/null
+++ b/llvm/test/Transforms/SCCP/ipsccp-noalias-check.ll
@@ -0,0 +1,47 @@
+; RUN: opt < %s -passes='ipsccp,inline' -S | FileCheck %s
+
+; This test looks if the store from callee after inlining gets the alias.scope
+; If IPSCCP ignores noalias %p ptr and replaces %add.ptr5's GEP %p with @arr,
+; the store will not receive an alias.scope as noalias attribute is lost.
+ at arr = global [100 x i32] zeroinitializer, align 16
+
+define void @caller(i32 noundef %c, i32 noundef %d) #0 {
+; COM: Check that store has both !alias.scope and !noalias
+; CHECK-LABEL: for.body.i:
+; CHECK:  store {{.*}}!alias.scope{{.*}}!noalias
+entry:
+  %idx.ext = sext i32 %d to i64
+  %add.ptr = getelementptr inbounds i32, ptr @arr, i64 %idx.ext
+  %add.ptr4 = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext
+  call void @callee(ptr noundef @arr, ptr noundef %add.ptr, ptr noundef %add.ptr4, i32 noundef %d)
+  ret void
+}
+
+define void @callee(ptr noalias noundef %p, ptr noalias noundef %q, ptr noalias noundef %r, i32 noundef %len) #1 align 2 {
+entry:
+  br label %for.cond
+for.cond:                                         ; preds = %for.body, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  %cmp = icmp slt i32 %i.0, %len
+  br i1 %cmp, label %for.body, label %for.end
+for.body:                                         ; preds = %for.cond
+  %idx.ext = sext i32 %i.0 to i64
+  %add.ptr = getelementptr inbounds i32, ptr %q, i64 %idx.ext
+  %0 = load i32, ptr %add.ptr, align 4
+  %add.ptr3 = getelementptr inbounds i32, ptr %r, i64 %idx.ext
+  %1 = load i32, ptr %add.ptr3, align 4
+  %mul = mul nsw i32 %0, %1
+  %add = add nsw i32 %mul, %i.0
+  %add.ptr5 = getelementptr inbounds i32, ptr %p, i64 %idx.ext
+  store i32 %add, ptr %add.ptr5, align 4
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
+
+attributes #0 = { mustprogress uwtable}
+attributes #1 = { mustprogress nounwind uwtable }
+
+



More information about the llvm-commits mailing list