- 
                Notifications
    You must be signed in to change notification settings 
- Fork 15k
[DataLayout] Add isNullPointerAllZeroes #165314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add a function to check for a given address space if its null pointer has an all-zero bit representation.
| @llvm/pr-subscribers-llvm-ir Author: Robert Imschweiler (ro-i) ChangesAdd a function to check for a given address space if its null pointer has an all-zero bit representation. See #140802 (comment) Full diff: https://github.com/llvm/llvm-project/pull/165314.diff 2 Files Affected: 
 diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index 56fc749838ef9..b8dcd6647f877 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -398,6 +398,12 @@ class DataLayout {
            PS.HasExternalState;
   }
 
+  /// Returns if the null pointer for this address space has an all-zero bit
+  /// representation.
+  bool isNullPointerAllZeroes(unsigned AddrSpace) const {
+    return AddrSpace == 0;
+  }
+
   /// Returns whether this address space has an "unstable" pointer
   /// representation. The bitwise pattern of such pointers is allowed to change
   /// in a target-specific way. For example, this could be used for copying
diff --git a/llvm/unittests/IR/DataLayoutTest.cpp b/llvm/unittests/IR/DataLayoutTest.cpp
index 9ca88141ca0eb..d5336a89c5859 100644
--- a/llvm/unittests/IR/DataLayoutTest.cpp
+++ b/llvm/unittests/IR/DataLayoutTest.cpp
@@ -700,6 +700,15 @@ TEST(DataLayout, NonIntegralHelpers) {
   }
 }
 
+TEST(DataLayoutTest, IsNullPointerAllZeroes) {
+  EXPECT_TRUE(DataLayout("").isNullPointerAllZeroes(0));
+  EXPECT_FALSE(DataLayout("").isNullPointerAllZeroes(1));
+  EXPECT_TRUE(DataLayout("p:32:32").isNullPointerAllZeroes(0));
+  EXPECT_FALSE(DataLayout("p:32:32").isNullPointerAllZeroes(1));
+  EXPECT_TRUE(DataLayout("p:64:64").isNullPointerAllZeroes(0));
+  EXPECT_FALSE(DataLayout("p:64:64").isNullPointerAllZeroes(1));
+}
+
 TEST(DataLayoutTest, CopyAssignmentInvalidatesStructLayout) {
   DataLayout DL1 = cantFail(DataLayout::parse("p:32:32"));
   DataLayout DL2 = cantFail(DataLayout::parse("p:64:64"));
 | 
        
          
                llvm/include/llvm/IR/DataLayout.h
              
                Outdated
          
        
      | bool isNullPointerAllZeroes(unsigned AddrSpace) const { | ||
| return AddrSpace == 0; | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your suggestion of getNullPointerValue() is probably better, could do something like the following?
| bool isNullPointerAllZeroes(unsigned AddrSpace) const { | |
| return AddrSpace == 0; | |
| } | |
| std::optional<APInt> getNullPointerValue(unsigned AS) const { | |
| // Address space zero is currently defined to always have | |
| // a all-zero null pointer representation, the others are | |
| // target-specific and will require a data layout property. | |
| // See https://discourse.llvm.org/t/rfc-introduce-sentinel-pointer-value-to-datalayout | |
| if (AS == 0) | |
| return 0; | |
| return std::nullopt; | |
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, it probably doesn't matter too much what we use since it will have to change again for #131557 , the main thing I would like to see is avoiding ==0 checks which this patch achieves as is so IMO no need to do something generic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, see commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, race condition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you are trying to do here. The null pointer (as in ptr null) is always all-zeroes, no matter the address space. What differs by address space is whether the all-zeroes pointer is assumed to be non-dereferenceable by default.
Co-authored-by: Alexander Richardson <[email protected]>
| 
 It is. Making  (The only thing that's easy to do is allow specifying that null in certain address spaces is non-dereferenceable. But I don't think that's what you are trying to do?) | 
| 
 Yes and in fact the data layout change would be the last step after we have proper representation of the actual constant nullptr. I have something WIP locally but got stuck by the aggregate type. Just had some discussion with @arsenm this morning so will pick it up later. | 
| I mean, assuming that the value of null is 0 would be wrong, no matter how it's currently implemented, right? See https://llvm.org/docs/AMDGPUUsage.html#address-spaces, for example | 
| 
 It is correct at the LLVM IR level. The "NULL value" in this table presumably refers to  llvm-project/clang/lib/CodeGen/Targets/AMDGPU.cpp Lines 455 to 471 in 2f869c4 
 | 
| 
 yes, which is wrong, right? The code snippet you referenced also states this: "Currently LLVM assumes null pointers always have value 0, which results in incorrectly transformed IR." Except if you'd like to define  Or am I missing your point? | 
| The point is that introducing support for non-zero null pointers is a non-trivial IR change, which will require changes in multiple places. It's something we want to do, but it needs to be coordinated. Only introducing a DataLayout method for this creates the incorrect impression that non-zero null pointers are supported by LLVM. If you want to introduce this kind of method, the implementation should basically be  | 
| 
 I see, makes sense. 
 I think @arichardson's original point (#140802 (comment)) was that we shouldn't introduce additional hardcoded  | 
Add a function to check for a given address space if its null pointer has an all-zero bit representation.
See #140802 (comment)
Maybe something like
getNullPointerValuewould be more useful, but would depend on #131557 and the open questions around it.