diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h --- a/llvm/include/llvm/Analysis/MemoryBuiltins.h +++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h @@ -119,8 +119,8 @@ }); /// If this is a call to an allocation function that initializes memory to a -/// fixed value, return said value in the requested type. Otherwise, return -/// nullptr. +/// fixed value, return said value in the requested type. If this is a call to +/// alloca instruction the returned value is undef. Otherwise, return nullptr. Constant *getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty); diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp --- a/llvm/lib/Analysis/MemoryBuiltins.cpp +++ b/llvm/lib/Analysis/MemoryBuiltins.cpp @@ -436,6 +436,9 @@ Constant *llvm::getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty) { + if (isa(V)) + return UndefValue::get(Ty); + auto *Alloc = dyn_cast(V); if (!Alloc) return nullptr; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -32,6 +32,7 @@ #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/InstSimplifyFolder.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/IRBuilder.h" @@ -805,7 +806,9 @@ // undef. SSAUpdater Updater; Updater.Initialize(VectorTy, "promotealloca"); - Updater.AddAvailableValue(Alloca.getParent(), UndefValue::get(VectorTy)); + Updater.AddAvailableValue( + Alloca.getParent(), + getInitialValueOfAllocation(&Alloca, nullptr, VectorTy)); // First handle the initial worklist. SmallVector DeferredLoads; diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -1239,11 +1239,12 @@ } assert(DepInfo.isDef() && "follows from above"); - // Loading the alloca -> undef. // Loading immediately after lifetime begin -> undef. - if (isa(DepInst) || isLifetimeStart(DepInst)) + if (isLifetimeStart(DepInst)) return AvailableValue::get(UndefValue::get(Load->getType())); + // In addition to allocator function calls this includes loading the alloca -> + // undef. if (Constant *InitVal = getInitialValueOfAllocation(DepInst, TLI, Load->getType())) return AvailableValue::get(InitVal); diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp --- a/llvm/lib/Transforms/Scalar/NewGVN.cpp +++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp @@ -1496,21 +1496,18 @@ if (LoadPtr != lookupOperandLeader(DepInst) && !AA->isMustAlias(LoadPtr, DepInst)) return nullptr; - // If this load really doesn't depend on anything, then we must be loading an - // undef value. This can happen when loading for a fresh allocation with no - // intervening stores, for example. Note that this is only true in the case - // that the result of the allocation is pointer equal to the load ptr. - if (isa(DepInst)) { - return createConstantExpression(UndefValue::get(LoadType)); - } // If this load occurs either right after a lifetime begin, // then the loaded value is undefined. - else if (auto *II = dyn_cast(DepInst)) { + if (auto *II = dyn_cast(DepInst)) { if (II->getIntrinsicID() == Intrinsic::lifetime_start) return createConstantExpression(UndefValue::get(LoadType)); - } else if (auto *InitVal = - getInitialValueOfAllocation(DepInst, TLI, LoadType)) - return createConstantExpression(InitVal); + } + // If this load really doesn't depend on anything, then we must be loading an + // undef value. This can happen when loading for a fresh allocation with no + // intervening stores, for example. Note that this is only true in the case + // that the result of the allocation is pointer equal to the load ptr. + else if (auto *InitVal = getInitialValueOfAllocation(DepInst, TLI, LoadType)) + return createConstantExpression(InitVal); return nullptr; } diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp --- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -24,6 +24,7 @@ #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/IteratedDominanceFrontier.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" @@ -600,7 +601,7 @@ if (I == StoresByIndex.begin()) { if (StoresByIndex.empty()) // If there are no stores, the load takes the undef value. - ReplVal = UndefValue::get(LI->getType()); + ReplVal = getInitialValueOfAllocation(AI, nullptr, LI->getType()); else // There is no store before this load, bail out (load may be affected // by the following stores - see main comment).