[llvm] [NewGVN] Don't use returned arg in memory defining intrinsics (PR #161865)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 3 08:41:08 PDT 2025


https://github.com/ManuelJBrito created https://github.com/llvm/llvm-project/pull/161865

In NewGVN we value number memory versions, therefore simplifying a memory defining call to the returned argument is nonsensical.
fixes #159918

>From 354af47a7ad559c4aad9b4b278b2649885aab12d Mon Sep 17 00:00:00 2001
From: ManuelJBrito <manuel.brito at tecnico.ulisboa.pt>
Date: Fri, 3 Oct 2025 16:24:56 +0100
Subject: [PATCH] [NewGVN] Don't use returned arg in memory defining intrinsics

---
 llvm/lib/Transforms/Scalar/NewGVN.cpp   |  4 +++-
 llvm/test/Transforms/NewGVN/pr159918.ll | 21 +++++++++++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Transforms/NewGVN/pr159918.ll

diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 9d4fb79416596..561c5341e57de 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -1647,7 +1647,9 @@ NewGVN::performSymbolicPredicateInfoEvaluation(BitCastInst *I) const {
 NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(Instruction *I) const {
   auto *CI = cast<CallInst>(I);
   if (auto *II = dyn_cast<IntrinsicInst>(I)) {
-    if (auto *ReturnedValue = II->getReturnedArgOperand())
+    auto *ReturnedValue = II->getReturnedArgOperand();
+    auto *MemDef = dyn_cast_or_null<MemoryDef>(getMemoryAccess(I));
+    if (ReturnedValue && !MemDef)
       return ExprResult::some(createVariableOrConstant(ReturnedValue));
   }
 
diff --git a/llvm/test/Transforms/NewGVN/pr159918.ll b/llvm/test/Transforms/NewGVN/pr159918.ll
new file mode 100644
index 0000000000000..3fad6e66d11ac
--- /dev/null
+++ b/llvm/test/Transforms/NewGVN/pr159918.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=newgvn < %s | FileCheck %s
+
+; Don't use returned argument in memory defining intrinsics.
+define void @wombat(ptr %arg) {
+; CHECK-LABEL: define void @wombat(
+; CHECK-SAME: ptr [[ARG:%.*]]) {
+; CHECK-NEXT:    [[LOAD:%.*]] = load ptr, ptr [[ARG]], align 8
+; CHECK-NEXT:    [[CALL:%.*]] = call ptr @llvm.objc.retain(ptr [[LOAD]])
+; CHECK-NEXT:    store ptr [[CALL]], ptr [[ARG]], align 8
+; CHECK-NEXT:    ret void
+;
+  %load = load ptr, ptr %arg, align 8
+  %call = call ptr @llvm.objc.retain(ptr %load)
+  store ptr %call, ptr %arg, align 8
+  ret void
+}
+
+declare ptr @llvm.objc.retain(ptr returned) #0
+
+attributes #0 = { nounwind }



More information about the llvm-commits mailing list