diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -41,6 +41,7 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/PatternMatch.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" @@ -62,6 +63,7 @@ #define DEBUG_TYPE "basicaa" using namespace llvm; +using namespace PatternMatch; /// Enable analysis of recursive PHI nodes. static cl::opt EnableRecPhiAnalysis("basicaa-recphi", cl::Hidden, @@ -469,6 +471,11 @@ continue; } + Value *Loc; + if (match(Op, m_IntToPtr(m_Load(m_Value(Loc))))) { + Decomposed.Base = Loc; + return false; + } const GEPOperator *GEPOp = dyn_cast(Op); if (!GEPOp) { if (const auto *Call = dyn_cast(V)) { diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3720,6 +3720,11 @@ if (!V->getType()->isPointerTy()) return V; for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { + Value *Loc; + if (match(V, m_IntToPtr(m_Load(m_Value(Loc))))) { + return Loc; + } + if (GEPOperator *GEP = dyn_cast(V)) { V = GEP->getPointerOperand(); } else if (Operator::getOpcode(V) == Instruction::BitCast || diff --git a/llvm/test/Analysis/BasicAA/inttoptr.ll b/llvm/test/Analysis/BasicAA/inttoptr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/BasicAA/inttoptr.ll @@ -0,0 +1,47 @@ +; RUN: opt -basicaa -aa-eval -print-no-aliases < %s 2>&1 --disable-output | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +%struct.data = type <{ i64*, i64, [20 x i64] }> + +declare void @init(%struct.data** %ptr) + +; CHECK-LABEL: Function: test1 +; CHECK: NoAlias: i64* %base, i64* %gep.2 + +define void @test1(i64 %arg) { + %loc = alloca %struct.data*, align 8 + %base = bitcast %struct.data** %loc to i64* + call void @init(%struct.data** %loc ) + + %addr = load i64, i64* %base, align 8 + %ptr = inttoptr i64 %addr to %struct.data* + %offset.ptr = getelementptr inbounds %struct.data, %struct.data* %ptr, i64 0, i32 1 + %offset = load i64, i64* %offset.ptr, align 8, !range !13 + %gep.1 = getelementptr inbounds %struct.data, %struct.data* %ptr, i64 0, i32 2 + %gep.2 = getelementptr inbounds [20 x i64], [20 x i64]* %gep.1, i64 0, i64 %offset + store i64 1, i64* %gep.2, align 8 + ret void +} + + +; CHECK-LABEL: Function: test2 +; CHECK-NOT: NoAlias: i64* %base, i64* %gep.2 +define void @test2(i64 %arg) { + %loc = alloca %struct.data*, align 8 + %base = bitcast %struct.data** %loc to i64* + call void @init(%struct.data** %loc ) + + %addr = load i64, i64* %base, align 8 + %strip = and i64 %addr, 72057594037927928 + %ptr = inttoptr i64 %strip to %struct.data* + %offset.ptr = getelementptr inbounds %struct.data, %struct.data* %ptr, i64 0, i32 1 + %offset = load i64, i64* %offset.ptr, align 8, !range !13 + %gep.1 = getelementptr inbounds %struct.data, %struct.data* %ptr, i64 0, i32 2 + %gep.2 = getelementptr inbounds [20 x i64], [20 x i64]* %gep.1, i64 0, i64 %offset + store i64 1, i64* %gep.2, align 8 + ret void +} + + +!13 = !{i64 0, i64 20}