diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 85ebf694e69..51a295aa5b4 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -2026,12 +2026,22 @@ static Constant *computePointerICmp(const DataLayout *DL, }; // Is the set of underlying objects all things which must be disjoint from - // noalias calls. + // noalias calls. For allocas, we consider only static ones (dynamic + // allocas might be transformed into calls to malloc not simultaneously + // live with the compared-to allocation). For globals, we exclude symbols + // that might be resolve lazily to symbols in another dynamically-loaded + // library (and, thus, could be malloc'ed by the implementation). auto IsAllocDisjoint = [](SmallVectorImpl &Objects) { return std::all_of(Objects.begin(), Objects.end(), [](Value *V){ - if (isa(V) || isa(V)) - return true; + if (const AllocaInst *AI = dyn_cast(V)) + return AI->isStaticAlloca(); + if (const GlobalValue *GV = dyn_cast(V)) + return (GV->hasLocalLinkage() || + GV->hasHiddenVisibility() || + GV->hasProtectedVisibility() || + GV->hasUnnamedAddr()) && + !GV->isThreadLocal(); if (const Argument *A = dyn_cast(V)) return A->hasByValAttr(); return false; diff --git a/test/Transforms/InstSimplify/noalias-ptr.ll b/test/Transforms/InstSimplify/noalias-ptr.ll index e3435097880..7693e554235 100644 --- a/test/Transforms/InstSimplify/noalias-ptr.ll +++ b/test/Transforms/InstSimplify/noalias-ptr.ll @@ -3,6 +3,11 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @g1 = global i32 0, align 4 +@g2 = internal global i32 0, align 4 +@g3 = unnamed_addr global i32 0, align 4 +@g4 = hidden global i32 0, align 4 +@g5 = protected global i32 0, align 4 +@g6 = thread_local unnamed_addr global i32 0, align 4 ; Make sure we can simplify away a pointer comparison between ; dynamically-allocated memory and a local stack allocation. @@ -43,7 +48,7 @@ define void @_Z2p2bb(i1 zeroext %b1, i1 zeroext %b2) #0 { %mStackData = alloca [10 x i32], align 16 %1 = bitcast [10 x i32]* %mStackData to i8* %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0 - %3 = select i1 %b1, i32* %2, i32* @g1 + %3 = select i1 %b1, i32* %2, i32* @g2 %4 = tail call noalias i8* @_Znam(i64 48) #4 %5 = tail call noalias i8* @_Znam(i64 48) #4 %.v = select i1 %b2, i8* %4, i8* %5 @@ -64,6 +69,81 @@ define void @_Z2p2bb(i1 zeroext %b1, i1 zeroext %b2) #0 { ret void } +define void @_Z2p4bb(i1 zeroext %b1, i1 zeroext %b2) #0 { + %mStackData = alloca [10 x i32], align 16 + %1 = bitcast [10 x i32]* %mStackData to i8* + %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0 + %3 = select i1 %b1, i32* %2, i32* @g3 + %4 = tail call noalias i8* @_Znam(i64 48) #4 + %5 = tail call noalias i8* @_Znam(i64 48) #4 + %.v = select i1 %b2, i8* %4, i8* %5 + %6 = bitcast i8* %.v to i32* + %7 = icmp eq i32* %6, %3 + br i1 %7, label %9, label %8 + +; CHECK-LABEL: @_Z2p4bb +; CHECK-NOT: icmp +; CHECK: ret void + +;