[llvm] ebab105 - [IR] Don't strip through pointer to vector of pointer bitcasts

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 00:48:06 PDT 2024


Author: Nikita Popov
Date: 2024-07-04T09:47:59+02:00
New Revision: ebab105670a409e426ddcb0278578711a622b1b2

URL: https://github.com/llvm/llvm-project/commit/ebab105670a409e426ddcb0278578711a622b1b2
DIFF: https://github.com/llvm/llvm-project/commit/ebab105670a409e426ddcb0278578711a622b1b2.diff

LOG: [IR] Don't strip through pointer to vector of pointer bitcasts

When using stripPointerCasts() and getUnderlyingObject(), don't
strip through a bitcast from ptr to <1 x ptr>, which is not a
no-op pointer cast. Calling code is generally not prepared to
handle that situation, resulting in incorrect alias analysis
results for example.

Fixes https://github.com/llvm/llvm-project/issues/97600.

Added: 
    llvm/test/Analysis/BasicAA/ptr-vector.ll

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/lib/IR/Value.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5476dc5d85182..258576f0cdff8 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6403,9 +6403,10 @@ const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup) {
       V = GEP->getPointerOperand();
     } else if (Operator::getOpcode(V) == Instruction::BitCast ||
                Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
-      V = cast<Operator>(V)->getOperand(0);
-      if (!V->getType()->isPointerTy())
+      Value *NewV = cast<Operator>(V)->getOperand(0);
+      if (!NewV->getType()->isPointerTy())
         return V;
+      V = NewV;
     } else if (auto *GA = dyn_cast<GlobalAlias>(V)) {
       if (GA->isInterposable())
         return V;

diff  --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 8522747ccf128..b2ee75811fbb7 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -652,9 +652,10 @@ static const Value *stripPointerCastsAndOffsets(
       }
       V = GEP->getPointerOperand();
     } else if (Operator::getOpcode(V) == Instruction::BitCast) {
-      V = cast<Operator>(V)->getOperand(0);
-      if (!V->getType()->isPointerTy())
+      Value *NewV = cast<Operator>(V)->getOperand(0);
+      if (!NewV->getType()->isPointerTy())
         return V;
+      V = NewV;
     } else if (StripKind != PSK_ZeroIndicesSameRepresentation &&
                Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
       // TODO: If we know an address space cast will not change the

diff  --git a/llvm/test/Analysis/BasicAA/ptr-vector.ll b/llvm/test/Analysis/BasicAA/ptr-vector.ll
new file mode 100644
index 0000000000000..7dea24fb5aba7
--- /dev/null
+++ b/llvm/test/Analysis/BasicAA/ptr-vector.ll
@@ -0,0 +1,12 @@
+; RUN: opt -print-all-alias-modref-info -passes=aa-eval -disable-output < %s 2>&1 | FileCheck %s
+
+; CHECK: MayAlias:	i8* %b, i8* %p
+; CHECK: Just Ref:  Ptr: i8* %p	<->  %v1p = call <1 x ptr> @llvm.masked.load.v1p0.p0(ptr %a, i32 8, <1 x i1> %c, <1 x ptr> poison)
+; CHECK: Just Ref:  Ptr: i8* %b	<->  %v1p = call <1 x ptr> @llvm.masked.load.v1p0.p0(ptr %a, i32 8, <1 x i1> %c, <1 x ptr> poison)
+define void @test(ptr %a, ptr %b, <1 x i1> %c) {
+  %v1p = call <1 x ptr> @llvm.masked.load.v1p0.p0(ptr %a, i32 8, <1 x i1> %c, <1 x ptr> poison)
+  %p = bitcast <1 x ptr> %v1p to ptr
+  load i8, ptr %p
+  store i8 0, ptr %b
+  ret void
+}


        


More information about the llvm-commits mailing list