diff options
author | Philip Reames <listmail@philipreames.com> | 2019-02-19 23:07:15 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2019-02-19 23:07:15 +0000 |
commit | 92756a80e7ae7b0ce682d84e8576e885e7e4ccb1 (patch) | |
tree | 4272d18393e05322fc7bad7ea5eb1191b21c20f8 /llvm/lib/Transforms/Utils/VNCoercion.cpp | |
parent | 979587d91dbea0e3757db4ceb0045a51e85c6d81 (diff) | |
download | bcm5719-llvm-92756a80e7ae7b0ce682d84e8576e885e7e4ccb1.tar.gz bcm5719-llvm-92756a80e7ae7b0ce682d84e8576e885e7e4ccb1.zip |
[GVN] Fix a crash bug around non-integral pointers
If we encountered a location where we tried to forward the value of a memset to a load of a non-integral pointer, we crashed. Such a forward is not legal in general, but we can forward null pointers. Test for both cases are included.
llvm-svn: 354399
Diffstat (limited to 'llvm/lib/Transforms/Utils/VNCoercion.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/VNCoercion.cpp | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/VNCoercion.cpp b/llvm/lib/Transforms/Utils/VNCoercion.cpp index 19e5db4eee2..74572eb2d46 100644 --- a/llvm/lib/Transforms/Utils/VNCoercion.cpp +++ b/llvm/lib/Transforms/Utils/VNCoercion.cpp @@ -32,9 +32,15 @@ bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, // Don't coerce non-integral pointers to integers or vice versa. if (DL.isNonIntegralPointerType(StoredVal->getType()) != - DL.isNonIntegralPointerType(LoadTy)) + DL.isNonIntegralPointerType(LoadTy)) { + // 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<ConstantInt>(StoredVal)) + return CI->isZero(); return false; - + } + return true; } @@ -264,9 +270,16 @@ int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, // If this is memset, we just need to see if the offset is valid in the size // of the memset.. - if (MI->getIntrinsicID() == Intrinsic::memset) + if (MI->getIntrinsicID() == Intrinsic::memset) { + Value *StoredVal = cast<MemSetInst>(MI)->getValue(); + if (DL.isNonIntegralPointerType(LoadTy->getScalarType())) { + auto *CI = dyn_cast<ConstantInt>(StoredVal); + if (!CI || !CI->isZero()) + return -1; + } return analyzeLoadFromClobberingWrite(LoadTy, LoadPtr, MI->getDest(), MemSizeInBits, DL); + } // If we have a memcpy/memmove, the only case we can handle is if this is a // copy from constant memory. In that case, we can read directly from the |