[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