diff --git a/llvm/lib/Transforms/Utils/VNCoercion.cpp b/llvm/lib/Transforms/Utils/VNCoercion.cpp --- a/llvm/lib/Transforms/Utils/VNCoercion.cpp +++ b/llvm/lib/Transforms/Utils/VNCoercion.cpp @@ -11,10 +11,8 @@ namespace llvm { namespace VNCoercion { -/// Return true if coerceAvailableValueToLoadType will succeed. -bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, +bool canCoerceMustAliasedValueToLoad(Type *StoredTy, Type *LoadTy, const DataLayout &DL) { - Type *StoredTy = StoredVal->getType(); if (StoredTy == LoadTy) return true; @@ -35,19 +33,24 @@ return false; // Don't coerce non-integral pointers to integers or vice versa. - if (DL.isNonIntegralPointerType(StoredVal->getType()->getScalarType()) != - DL.isNonIntegralPointerType(LoadTy->getScalarType())) { - // As a special case, allow coercion of memset used to initialize - // an array w/null. Despite non-integral pointers not generally having a - // specific bit pattern, we do assume null is zero. - if (auto *CI = dyn_cast(StoredVal)) - return CI->isNullValue(); + if (DL.isNonIntegralPointerType(StoredTy->getScalarType()) != + DL.isNonIntegralPointerType(LoadTy->getScalarType())) return false; - } - + return true; } +/// Return true if coerceAvailableValueToLoadType will succeed. +bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, + const DataLayout &DL) { + Type *StoredTy = StoredVal->getType(); + if (auto *CI = dyn_cast(StoredVal)) + if (CI->isNullValue()) + if (StoredTy == LoadTy || DL.getTypeSizeInBits(StoredTy) >= DL.getTypeSizeInBits(LoadTy)) + return true; + return canCoerceMustAliasedValueToLoad(StoredTy, LoadTy, DL); +} + template static T *coerceAvailableValueToLoadTypeHelper(T *StoredVal, Type *LoadedTy, HelperClass &Helper, @@ -341,6 +344,9 @@ HelperClass &Helper, const DataLayout &DL) { LLVMContext &Ctx = SrcVal->getType()->getContext(); + if (auto *CI = dyn_cast(GetUnderlyingObject(SrcVal, DL))) + if (CI->isNullValue()) + return Constant::getNullValue(LoadTy); // If two pointers are in the same address space, they have the same size, // so we don't need to do any truncation, etc. This avoids introducing @@ -468,6 +474,12 @@ // memset(P, 'x', 1234) -> splat('x'), even if x is a variable, and // independently of what the offset is. T *Val = cast(MSI->getValue()); + if (auto *CI = dyn_cast(Val)) { + // memset(P, '\0', 1234) -> just directly create the null value for *P + // by-passing any later validity checks + if (CI->isNullValue()) + return Constant::getNullValue(LoadTy); + } if (LoadSize != 1) Val = Helper.CreateZExtOrBitCast(Val, IntegerType::get(Ctx, LoadSize * 8));