diff options
author | Philip Reames <listmail@philipreames.com> | 2019-04-12 18:26:56 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2019-04-12 18:26:56 +0000 |
commit | b091cc081df43b1789cde9189936b485da0c1b2d (patch) | |
tree | 0a3ed74eec8f954b66777544d4e256bb006e3447 /llvm/lib/Transforms | |
parent | 00a0d5d1de58da3651f7efe74d9f17ebfd2cbb01 (diff) | |
download | bcm5719-llvm-b091cc081df43b1789cde9189936b485da0c1b2d.tar.gz bcm5719-llvm-b091cc081df43b1789cde9189936b485da0c1b2d.zip |
[InstCombine] Fix a nasty miscompile introduced w/masked.gather demanded elts
This fixes a miscompile which was introduced in r356510 (https://reviews.llvm.org/D57372).
The problem is that the original patch removed pointer operands where the load results we're demanded, but without considering the legality of the load itself. If the masked.gather had active, but undemanded, lanes, then we could end up creating a load which loaded from an undef address. The result could be a segfault, or, in theory, an arbitrary read from a random memory location into an used register.
llvm-svn: 358299
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 2dea7eea404..1d52938d1f8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -1437,7 +1437,11 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, switch (II->getIntrinsicID()) { case Intrinsic::masked_gather: // fallthrough case Intrinsic::masked_load: { - APInt DemandedPtrs(DemandedElts), DemandedPassThrough(DemandedElts); + // Subtlety: If we load from a pointer, the pointer must be valid + // regardless of whether the element is demanded. Doing otherwise risks + // segfaults which didn't exist in the original program. + APInt DemandedPtrs(APInt::getAllOnesValue(VWidth)), + DemandedPassThrough(DemandedElts); if (auto *CV = dyn_cast<ConstantVector>(II->getOperand(2))) for (unsigned i = 0; i < VWidth; i++) { Constant *CElt = CV->getAggregateElement(i); |