Skip to content

Conversation

@shiltian
Copy link
Contributor

@shiltian shiltian commented Feb 11, 2025

ConstantPointerNull represents a pointer with value 0, but it doesn’t
necessarily mean a nullptr. ptr addrspace(x) null is not the same as
addrspacecast (ptr null to ptr addrspace(x)) if the nullptr in AS X is not
zero. Therefore, we can't simply replace it.

Fixes #115083.

@llvmbot
Copy link
Member

llvmbot commented Feb 11, 2025

@llvm/pr-subscribers-backend-amdgpu

@llvm/pr-subscribers-llvm-transforms

Author: Shilei Tian (shiltian)

Changes

ConstantPointerNull represents a pointer with value 0, but it doesn’t
necessarily mean a nullptr. ptr addrspace(x) null is not the same as
addrspacecast (ptr null to ptr addrspace(x)) if the nullptr in AS x is not
zero. Therefore, we can't simply replace it.

Fixes #115083.


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/IPO/AttributorAttributes.cpp (+9)
  • (added) llvm/test/Transforms/Attributor/do-not-replace-addrspacecast-with-constantpointernull.ll (+39)
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 17e7fada1082762..143215ec91706b3 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -10970,6 +10970,15 @@ struct AAPotentialValuesImpl : AAPotentialValues {
       Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
       if (!NewV || NewV == &OldV)
         continue;
+      // FIXME: ConstantPointerNull represents a pointer with value 0, but it
+      // doesn’t necessarily mean a nullptr. `ptr addrspace(x) null` is not the
+      // same as `addrspacecast (ptr null to ptr addrspace(x))` if the nullptr
+      // in AS x is not zero. Therefore, we can't simply replace it.
+      if (isa<ConstantPointerNull>(NewV) && isa<ConstantExpr>(OldV)) {
+        auto &CE = cast<ConstantExpr>(OldV);
+        if (CE.getOpcode() == Instruction::AddrSpaceCast)
+          continue;
+      }
       if (getCtxI() &&
           !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
         continue;
diff --git a/llvm/test/Transforms/Attributor/do-not-replace-addrspacecast-with-constantpointernull.ll b/llvm/test/Transforms/Attributor/do-not-replace-addrspacecast-with-constantpointernull.ll
new file mode 100644
index 000000000000000..77eb5fed81d3cfa
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/do-not-replace-addrspacecast-with-constantpointernull.ll
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=attributor $s -o - | FileCheck %s
+
+define i32 @bar(ptr %p0, ptr addrspace(5) %p5) {
+; CHECK-LABEL: define i32 @bar(
+; CHECK-SAME: ptr nofree readonly captures(none) [[P0:%.*]], ptr addrspace(5) nofree readonly [[P5:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq ptr addrspace(5) [[P5]], addrspacecast (ptr null to ptr addrspace(5))
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[TMP0]], ptr [[P0]], ptr null
+; CHECK-NEXT:    switch i8 0, label %[[BB_2:.*]] [
+; CHECK-NEXT:      i8 0, label %[[BB_0:.*]]
+; CHECK-NEXT:      i8 1, label %[[BB_1:.*]]
+; CHECK-NEXT:    ]
+; CHECK:       [[BB_0]]:
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4
+; CHECK-NEXT:    ret i32 [[TMP2]]
+; CHECK:       [[BB_1]]:
+; CHECK-NEXT:    unreachable
+; CHECK:       [[BB_2]]:
+; CHECK-NEXT:    unreachable
+;
+entry:
+  %0 = icmp eq ptr addrspace(5) %p5, addrspacecast (ptr null to ptr addrspace(5))
+  %1 = select i1 %0, ptr %p0, ptr null
+  switch i8 0, label %bb.2 [
+  i8 0, label %bb.0
+  i8 1, label %bb.1
+  ]
+
+bb.0:                                             ; preds = %entry
+  %2 = load i32, ptr %1, align 4
+  ret i32 %2
+
+bb.1:                                             ; preds = %entry
+  ret i32 0
+
+bb.2:                                             ; preds = %entry
+  ret i32 1
+}

@shiltian shiltian requested review from arsenm and jdoerfert February 11, 2025 18:56
@shiltian shiltian force-pushed the users/shiltian/do-not-replace-addrspacecast-with-constantpointernull branch from 6ae31b3 to 23d8876 Compare February 11, 2025 19:13
Copy link
Contributor Author

@shiltian shiltian force-pushed the users/shiltian/do-not-replace-addrspacecast-with-constantpointernull branch 2 times, most recently from dcd5a83 to 93c20b2 Compare February 14, 2025 05:36
@shiltian
Copy link
Contributor Author

Ping.

AFAICT, only ConstantPointerNull matters here because it represents null in all AS. For the others, they are not constant thus will not be replaced by this code path.

@shiltian
Copy link
Contributor Author

This will be properly resolved after #131557 (as well as its follow-up patches).

@shiltian shiltian changed the title [Attributor] Don't replace AddrSpaceCast with ConstantPointerNull [Attributor] Don't replace addrspacecast (ptr null to ptr addrspace(x)) with ptr addrspace(x) null May 15, 2025
@shiltian shiltian force-pushed the users/shiltian/do-not-replace-addrspacecast-with-constantpointernull branch from 93c20b2 to 48eff91 Compare May 15, 2025 17:28
@shiltian shiltian force-pushed the users/shiltian/do-not-replace-addrspacecast-with-constantpointernull branch from 48eff91 to fe5e442 Compare May 15, 2025 17:38
@shiltian
Copy link
Contributor Author

I figured it's gonna take much longer time to change the semantics of ConstantPointerNull as well as all related stuff, so I pushed an alternative solution here.

@shiltian shiltian force-pushed the users/shiltian/do-not-replace-addrspacecast-with-constantpointernull branch 2 times, most recently from e7c3060 to 48ae8cd Compare May 15, 2025 20:24
@shiltian shiltian requested review from arsenm and nikic May 19, 2025 14:18
@shiltian shiltian force-pushed the users/shiltian/do-not-replace-addrspacecast-with-constantpointernull branch from 48ae8cd to ec76d44 Compare May 20, 2025 15:16
Copy link
Member

@jdoerfert jdoerfert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super convinced but it seems necessary for now.
LG

@shiltian shiltian force-pushed the users/shiltian/do-not-replace-addrspacecast-with-constantpointernull branch from ec76d44 to 2bbd606 Compare May 20, 2025 16:03
`ConstantPointerNull` represents a pointer with value 0, but it doesn’t
necessarily mean a nullptr. `ptr addrspace(x) null` is not the same as
`addrspacecast (ptr null to ptr addrspace(x))` if the nullptr in AS x is not
zero. Therefore, we can't simply replace it.

Fixes #115083.
@shiltian shiltian force-pushed the users/shiltian/do-not-replace-addrspacecast-with-constantpointernull branch from 2bbd606 to 7be9429 Compare May 20, 2025 16:11
@shiltian shiltian merged commit d299242 into main May 20, 2025
11 checks passed
@shiltian shiltian deleted the users/shiltian/do-not-replace-addrspacecast-with-constantpointernull branch May 20, 2025 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[AMDGPU] Sprintf test fails after amdgpu-attributor pass

6 participants