[PATCH] D153790: [ValueTracking] Add option to ignore ptrmask in getUnderlyingObject*

Krzysztof Drewniak via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 26 10:40:59 PDT 2023


krzysz00 created this revision.
Herald added subscribers: hiraditya, arichardson.
Herald added a project: All.
krzysz00 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

In some cases (an upcoming pass of mine that deals with a non-integral
address space) we want getUnderlyingObject() to regard the result of a
ptrmask() or other similar intrinsic that performs arbitrary bit
manipulation on a pointer to be considered a new object for analysis
purposes.

This commit supports this usecase by adding AllowBitManipulation as an
option to getUnderlyingObject*(). It will not break existing code
because the option defaults to true, which preserves the existing
behavior.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153790

Files:
  llvm/include/llvm/Analysis/ValueTracking.h
  llvm/lib/Analysis/ValueTracking.cpp


Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -5712,7 +5712,8 @@
   return true;
 }
 
-const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup) {
+const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup,
+                                       bool AllowBitManipulation) {
   if (!V->getType()->isPointerTy())
     return V;
   for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
@@ -5743,8 +5744,11 @@
         // be marked with returns attribute), it is crucial to use this function
         // because it should be in sync with CaptureTracking. Not using it may
         // cause weird miscompilations where 2 aliasing pointers are assumed to
-        // noalias.
-        if (auto *RP = getArgumentAliasingToReturnedPointer(Call, false)) {
+        // noalias. If bit manipulation is forbidden, then intrinsics that do
+        // not preserve the null pointer, namely ptrmask, count as a new
+        // underlying object.
+        if (auto *RP = getArgumentAliasingToReturnedPointer(
+                Call, !AllowBitManipulation)) {
           V = RP;
           continue;
         }
@@ -5759,13 +5763,14 @@
 
 void llvm::getUnderlyingObjects(const Value *V,
                                 SmallVectorImpl<const Value *> &Objects,
-                                LoopInfo *LI, unsigned MaxLookup) {
+                                LoopInfo *LI, unsigned MaxLookup,
+                                bool AllowBitManipulation) {
   SmallPtrSet<const Value *, 4> Visited;
   SmallVector<const Value *, 4> Worklist;
   Worklist.push_back(V);
   do {
     const Value *P = Worklist.pop_back_val();
-    P = getUnderlyingObject(P, MaxLookup);
+    P = getUnderlyingObject(P, MaxLookup, AllowBitManipulation);
 
     if (!Visited.insert(P).second)
       continue;
Index: llvm/include/llvm/Analysis/ValueTracking.h
===================================================================
--- llvm/include/llvm/Analysis/ValueTracking.h
+++ llvm/include/llvm/Analysis/ValueTracking.h
@@ -646,9 +646,12 @@
 /// the specified value, returning the original object being addressed. Note
 /// that the returned value has pointer type if the specified value does. If
 /// the MaxLookup value is non-zero, it limits the number of instructions to
-/// be stripped off.
-const Value *getUnderlyingObject(const Value *V, unsigned MaxLookup = 6);
-inline Value *getUnderlyingObject(Value *V, unsigned MaxLookup = 6) {
+/// be stripped off. This will look through llvm.ptrmask unless
+/// AllowBitManipulation is false.
+const Value *getUnderlyingObject(const Value *V, unsigned MaxLookup = 6,
+                                 bool AllowBitManipulation = true);
+inline Value *getUnderlyingObject(Value *V, unsigned MaxLookup = 6,
+                                  bool AllowBitManipulation = true) {
   // Force const to avoid infinite recursion.
   const Value *VConst = V;
   return const_cast<Value *>(getUnderlyingObject(VConst, MaxLookup));
@@ -682,9 +685,11 @@
 /// Since A[i] and A[i-1] are independent pointers, getUnderlyingObjects
 /// should not assume that Curr and Prev share the same underlying object thus
 /// it shouldn't look through the phi above.
+///
 void getUnderlyingObjects(const Value *V,
                           SmallVectorImpl<const Value *> &Objects,
-                          LoopInfo *LI = nullptr, unsigned MaxLookup = 6);
+                          LoopInfo *LI = nullptr, unsigned MaxLookup = 6,
+                          bool AllowBitManipulation = true);
 
 /// This is a wrapper around getUnderlyingObjects and adds support for basic
 /// ptrtoint+arithmetic+inttoptr sequences.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153790.534642.patch
Type: text/x-patch
Size: 3813 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230626/c67898aa/attachment.bin>


More information about the llvm-commits mailing list