Skip to content

Commit

Permalink
[PR29121] Don't fold if it would produce atomic vector loads or stores
Browse files Browse the repository at this point in the history
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



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288415 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
preames committed Dec 1, 2016
1 parent c0d2319 commit ed79607
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 14 deletions.
42 changes: 28 additions & 14 deletions lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
20 changes: 20 additions & 0 deletions test/Transforms/InstCombine/atomic.ll
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,23 @@ define void @pr27490b(i8** %p1, i8** %p2) {
store atomic i8* %l, i8** %p2 seq_cst, align 8
ret void
}

;; At the moment, we can't form atomic vectors by folding since these are
;; not representable in the IR. This was pr29121. The right long term
;; solution is to extend the IR to handle this case.
define <2 x float> @no_atomic_vector_load(i64* %p) {
; CHECK-LABEL @no_atomic_vector_load
; CHECK: load atomic i64, i64* %p unordered, align 8
%load = load atomic i64, i64* %p unordered, align 8
%.cast = bitcast i64 %load to <2 x float>
ret <2 x float> %.cast
}

define void @no_atomic_vector_store(<2 x float> %p, i8* %p2) {
; CHECK-LABEL: @no_atomic_vector_store
; CHECK: store atomic i64 %1, i64* %2 unordered, align 8
%1 = bitcast <2 x float> %p to i64
%2 = bitcast i8* %p2 to i64*
store atomic i64 %1, i64* %2 unordered, align 8
ret void
}

0 comments on commit ed79607

Please sign in to comment.