diff --git a/llvm/lib/Transforms/Utils/GlobalStatus.cpp b/llvm/lib/Transforms/Utils/GlobalStatus.cpp index 0b3016a86e287..54a72824129b8 100644 --- a/llvm/lib/Transforms/Utils/GlobalStatus.cpp +++ b/llvm/lib/Transforms/Utils/GlobalStatus.cpp @@ -78,8 +78,14 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS, return true; } else { // Ignore dead constant users. - if (!isSafeToDestroyConstant(C)) - return true; + if (!isSafeToDestroyConstant(C)) { + if (CE) { + if (VisitedUsers.insert(CE).second) + if (analyzeGlobalAux(CE, GS, VisitedUsers)) + return true; + } else + return true; + } } } else if (const Instruction *I = dyn_cast(UR)) { if (!GS.HasMultipleAccessingFunctions) { @@ -166,9 +172,12 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS, if (MTI->getArgOperand(1) == V) GS.IsLoaded = true; } else if (const MemSetInst *MSI = dyn_cast(I)) { - assert(MSI->getArgOperand(0) == V && "Memset only takes one pointer!"); + if (MSI->getArgOperand(0) != V || MSI->getArgOperand(1) == V) + return true; if (MSI->isVolatile()) return true; + assert(MSI->getArgOperand(0) == V && + "First argument must be the pointer!"); GS.StoredType = GlobalStatus::Stored; } else if (const auto *CB = dyn_cast(I)) { if (CB->getIntrinsicID() == Intrinsic::threadlocal_address) { diff --git a/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll b/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll index 1e87d9266cb38..52bdc4343851a 100644 --- a/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll +++ b/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll @@ -12,8 +12,6 @@ declare i32 @fn1() define void @stores_single_use_gep_constexpr() { ; CHECK-LABEL: @stores_single_use_gep_constexpr( ; CHECK-NEXT: entry: -; CHECK-NEXT: store ptr @fn0, ptr @global.20ptr, align 8 -; CHECK-NEXT: store ptr @fn1, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR:%.*]], ptr @global.20ptr, i64 0, i32 1), align 8 ; CHECK-NEXT: ret void ; entry: diff --git a/llvm/test/Transforms/GlobalOpt/read-with-constexpr-users.ll b/llvm/test/Transforms/GlobalOpt/read-with-constexpr-users.ll index 9df31887102f2..1e39cac9722ca 100644 --- a/llvm/test/Transforms/GlobalOpt/read-with-constexpr-users.ll +++ b/llvm/test/Transforms/GlobalOpt/read-with-constexpr-users.ll @@ -5,15 +5,14 @@ @H = internal global [2 x i64 ] zeroinitializer ;. -; CHECK: @G = internal global [2 x i64] zeroinitializer +; CHECK: @G = internal constant [2 x i64] zeroinitializer ; CHECK: @H = internal global [2 x i64] zeroinitializer ;. define i64 @G_used_by_gep_inttoptr_exprs() { ; CHECK-LABEL: define i64 @G_used_by_gep_inttoptr_exprs() local_unnamed_addr { -; CHECK-NEXT: [[L:%.*]] = load i64, ptr @G, align 8 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @G, i64 16) to i64), i64 8) to ptr), i64 1 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[GEP]], @G -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 [[L]], i64 9 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 0, i64 9 ; CHECK-NEXT: ret i64 [[SEL]] ; %l = load i64, ptr @G, align 8