Skip to content

[IR] Add a helper Function::isReturnNonNull #128107

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

Closed
wants to merge 1 commit into from

Conversation

dtcxzyw
Copy link
Member

@dtcxzyw dtcxzyw commented Feb 21, 2025

The code is copied from CallBase::isReturnNonNull. It is required by the follow-up of #127979.

@dtcxzyw dtcxzyw requested a review from nikic February 21, 2025 02:07
@llvmbot
Copy link
Member

llvmbot commented Feb 21, 2025

@llvm/pr-subscribers-llvm-ir

Author: Yingwei Zheng (dtcxzyw)

Changes

The code is copied from CallBase::isReturnNonNull. It is required by the follow-up of #127979.


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

2 Files Affected:

  • (modified) llvm/include/llvm/IR/Function.h (+5)
  • (modified) llvm/lib/IR/Function.cpp (+11)
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 29041688124bc..7ea8673bedad1 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -731,6 +731,11 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
   /// create a Function) from the Function Src to this one.
   void copyAttributesFrom(const Function *Src);
 
+  /// Return true if the return value is known to be not null.
+  /// This may be because it has the nonnull attribute, or because at least
+  /// one byte is dereferenceable and the pointer is in addrspace(0).
+  bool isReturnNonNull() const;
+
   /// deleteBody - This method deletes the body of the function, and converts
   /// the linkage to external.
   ///
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 5666f0a53866f..d22cf65769e26 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -873,6 +873,17 @@ void Function::copyAttributesFrom(const Function *Src) {
     setPrologueData(Src->getPrologueData());
 }
 
+bool Function::isReturnNonNull() const {
+  if (hasRetAttribute(Attribute::NonNull))
+    return true;
+
+  if (AttributeSets.getRetDereferenceableBytes() > 0 &&
+      !NullPointerIsDefined(this, getReturnType()->getPointerAddressSpace()))
+    return true;
+
+  return false;
+}
+
 MemoryEffects Function::getMemoryEffects() const {
   return getAttributes().getMemoryEffects();
 }

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM. Something you might want to consider though is that you could do different optimizations for both cases. In particular, for nonnull you can only look through inbounds gep, while for dereferenceable you can look through any gep. If you want to make use of that, then the helper is probably not going to be useful...

@dtcxzyw
Copy link
Member Author

dtcxzyw commented Feb 21, 2025

Interesting: https://alive2.llvm.org/ce/z/4RDBS8
Closed this PR until we need it in the future.

@dtcxzyw dtcxzyw closed this Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants