diff options
| author | Philip Reames <listmail@philipreames.com> | 2016-12-01 20:17:06 +0000 | 
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2016-12-01 20:17:06 +0000 | 
| commit | 89e92d21b40a681ee4828daff38229cb417915b5 (patch) | |
| tree | 0063a8b4b6a9ccec7fc83733f782252d88439214 /llvm/lib | |
| parent | bf1a70f1c9a8c5558fd3eb54624a349b9a61979b (diff) | |
| download | bcm5719-llvm-89e92d21b40a681ee4828daff38229cb417915b5.tar.gz bcm5719-llvm-89e92d21b40a681ee4828daff38229cb417915b5.zip | |
[PR29121] Don't fold if it would produce atomic vector loads or stores
The instcombine code which folds loads and stores into their use types can trip up if the use is a bitcast to a type which we can't directly load or store in the IR. In principle, such types shouldn't exist, but in practice they do today. This is a workaround to avoid a bug while we work towards the long term goal.
Differential Revision: https://reviews.llvm.org/D24365
llvm-svn: 288415
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 42 | 
1 files changed, 28 insertions, 14 deletions
| diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 19a11f9896e..5276bee4e0a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -308,6 +308,11 @@ Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) {    return visitAllocSite(AI);  } +// Are we allowed to form a atomic load or store of this type? +static bool isSupportedAtomicType(Type *Ty) { +  return Ty->isIntegerTy() || Ty->isPointerTy() || Ty->isFloatingPointTy(); +} +  /// \brief Helper to combine a load to a new type.  ///  /// This just does the work of combining a load to a new type. It handles @@ -319,6 +324,9 @@ Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) {  /// point the \c InstCombiner currently is using.  static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewTy,                                        const Twine &Suffix = "") { +  assert((!LI.isAtomic() || isSupportedAtomicType(NewTy)) && +         "can't fold an atomic load to requested type"); +      Value *Ptr = LI.getPointerOperand();    unsigned AS = LI.getPointerAddressSpace();    SmallVector<std::pair<unsigned, MDNode *>, 8> MD; @@ -400,6 +408,9 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT  ///  /// Returns the newly created store instruction.  static StoreInst *combineStoreToNewValue(InstCombiner &IC, StoreInst &SI, Value *V) { +  assert((!SI.isAtomic() || isSupportedAtomicType(V->getType())) && +         "can't fold an atomic store of requested type"); +      Value *Ptr = SI.getPointerOperand();    unsigned AS = SI.getPointerAddressSpace();    SmallVector<std::pair<unsigned, MDNode *>, 8> MD; @@ -514,14 +525,14 @@ static Instruction *combineLoadToOperationType(InstCombiner &IC, LoadInst &LI) {    // as long as those are noops (i.e., the source or dest type have the same    // bitwidth as the target's pointers).    if (LI.hasOneUse()) -    if (auto* CI = dyn_cast<CastInst>(LI.user_back())) { -      if (CI->isNoopCast(DL)) { -        LoadInst *NewLoad = combineLoadToNewType(IC, LI, CI->getDestTy()); -        CI->replaceAllUsesWith(NewLoad); -        IC.eraseInstFromFunction(*CI); -        return &LI; -      } -    } +    if (auto* CI = dyn_cast<CastInst>(LI.user_back())) +      if (CI->isNoopCast(DL)) +        if (!LI.isAtomic() || isSupportedAtomicType(CI->getDestTy())) { +          LoadInst *NewLoad = combineLoadToNewType(IC, LI, CI->getDestTy()); +          CI->replaceAllUsesWith(NewLoad); +          IC.eraseInstFromFunction(*CI); +          return &LI; +        }    // FIXME: We should also canonicalize loads of vectors when their elements are    // cast to other types. @@ -1026,14 +1037,17 @@ static bool combineStoreToValueType(InstCombiner &IC, StoreInst &SI) {    // Fold away bit casts of the stored value by storing the original type.    if (auto *BC = dyn_cast<BitCastInst>(V)) {      V = BC->getOperand(0); -    combineStoreToNewValue(IC, SI, V); -    return true; +    if (!SI.isAtomic() || isSupportedAtomicType(V->getType())) { +      combineStoreToNewValue(IC, SI, V); +      return true; +    }    } -  if (Value *U = likeBitCastFromVector(IC, V)) { -    combineStoreToNewValue(IC, SI, U); -    return true; -  } +  if (Value *U = likeBitCastFromVector(IC, V)) +    if (!SI.isAtomic() || isSupportedAtomicType(U->getType())) { +      combineStoreToNewValue(IC, SI, U); +      return true; +    }    // FIXME: We should also canonicalize stores of vectors when their elements    // are cast to other types. | 

