Revert "[SLP]Remove LoadCombine workaround after handling of the copyables"
This reverts commit 8dbb9f66e8b14a8a06f1873a2c1b7dce366ed2d6 to fix buildbot issues https://lab.llvm.org/buildbot/#/builders/224/builds/2795
This commit is contained in:
parent
8f484ff2a0
commit
6377c86d71
@ -2100,16 +2100,12 @@ public:
|
||||
VectorizableTree.front()->getVectorFactor());
|
||||
}
|
||||
|
||||
/// Returns true if the tree results in one of the reduced bitcasts variants.
|
||||
/// Returns the opcode of the root node, or 0, if the root node is gather.
|
||||
bool isReducedBitcastRoot() const {
|
||||
return VectorizableTree.front()->hasState() &&
|
||||
(VectorizableTree.front()->CombinedOp == TreeEntry::ReducedBitcast ||
|
||||
VectorizableTree.front()->CombinedOp ==
|
||||
TreeEntry::ReducedBitcastBSwap ||
|
||||
VectorizableTree.front()->CombinedOp ==
|
||||
TreeEntry::ReducedBitcastLoads ||
|
||||
VectorizableTree.front()->CombinedOp ==
|
||||
TreeEntry::ReducedBitcastBSwapLoads) &&
|
||||
TreeEntry::ReducedBitcastBSwap) &&
|
||||
VectorizableTree.front()->State == TreeEntry::Vectorize;
|
||||
}
|
||||
|
||||
@ -2274,6 +2270,23 @@ public:
|
||||
/// effectively than the base graph.
|
||||
bool isTreeNotExtendable() const;
|
||||
|
||||
/// Assume that a legal-sized 'or'-reduction of shifted/zexted loaded values
|
||||
/// can be load combined in the backend. Load combining may not be allowed in
|
||||
/// the IR optimizer, so we do not want to alter the pattern. For example,
|
||||
/// partially transforming a scalar bswap() pattern into vector code is
|
||||
/// effectively impossible for the backend to undo.
|
||||
/// TODO: If load combining is allowed in the IR optimizer, this analysis
|
||||
/// may not be necessary.
|
||||
bool isLoadCombineReductionCandidate(RecurKind RdxKind) const;
|
||||
|
||||
/// Assume that a vector of stores of bitwise-or/shifted/zexted loaded values
|
||||
/// can be load combined in the backend. Load combining may not be allowed in
|
||||
/// the IR optimizer, so we do not want to alter the pattern. For example,
|
||||
/// partially transforming a scalar bswap() pattern into vector code is
|
||||
/// effectively impossible for the backend to undo.
|
||||
/// TODO: If load combining is allowed in the IR optimizer, this analysis
|
||||
/// may not be necessary.
|
||||
bool isLoadCombineCandidate(ArrayRef<Value *> Stores) const;
|
||||
bool isStridedLoad(ArrayRef<Value *> PointerOps, Type *ScalarTy,
|
||||
Align Alignment, const int64_t Diff,
|
||||
const size_t Sz) const;
|
||||
@ -3919,9 +3932,8 @@ private:
|
||||
/// .., 56))-like pattern.
|
||||
/// If the int shifts unique, also strided, but not ordered, sets \p Order.
|
||||
/// If the node can be represented as a bitcast + bswap, sets \p IsBSwap.
|
||||
/// If the root nodes are loads, sets \p ForLoads to true.
|
||||
bool matchesShlZExt(const TreeEntry &TE, OrdersType &Order, bool &IsBSwap,
|
||||
bool &ForLoads) const;
|
||||
bool matchesShlZExt(const TreeEntry &TE, OrdersType &Order,
|
||||
bool &IsBSwap) const;
|
||||
|
||||
class TreeEntry {
|
||||
public:
|
||||
@ -4054,8 +4066,6 @@ private:
|
||||
FMulAdd,
|
||||
ReducedBitcast,
|
||||
ReducedBitcastBSwap,
|
||||
ReducedBitcastLoads,
|
||||
ReducedBitcastBSwapLoads,
|
||||
};
|
||||
CombinedOpcode CombinedOp = NotCombinedOp;
|
||||
|
||||
@ -13343,11 +13353,10 @@ static InstructionCost canConvertToFMA(ArrayRef<Value *> VL,
|
||||
}
|
||||
|
||||
bool BoUpSLP::matchesShlZExt(const TreeEntry &TE, OrdersType &Order,
|
||||
bool &IsBSwap, bool &ForLoads) const {
|
||||
bool &IsBSwap) const {
|
||||
assert(TE.hasState() && TE.getOpcode() == Instruction::Shl &&
|
||||
"Expected Shl node.");
|
||||
IsBSwap = false;
|
||||
ForLoads = false;
|
||||
if (TE.State != TreeEntry::Vectorize || !TE.ReorderIndices.empty() ||
|
||||
!TE.ReuseShuffleIndices.empty() || MinBWs.contains(&TE) ||
|
||||
any_of(TE.Scalars, [](Value *V) { return !V->hasOneUse(); }))
|
||||
@ -13454,44 +13463,6 @@ bool BoUpSLP::matchesShlZExt(const TreeEntry &TE, OrdersType &Order,
|
||||
if (BSwapCost <= BitcastCost) {
|
||||
BitcastCost = BSwapCost;
|
||||
IsBSwap = true;
|
||||
Order.clear();
|
||||
// Check for loads in the ZExt node.
|
||||
const TreeEntry *SrcTE = getOperandEntry(LhsTE, /*Idx=*/0);
|
||||
if (SrcTE->State == TreeEntry::Vectorize &&
|
||||
SrcTE->ReorderIndices.empty() && SrcTE->ReuseShuffleIndices.empty() &&
|
||||
SrcTE->getOpcode() == Instruction::Load && !SrcTE->isAltShuffle() &&
|
||||
all_of(SrcTE->Scalars, [](Value *V) { return V->hasOneUse(); })) {
|
||||
auto *LI = cast<LoadInst>(SrcTE->getMainOp());
|
||||
IntrinsicCostAttributes CostAttrs(Intrinsic::bswap, ScalarTy,
|
||||
{ScalarTy});
|
||||
InstructionCost BSwapCost =
|
||||
TTI->getMemoryOpCost(Instruction::Load, ScalarTy, LI->getAlign(),
|
||||
LI->getPointerAddressSpace(), CostKind) +
|
||||
TTI->getIntrinsicInstrCost(CostAttrs, CostKind);
|
||||
if (BSwapCost <= BitcastCost) {
|
||||
VecCost +=
|
||||
TTI->getMemoryOpCost(Instruction::Load, SrcVecTy, LI->getAlign(),
|
||||
LI->getPointerAddressSpace(), CostKind);
|
||||
BitcastCost = BSwapCost;
|
||||
ForLoads = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (Order.empty() && DL->getTypeSizeInBits(SrcScalarTy) == ByteSize) {
|
||||
// Check for loads in the ZExt node.
|
||||
const TreeEntry *SrcTE = getOperandEntry(LhsTE, /*Idx=*/0);
|
||||
if (SrcTE->State == TreeEntry::Vectorize && SrcTE->ReorderIndices.empty() &&
|
||||
SrcTE->ReuseShuffleIndices.empty() &&
|
||||
SrcTE->getOpcode() == Instruction::Load && !SrcTE->isAltShuffle() &&
|
||||
all_of(SrcTE->Scalars, [](Value *V) { return V->hasOneUse(); })) {
|
||||
auto *LI = cast<LoadInst>(SrcTE->getMainOp());
|
||||
BitcastCost =
|
||||
TTI->getMemoryOpCost(Instruction::Load, ScalarTy, LI->getAlign(),
|
||||
LI->getPointerAddressSpace(), CostKind);
|
||||
VecCost +=
|
||||
TTI->getMemoryOpCost(Instruction::Load, SrcVecTy, LI->getAlign(),
|
||||
LI->getPointerAddressSpace(), CostKind);
|
||||
ForLoads = true;
|
||||
}
|
||||
}
|
||||
return BitcastCost < VecCost;
|
||||
@ -13913,17 +13884,14 @@ void BoUpSLP::transformNodes() {
|
||||
break;
|
||||
OrdersType Order;
|
||||
bool IsBSwap;
|
||||
bool ForLoads;
|
||||
if (!matchesShlZExt(E, Order, IsBSwap, ForLoads))
|
||||
if (!matchesShlZExt(E, Order, IsBSwap))
|
||||
break;
|
||||
// This node is a (reduced disjoint or) bitcast node.
|
||||
TreeEntry::CombinedOpcode Code =
|
||||
IsBSwap ? (ForLoads ? TreeEntry::ReducedBitcastBSwapLoads
|
||||
: TreeEntry::ReducedBitcastBSwap)
|
||||
: (ForLoads ? TreeEntry::ReducedBitcastLoads
|
||||
: TreeEntry::ReducedBitcast);
|
||||
IsBSwap ? TreeEntry::ReducedBitcastBSwap : TreeEntry::ReducedBitcast;
|
||||
E.CombinedOp = Code;
|
||||
E.ReorderIndices = std::move(Order);
|
||||
if (!IsBSwap)
|
||||
E.ReorderIndices = std::move(Order);
|
||||
TreeEntry *ZExtEntry = getOperandEntry(&E, 0);
|
||||
assert(ZExtEntry->UserTreeIndex &&
|
||||
ZExtEntry->State == TreeEntry::Vectorize &&
|
||||
@ -13932,16 +13900,6 @@ void BoUpSLP::transformNodes() {
|
||||
// The ZExt node is part of the combined node.
|
||||
ZExtEntry->State = TreeEntry::CombinedVectorize;
|
||||
ZExtEntry->CombinedOp = Code;
|
||||
if (ForLoads) {
|
||||
TreeEntry *LoadsEntry = getOperandEntry(ZExtEntry, 0);
|
||||
assert(LoadsEntry->UserTreeIndex &&
|
||||
LoadsEntry->State == TreeEntry::Vectorize &&
|
||||
LoadsEntry->getOpcode() == Instruction::Load &&
|
||||
"Expected Load node.");
|
||||
// The Load node is part of the combined node.
|
||||
LoadsEntry->State = TreeEntry::CombinedVectorize;
|
||||
LoadsEntry->CombinedOp = Code;
|
||||
}
|
||||
TreeEntry *ConstEntry = getOperandEntry(&E, 1);
|
||||
assert(ConstEntry->UserTreeIndex && ConstEntry->isGather() &&
|
||||
"Expected ZExt node.");
|
||||
@ -15601,44 +15559,6 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals,
|
||||
};
|
||||
return GetCostDiff(GetScalarCost, GetVectorCost);
|
||||
}
|
||||
case TreeEntry::ReducedBitcastLoads:
|
||||
case TreeEntry::ReducedBitcastBSwapLoads: {
|
||||
auto GetScalarCost = [&, &TTI = *TTI](unsigned Idx) {
|
||||
if (isa<PoisonValue>(UniqueValues[Idx]))
|
||||
return InstructionCost(TTI::TCC_Free);
|
||||
auto *Shl = dyn_cast<Instruction>(UniqueValues[Idx]);
|
||||
if (!Shl)
|
||||
return InstructionCost(TTI::TCC_Free);
|
||||
InstructionCost ScalarCost = TTI.getInstructionCost(Shl, CostKind);
|
||||
auto *ZExt = dyn_cast<Instruction>(Shl->getOperand(0));
|
||||
if (!ZExt)
|
||||
return ScalarCost;
|
||||
ScalarCost += TTI.getInstructionCost(ZExt, CostKind);
|
||||
auto *Load = dyn_cast<Instruction>(ZExt->getOperand(0));
|
||||
if (!Load)
|
||||
return ScalarCost;
|
||||
ScalarCost += TTI.getInstructionCost(Load, CostKind);
|
||||
return ScalarCost;
|
||||
};
|
||||
auto GetVectorCost = [&, &TTI = *TTI](InstructionCost CommonCost) {
|
||||
const TreeEntry *LhsTE = getOperandEntry(E, /*Idx=*/0);
|
||||
const TreeEntry *LoadTE = getOperandEntry(LhsTE, /*Idx=*/0);
|
||||
auto *LI0 = cast<LoadInst>(LoadTE->getMainOp());
|
||||
auto *OrigScalarTy = E->getMainOp()->getType();
|
||||
InstructionCost LoadCost =
|
||||
TTI.getMemoryOpCost(Instruction::Load, OrigScalarTy, LI0->getAlign(),
|
||||
LI0->getPointerAddressSpace(), CostKind);
|
||||
if (ShuffleOrOp == TreeEntry::ReducedBitcastBSwapLoads) {
|
||||
IntrinsicCostAttributes CostAttrs(Intrinsic::bswap, OrigScalarTy,
|
||||
{OrigScalarTy});
|
||||
InstructionCost IntrinsicCost =
|
||||
TTI.getIntrinsicInstrCost(CostAttrs, CostKind);
|
||||
LoadCost += IntrinsicCost;
|
||||
}
|
||||
return LoadCost + CommonCost;
|
||||
};
|
||||
return GetCostDiff(GetScalarCost, GetVectorCost);
|
||||
}
|
||||
case Instruction::FNeg:
|
||||
case Instruction::Add:
|
||||
case Instruction::FAdd:
|
||||
@ -16123,6 +16043,69 @@ bool BoUpSLP::isFullyVectorizableTinyTree(bool ForReduction) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool isLoadCombineCandidateImpl(Value *Root, unsigned NumElts,
|
||||
TargetTransformInfo *TTI,
|
||||
bool MustMatchOrInst) {
|
||||
// Look past the root to find a source value. Arbitrarily follow the
|
||||
// path through operand 0 of any 'or'. Also, peek through optional
|
||||
// shift-left-by-multiple-of-8-bits.
|
||||
Value *ZextLoad = Root;
|
||||
const APInt *ShAmtC;
|
||||
bool FoundOr = false;
|
||||
while (!isa<ConstantExpr>(ZextLoad) &&
|
||||
(match(ZextLoad, m_Or(m_Value(), m_Value())) ||
|
||||
(match(ZextLoad, m_Shl(m_Value(), m_APInt(ShAmtC))) &&
|
||||
ShAmtC->urem(8) == 0))) {
|
||||
auto *BinOp = cast<BinaryOperator>(ZextLoad);
|
||||
ZextLoad = BinOp->getOperand(0);
|
||||
if (BinOp->getOpcode() == Instruction::Or)
|
||||
FoundOr = true;
|
||||
}
|
||||
// Check if the input is an extended load of the required or/shift expression.
|
||||
Value *Load;
|
||||
if ((MustMatchOrInst && !FoundOr) || ZextLoad == Root ||
|
||||
!match(ZextLoad, m_ZExt(m_Value(Load))) || !isa<LoadInst>(Load))
|
||||
return false;
|
||||
|
||||
// Require that the total load bit width is a legal integer type.
|
||||
// For example, <8 x i8> --> i64 is a legal integer on a 64-bit target.
|
||||
// But <16 x i8> --> i128 is not, so the backend probably can't reduce it.
|
||||
Type *SrcTy = Load->getType();
|
||||
unsigned LoadBitWidth = SrcTy->getIntegerBitWidth() * NumElts;
|
||||
if (!TTI->isTypeLegal(IntegerType::get(Root->getContext(), LoadBitWidth)))
|
||||
return false;
|
||||
|
||||
// Everything matched - assume that we can fold the whole sequence using
|
||||
// load combining.
|
||||
LLVM_DEBUG(dbgs() << "SLP: Assume load combining for tree starting at "
|
||||
<< *(cast<Instruction>(Root)) << "\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BoUpSLP::isLoadCombineReductionCandidate(RecurKind RdxKind) const {
|
||||
if (RdxKind != RecurKind::Or)
|
||||
return false;
|
||||
|
||||
unsigned NumElts = VectorizableTree[0]->Scalars.size();
|
||||
Value *FirstReduced = VectorizableTree[0]->Scalars[0];
|
||||
return isLoadCombineCandidateImpl(FirstReduced, NumElts, TTI,
|
||||
/* MatchOr */ false);
|
||||
}
|
||||
|
||||
bool BoUpSLP::isLoadCombineCandidate(ArrayRef<Value *> Stores) const {
|
||||
// Peek through a final sequence of stores and check if all operations are
|
||||
// likely to be load-combined.
|
||||
unsigned NumElts = Stores.size();
|
||||
for (Value *Scalar : Stores) {
|
||||
Value *X;
|
||||
if (!match(Scalar, m_Store(m_Value(X), m_Value())) ||
|
||||
!isLoadCombineCandidateImpl(X, NumElts, TTI, /* MatchOr */ true))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BoUpSLP::isTreeTinyAndNotFullyVectorizable(bool ForReduction) const {
|
||||
if (!DebugCounter::shouldExecute(VectorizedGraphs))
|
||||
return true;
|
||||
@ -16351,9 +16334,7 @@ InstructionCost BoUpSLP::getSpillCost() {
|
||||
SmallPtrSet<const TreeEntry *, 8> ScalarOrPseudoEntries;
|
||||
for (const auto &TEPtr : VectorizableTree) {
|
||||
if (TEPtr->CombinedOp == TreeEntry::ReducedBitcast ||
|
||||
TEPtr->CombinedOp == TreeEntry::ReducedBitcastBSwap ||
|
||||
TEPtr->CombinedOp == TreeEntry::ReducedBitcastLoads ||
|
||||
TEPtr->CombinedOp == TreeEntry::ReducedBitcastBSwapLoads) {
|
||||
TEPtr->CombinedOp == TreeEntry::ReducedBitcastBSwap) {
|
||||
ScalarOrPseudoEntries.insert(TEPtr.get());
|
||||
continue;
|
||||
}
|
||||
@ -20288,8 +20269,6 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
|
||||
switch (E->CombinedOp) {
|
||||
case TreeEntry::ReducedBitcast:
|
||||
case TreeEntry::ReducedBitcastBSwap:
|
||||
case TreeEntry::ReducedBitcastLoads:
|
||||
case TreeEntry::ReducedBitcastBSwapLoads:
|
||||
ShuffleOrOp = E->CombinedOp;
|
||||
break;
|
||||
default:
|
||||
@ -21257,31 +21236,6 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
|
||||
++NumVectorInstructions;
|
||||
return V;
|
||||
}
|
||||
case TreeEntry::ReducedBitcastLoads:
|
||||
case TreeEntry::ReducedBitcastBSwapLoads: {
|
||||
assert(UserIgnoreList && "Expected reduction operations only.");
|
||||
setInsertPointAfterBundle(E);
|
||||
TreeEntry *ZExt = getOperandEntry(E, /*Idx=*/0);
|
||||
ZExt->VectorizedValue = PoisonValue::get(getWidenedType(
|
||||
ZExt->getMainOp()->getType(), ZExt->getVectorFactor()));
|
||||
TreeEntry *Const = getOperandEntry(E, /*Idx=*/1);
|
||||
Const->VectorizedValue = PoisonValue::get(getWidenedType(
|
||||
Const->Scalars.front()->getType(), Const->getVectorFactor()));
|
||||
TreeEntry *Load = getOperandEntry(ZExt, /*Idx=*/0);
|
||||
Load->VectorizedValue = PoisonValue::get(getWidenedType(
|
||||
Load->getMainOp()->getType(), Load->getVectorFactor()));
|
||||
LoadInst *LI = cast<LoadInst>(Load->getMainOp());
|
||||
Value *PO = LI->getPointerOperand();
|
||||
Type *ScalarTy = ZExt->getMainOp()->getType();
|
||||
Value *V = Builder.CreateAlignedLoad(ScalarTy, PO, LI->getAlign());
|
||||
++NumVectorInstructions;
|
||||
if (ShuffleOrOp == TreeEntry::ReducedBitcastBSwapLoads) {
|
||||
V = Builder.CreateUnaryIntrinsic(Intrinsic::bswap, V);
|
||||
++NumVectorInstructions;
|
||||
}
|
||||
E->VectorizedValue = V;
|
||||
return V;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("unknown inst");
|
||||
}
|
||||
@ -21309,9 +21263,7 @@ Value *BoUpSLP::vectorizeTree(
|
||||
if (TE->isGather() || DeletedNodes.contains(TE.get()) ||
|
||||
(TE->State == TreeEntry::CombinedVectorize &&
|
||||
(TE->CombinedOp == TreeEntry::ReducedBitcast ||
|
||||
TE->CombinedOp == TreeEntry::ReducedBitcastBSwap ||
|
||||
TE->CombinedOp == TreeEntry::ReducedBitcastLoads ||
|
||||
TE->CombinedOp == TreeEntry::ReducedBitcastBSwapLoads)))
|
||||
TE->CombinedOp == TreeEntry::ReducedBitcastBSwap)))
|
||||
continue;
|
||||
(void)getLastInstructionInBundle(TE.get());
|
||||
}
|
||||
@ -21870,9 +21822,7 @@ Value *BoUpSLP::vectorizeTree(
|
||||
continue;
|
||||
|
||||
if (Entry->CombinedOp == TreeEntry::ReducedBitcast ||
|
||||
Entry->CombinedOp == TreeEntry::ReducedBitcastBSwap ||
|
||||
Entry->CombinedOp == TreeEntry::ReducedBitcastLoads ||
|
||||
Entry->CombinedOp == TreeEntry::ReducedBitcastBSwapLoads) {
|
||||
Entry->CombinedOp == TreeEntry::ReducedBitcastBSwap) {
|
||||
// Skip constant node
|
||||
if (!Entry->hasState()) {
|
||||
assert(allConstant(Entry->Scalars) && "Expected constants only.");
|
||||
@ -24188,6 +24138,8 @@ SLPVectorizerPass::vectorizeStoreChain(ArrayRef<Value *> Chain, BoUpSLP &R,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (R.isLoadCombineCandidate(Chain))
|
||||
return true;
|
||||
R.buildTree(Chain);
|
||||
// Check if tree tiny and store itself or its value is not vectorized.
|
||||
if (R.isTreeTinyAndNotFullyVectorizable()) {
|
||||
@ -25792,6 +25744,11 @@ public:
|
||||
V.analyzedReductionVals(VL);
|
||||
continue;
|
||||
}
|
||||
if (V.isLoadCombineReductionCandidate(RdxKind)) {
|
||||
if (!AdjustReducedVals())
|
||||
V.analyzedReductionVals(VL);
|
||||
continue;
|
||||
}
|
||||
V.reorderTopToBottom();
|
||||
// No need to reorder the root node at all for reassociative reduction.
|
||||
V.reorderBottomToTop(/*IgnoreReorder=*/RdxFMF.allowReassoc() ||
|
||||
|
||||
@ -70,7 +70,23 @@ define i32 @loadCombine_4consecutive_1243(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_1324(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_1324(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -98,7 +114,23 @@ define i32 @loadCombine_4consecutive_1324(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_1342(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_1342(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -126,7 +158,23 @@ define i32 @loadCombine_4consecutive_1342(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_1423(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_1423(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -154,7 +202,23 @@ define i32 @loadCombine_4consecutive_1423(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_1432(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_1432(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -305,7 +369,23 @@ define i32 @loadCombine_4consecutive_2341(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_2413(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_2413(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -333,7 +413,23 @@ define i32 @loadCombine_4consecutive_2413(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_2431(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_2431(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -361,7 +457,23 @@ define i32 @loadCombine_4consecutive_2431(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_3124(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_3124(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -389,7 +501,23 @@ define i32 @loadCombine_4consecutive_3124(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_3142(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_3142(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -540,7 +668,23 @@ define i32 @loadCombine_4consecutive_3421(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_4123(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_4123(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -568,7 +712,23 @@ define i32 @loadCombine_4consecutive_4123(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_4132(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_4132(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -596,7 +756,23 @@ define i32 @loadCombine_4consecutive_4132(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_4213(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_4213(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
@ -624,7 +800,23 @@ define i32 @loadCombine_4consecutive_4213(ptr %p) {
|
||||
|
||||
define i32 @loadCombine_4consecutive_4231(ptr %p) {
|
||||
; CHECK-LABEL: @loadCombine_4consecutive_4231(
|
||||
; CHECK-NEXT: [[O3:%.*]] = load i32, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
|
||||
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
|
||||
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[L2:%.*]] = load i8, ptr [[P1]], align 1
|
||||
; CHECK-NEXT: [[L3:%.*]] = load i8, ptr [[P2]], align 1
|
||||
; CHECK-NEXT: [[L4:%.*]] = load i8, ptr [[P3]], align 1
|
||||
; CHECK-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
|
||||
; CHECK-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
|
||||
; CHECK-NEXT: [[E3:%.*]] = zext i8 [[L3]] to i32
|
||||
; CHECK-NEXT: [[E4:%.*]] = zext i8 [[L4]] to i32
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw i32 [[E4]], 24
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i32 [[S2]], [[E1]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i32 [[O1]], [[S3]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i32 [[O2]], [[S4]]
|
||||
; CHECK-NEXT: ret i32 [[O3]]
|
||||
;
|
||||
%p1 = getelementptr i8, ptr %p, i32 1
|
||||
|
||||
@ -7,10 +7,43 @@
|
||||
|
||||
define i64 @load_bswap(ptr %p) {
|
||||
; CHECK-LABEL: @load_bswap(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = zext <8 x i8> [[TMP1]] to <8 x i64>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = shl nuw <8 x i64> [[TMP2]], <i64 56, i64 48, i64 40, i64 32, i64 24, i64 16, i64 8, i64 0>
|
||||
; CHECK-NEXT: [[OR01234567:%.*]] = call i64 @llvm.vector.reduce.or.v8i64(<8 x i64> [[TMP3]])
|
||||
; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [[V8I8:%.*]], ptr [[P:%.*]], i64 0, i32 1
|
||||
; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 2
|
||||
; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 3
|
||||
; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 4
|
||||
; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 5
|
||||
; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 6
|
||||
; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 7
|
||||
; CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[T1:%.*]] = load i8, ptr [[G1]], align 1
|
||||
; CHECK-NEXT: [[T2:%.*]] = load i8, ptr [[G2]], align 1
|
||||
; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[G3]], align 1
|
||||
; CHECK-NEXT: [[T4:%.*]] = load i8, ptr [[G4]], align 1
|
||||
; CHECK-NEXT: [[T5:%.*]] = load i8, ptr [[G5]], align 1
|
||||
; CHECK-NEXT: [[T6:%.*]] = load i8, ptr [[G6]], align 1
|
||||
; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[G7]], align 1
|
||||
; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[T0]] to i64
|
||||
; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[T1]] to i64
|
||||
; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[T2]] to i64
|
||||
; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[T3]] to i64
|
||||
; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[T4]] to i64
|
||||
; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[T5]] to i64
|
||||
; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[T6]] to i64
|
||||
; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[T7]] to i64
|
||||
; CHECK-NEXT: [[SH0:%.*]] = shl nuw i64 [[Z0]], 56
|
||||
; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw i64 [[Z1]], 48
|
||||
; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw i64 [[Z2]], 40
|
||||
; CHECK-NEXT: [[SH3:%.*]] = shl nuw nsw i64 [[Z3]], 32
|
||||
; CHECK-NEXT: [[SH4:%.*]] = shl nuw nsw i64 [[Z4]], 24
|
||||
; CHECK-NEXT: [[SH5:%.*]] = shl nuw nsw i64 [[Z5]], 16
|
||||
; CHECK-NEXT: [[SH6:%.*]] = shl nuw nsw i64 [[Z6]], 8
|
||||
; CHECK-NEXT: [[OR01:%.*]] = or i64 [[SH0]], [[SH1]]
|
||||
; CHECK-NEXT: [[OR012:%.*]] = or i64 [[OR01]], [[SH2]]
|
||||
; CHECK-NEXT: [[OR0123:%.*]] = or i64 [[OR012]], [[SH3]]
|
||||
; CHECK-NEXT: [[OR01234:%.*]] = or i64 [[OR0123]], [[SH4]]
|
||||
; CHECK-NEXT: [[OR012345:%.*]] = or i64 [[OR01234]], [[SH5]]
|
||||
; CHECK-NEXT: [[OR0123456:%.*]] = or i64 [[OR012345]], [[SH6]]
|
||||
; CHECK-NEXT: [[OR01234567:%.*]] = or i64 [[OR0123456]], [[Z7]]
|
||||
; CHECK-NEXT: ret i64 [[OR01234567]]
|
||||
;
|
||||
%g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1
|
||||
@ -60,10 +93,44 @@ define i64 @load_bswap(ptr %p) {
|
||||
|
||||
define i64 @load_bswap_nop_shift(ptr %p) {
|
||||
; CHECK-LABEL: @load_bswap_nop_shift(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = zext <8 x i8> [[TMP1]] to <8 x i64>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = shl nuw <8 x i64> [[TMP2]], <i64 56, i64 48, i64 40, i64 32, i64 24, i64 16, i64 8, i64 0>
|
||||
; CHECK-NEXT: [[OR01234567:%.*]] = call i64 @llvm.vector.reduce.or.v8i64(<8 x i64> [[TMP3]])
|
||||
; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [[V8I8:%.*]], ptr [[P:%.*]], i64 0, i32 1
|
||||
; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 2
|
||||
; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 3
|
||||
; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 4
|
||||
; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 5
|
||||
; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 6
|
||||
; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 7
|
||||
; CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[T1:%.*]] = load i8, ptr [[G1]], align 1
|
||||
; CHECK-NEXT: [[T2:%.*]] = load i8, ptr [[G2]], align 1
|
||||
; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[G3]], align 1
|
||||
; CHECK-NEXT: [[T4:%.*]] = load i8, ptr [[G4]], align 1
|
||||
; CHECK-NEXT: [[T5:%.*]] = load i8, ptr [[G5]], align 1
|
||||
; CHECK-NEXT: [[T6:%.*]] = load i8, ptr [[G6]], align 1
|
||||
; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[G7]], align 1
|
||||
; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[T0]] to i64
|
||||
; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[T1]] to i64
|
||||
; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[T2]] to i64
|
||||
; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[T3]] to i64
|
||||
; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[T4]] to i64
|
||||
; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[T5]] to i64
|
||||
; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[T6]] to i64
|
||||
; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[T7]] to i64
|
||||
; CHECK-NEXT: [[SH0:%.*]] = shl nuw i64 [[Z0]], 56
|
||||
; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw i64 [[Z1]], 48
|
||||
; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw i64 [[Z2]], 40
|
||||
; CHECK-NEXT: [[SH3:%.*]] = shl nuw nsw i64 [[Z3]], 32
|
||||
; CHECK-NEXT: [[SH4:%.*]] = shl nuw nsw i64 [[Z4]], 24
|
||||
; CHECK-NEXT: [[SH5:%.*]] = shl nuw nsw i64 [[Z5]], 16
|
||||
; CHECK-NEXT: [[SH6:%.*]] = shl nuw nsw i64 [[Z6]], 8
|
||||
; CHECK-NEXT: [[SH7:%.*]] = shl nuw nsw i64 [[Z7]], 0
|
||||
; CHECK-NEXT: [[OR01:%.*]] = or i64 [[SH0]], [[SH1]]
|
||||
; CHECK-NEXT: [[OR012:%.*]] = or i64 [[OR01]], [[SH2]]
|
||||
; CHECK-NEXT: [[OR0123:%.*]] = or i64 [[OR012]], [[SH3]]
|
||||
; CHECK-NEXT: [[OR01234:%.*]] = or i64 [[OR0123]], [[SH4]]
|
||||
; CHECK-NEXT: [[OR012345:%.*]] = or i64 [[OR01234]], [[SH5]]
|
||||
; CHECK-NEXT: [[OR0123456:%.*]] = or i64 [[OR012345]], [[SH6]]
|
||||
; CHECK-NEXT: [[OR01234567:%.*]] = or i64 [[OR0123456]], [[SH7]]
|
||||
; CHECK-NEXT: ret i64 [[OR01234567]]
|
||||
;
|
||||
%g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1
|
||||
@ -115,10 +182,43 @@ define i64 @load_bswap_nop_shift(ptr %p) {
|
||||
|
||||
define i64 @load64le(ptr %arg) {
|
||||
; CHECK-LABEL: @load64le(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[ARG:%.*]], align 1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = zext <8 x i8> [[TMP1]] to <8 x i64>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = shl <8 x i64> [[TMP2]], <i64 0, i64 8, i64 16, i64 24, i64 32, i64 40, i64 48, i64 56>
|
||||
; CHECK-NEXT: [[O7:%.*]] = call i64 @llvm.vector.reduce.or.v8i64(<8 x i64> [[TMP3]])
|
||||
; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1
|
||||
; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2
|
||||
; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 3
|
||||
; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 4
|
||||
; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 5
|
||||
; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 6
|
||||
; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 7
|
||||
; CHECK-NEXT: [[LD0:%.*]] = load i8, ptr [[ARG]], align 1
|
||||
; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[G1]], align 1
|
||||
; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[G2]], align 1
|
||||
; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[G3]], align 1
|
||||
; CHECK-NEXT: [[LD4:%.*]] = load i8, ptr [[G4]], align 1
|
||||
; CHECK-NEXT: [[LD5:%.*]] = load i8, ptr [[G5]], align 1
|
||||
; CHECK-NEXT: [[LD6:%.*]] = load i8, ptr [[G6]], align 1
|
||||
; CHECK-NEXT: [[LD7:%.*]] = load i8, ptr [[G7]], align 1
|
||||
; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[LD0]] to i64
|
||||
; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[LD1]] to i64
|
||||
; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[LD2]] to i64
|
||||
; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[LD3]] to i64
|
||||
; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[LD4]] to i64
|
||||
; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[LD5]] to i64
|
||||
; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[LD6]] to i64
|
||||
; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[LD7]] to i64
|
||||
; CHECK-NEXT: [[S1:%.*]] = shl nuw nsw i64 [[Z1]], 8
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i64 [[Z2]], 16
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i64 [[Z3]], 24
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw nsw i64 [[Z4]], 32
|
||||
; CHECK-NEXT: [[S5:%.*]] = shl nuw nsw i64 [[Z5]], 40
|
||||
; CHECK-NEXT: [[S6:%.*]] = shl nuw nsw i64 [[Z6]], 48
|
||||
; CHECK-NEXT: [[S7:%.*]] = shl nuw i64 [[Z7]], 56
|
||||
; CHECK-NEXT: [[O1:%.*]] = or i64 [[S1]], [[Z0]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or i64 [[O1]], [[S2]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or i64 [[O2]], [[S3]]
|
||||
; CHECK-NEXT: [[O4:%.*]] = or i64 [[O3]], [[S4]]
|
||||
; CHECK-NEXT: [[O5:%.*]] = or i64 [[O4]], [[S5]]
|
||||
; CHECK-NEXT: [[O6:%.*]] = or i64 [[O5]], [[S6]]
|
||||
; CHECK-NEXT: [[O7:%.*]] = or i64 [[O6]], [[S7]]
|
||||
; CHECK-NEXT: ret i64 [[O7]]
|
||||
;
|
||||
%g1 = getelementptr inbounds i8, ptr %arg, i64 1
|
||||
@ -168,10 +268,44 @@ define i64 @load64le(ptr %arg) {
|
||||
|
||||
define i64 @load64le_nop_shift(ptr %arg) {
|
||||
; CHECK-LABEL: @load64le_nop_shift(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[ARG:%.*]], align 1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = zext <8 x i8> [[TMP1]] to <8 x i64>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = shl nuw <8 x i64> [[TMP2]], <i64 0, i64 8, i64 16, i64 24, i64 32, i64 40, i64 48, i64 56>
|
||||
; CHECK-NEXT: [[O7:%.*]] = call i64 @llvm.vector.reduce.or.v8i64(<8 x i64> [[TMP3]])
|
||||
; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1
|
||||
; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2
|
||||
; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 3
|
||||
; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 4
|
||||
; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 5
|
||||
; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 6
|
||||
; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 7
|
||||
; CHECK-NEXT: [[LD0:%.*]] = load i8, ptr [[ARG]], align 1
|
||||
; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[G1]], align 1
|
||||
; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[G2]], align 1
|
||||
; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[G3]], align 1
|
||||
; CHECK-NEXT: [[LD4:%.*]] = load i8, ptr [[G4]], align 1
|
||||
; CHECK-NEXT: [[LD5:%.*]] = load i8, ptr [[G5]], align 1
|
||||
; CHECK-NEXT: [[LD6:%.*]] = load i8, ptr [[G6]], align 1
|
||||
; CHECK-NEXT: [[LD7:%.*]] = load i8, ptr [[G7]], align 1
|
||||
; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[LD0]] to i64
|
||||
; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[LD1]] to i64
|
||||
; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[LD2]] to i64
|
||||
; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[LD3]] to i64
|
||||
; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[LD4]] to i64
|
||||
; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[LD5]] to i64
|
||||
; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[LD6]] to i64
|
||||
; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[LD7]] to i64
|
||||
; CHECK-NEXT: [[S0:%.*]] = shl nuw nsw i64 [[Z0]], 0
|
||||
; CHECK-NEXT: [[S1:%.*]] = shl nuw nsw i64 [[Z1]], 8
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i64 [[Z2]], 16
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i64 [[Z3]], 24
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw nsw i64 [[Z4]], 32
|
||||
; CHECK-NEXT: [[S5:%.*]] = shl nuw nsw i64 [[Z5]], 40
|
||||
; CHECK-NEXT: [[S6:%.*]] = shl nuw nsw i64 [[Z6]], 48
|
||||
; CHECK-NEXT: [[S7:%.*]] = shl nuw i64 [[Z7]], 56
|
||||
; CHECK-NEXT: [[O1:%.*]] = or i64 [[S1]], [[S0]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or i64 [[O1]], [[S2]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or i64 [[O2]], [[S3]]
|
||||
; CHECK-NEXT: [[O4:%.*]] = or i64 [[O3]], [[S4]]
|
||||
; CHECK-NEXT: [[O5:%.*]] = or i64 [[O4]], [[S5]]
|
||||
; CHECK-NEXT: [[O6:%.*]] = or i64 [[O5]], [[S6]]
|
||||
; CHECK-NEXT: [[O7:%.*]] = or i64 [[O6]], [[S7]]
|
||||
; CHECK-NEXT: ret i64 [[O7]]
|
||||
;
|
||||
%g1 = getelementptr inbounds i8, ptr %arg, i64 1
|
||||
@ -221,8 +355,43 @@ define i64 @load64le_nop_shift(ptr %arg) {
|
||||
|
||||
define i64 @load_bswap_disjoint(ptr %p) {
|
||||
; CHECK-LABEL: @load_bswap_disjoint(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP1]])
|
||||
; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [[V8I8:%.*]], ptr [[P:%.*]], i64 0, i32 1
|
||||
; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 2
|
||||
; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 3
|
||||
; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 4
|
||||
; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 5
|
||||
; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 6
|
||||
; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 7
|
||||
; CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[T1:%.*]] = load i8, ptr [[G1]], align 1
|
||||
; CHECK-NEXT: [[T2:%.*]] = load i8, ptr [[G2]], align 1
|
||||
; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[G3]], align 1
|
||||
; CHECK-NEXT: [[T4:%.*]] = load i8, ptr [[G4]], align 1
|
||||
; CHECK-NEXT: [[T5:%.*]] = load i8, ptr [[G5]], align 1
|
||||
; CHECK-NEXT: [[T6:%.*]] = load i8, ptr [[G6]], align 1
|
||||
; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[G7]], align 1
|
||||
; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[T0]] to i64
|
||||
; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[T1]] to i64
|
||||
; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[T2]] to i64
|
||||
; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[T3]] to i64
|
||||
; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[T4]] to i64
|
||||
; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[T5]] to i64
|
||||
; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[T6]] to i64
|
||||
; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[T7]] to i64
|
||||
; CHECK-NEXT: [[SH0:%.*]] = shl nuw i64 [[Z0]], 56
|
||||
; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw i64 [[Z1]], 48
|
||||
; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw i64 [[Z2]], 40
|
||||
; CHECK-NEXT: [[SH3:%.*]] = shl nuw nsw i64 [[Z3]], 32
|
||||
; CHECK-NEXT: [[SH4:%.*]] = shl nuw nsw i64 [[Z4]], 24
|
||||
; CHECK-NEXT: [[SH5:%.*]] = shl nuw nsw i64 [[Z5]], 16
|
||||
; CHECK-NEXT: [[SH6:%.*]] = shl nuw nsw i64 [[Z6]], 8
|
||||
; CHECK-NEXT: [[OR01:%.*]] = or disjoint i64 [[SH0]], [[SH1]]
|
||||
; CHECK-NEXT: [[OR012:%.*]] = or disjoint i64 [[OR01]], [[SH2]]
|
||||
; CHECK-NEXT: [[OR0123:%.*]] = or disjoint i64 [[OR012]], [[SH3]]
|
||||
; CHECK-NEXT: [[OR01234:%.*]] = or disjoint i64 [[OR0123]], [[SH4]]
|
||||
; CHECK-NEXT: [[OR012345:%.*]] = or disjoint i64 [[OR01234]], [[SH5]]
|
||||
; CHECK-NEXT: [[OR0123456:%.*]] = or disjoint i64 [[OR012345]], [[SH6]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = or disjoint i64 [[OR0123456]], [[Z7]]
|
||||
; CHECK-NEXT: ret i64 [[TMP2]]
|
||||
;
|
||||
%g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1
|
||||
@ -272,8 +441,44 @@ define i64 @load_bswap_disjoint(ptr %p) {
|
||||
|
||||
define i64 @load_bswap_nop_shift_disjoint(ptr %p) {
|
||||
; CHECK-LABEL: @load_bswap_nop_shift_disjoint(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP1]])
|
||||
; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [[V8I8:%.*]], ptr [[P:%.*]], i64 0, i32 1
|
||||
; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 2
|
||||
; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 3
|
||||
; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 4
|
||||
; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 5
|
||||
; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 6
|
||||
; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds [[V8I8]], ptr [[P]], i64 0, i32 7
|
||||
; CHECK-NEXT: [[T0:%.*]] = load i8, ptr [[P]], align 1
|
||||
; CHECK-NEXT: [[T1:%.*]] = load i8, ptr [[G1]], align 1
|
||||
; CHECK-NEXT: [[T2:%.*]] = load i8, ptr [[G2]], align 1
|
||||
; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[G3]], align 1
|
||||
; CHECK-NEXT: [[T4:%.*]] = load i8, ptr [[G4]], align 1
|
||||
; CHECK-NEXT: [[T5:%.*]] = load i8, ptr [[G5]], align 1
|
||||
; CHECK-NEXT: [[T6:%.*]] = load i8, ptr [[G6]], align 1
|
||||
; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[G7]], align 1
|
||||
; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[T0]] to i64
|
||||
; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[T1]] to i64
|
||||
; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[T2]] to i64
|
||||
; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[T3]] to i64
|
||||
; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[T4]] to i64
|
||||
; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[T5]] to i64
|
||||
; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[T6]] to i64
|
||||
; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[T7]] to i64
|
||||
; CHECK-NEXT: [[SH0:%.*]] = shl nuw i64 [[Z0]], 56
|
||||
; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw i64 [[Z1]], 48
|
||||
; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw i64 [[Z2]], 40
|
||||
; CHECK-NEXT: [[SH3:%.*]] = shl nuw nsw i64 [[Z3]], 32
|
||||
; CHECK-NEXT: [[SH4:%.*]] = shl nuw nsw i64 [[Z4]], 24
|
||||
; CHECK-NEXT: [[SH5:%.*]] = shl nuw nsw i64 [[Z5]], 16
|
||||
; CHECK-NEXT: [[SH6:%.*]] = shl nuw nsw i64 [[Z6]], 8
|
||||
; CHECK-NEXT: [[SH7:%.*]] = shl nuw nsw i64 [[Z7]], 0
|
||||
; CHECK-NEXT: [[OR01:%.*]] = or disjoint i64 [[SH0]], [[SH1]]
|
||||
; CHECK-NEXT: [[OR012:%.*]] = or disjoint i64 [[OR01]], [[SH2]]
|
||||
; CHECK-NEXT: [[OR0123:%.*]] = or disjoint i64 [[OR012]], [[SH3]]
|
||||
; CHECK-NEXT: [[OR01234:%.*]] = or disjoint i64 [[OR0123]], [[SH4]]
|
||||
; CHECK-NEXT: [[OR012345:%.*]] = or disjoint i64 [[OR01234]], [[SH5]]
|
||||
; CHECK-NEXT: [[OR0123456:%.*]] = or disjoint i64 [[OR012345]], [[SH6]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = or disjoint i64 [[OR0123456]], [[SH7]]
|
||||
; CHECK-NEXT: ret i64 [[TMP2]]
|
||||
;
|
||||
%g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1
|
||||
@ -323,7 +528,43 @@ define i64 @load_bswap_nop_shift_disjoint(ptr %p) {
|
||||
|
||||
define i64 @load64le_disjoint(ptr %arg) {
|
||||
; CHECK-LABEL: @load64le_disjoint(
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 1
|
||||
; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1
|
||||
; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2
|
||||
; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 3
|
||||
; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 4
|
||||
; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 5
|
||||
; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 6
|
||||
; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 7
|
||||
; CHECK-NEXT: [[LD0:%.*]] = load i8, ptr [[ARG]], align 1
|
||||
; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[G1]], align 1
|
||||
; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[G2]], align 1
|
||||
; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[G3]], align 1
|
||||
; CHECK-NEXT: [[LD4:%.*]] = load i8, ptr [[G4]], align 1
|
||||
; CHECK-NEXT: [[LD5:%.*]] = load i8, ptr [[G5]], align 1
|
||||
; CHECK-NEXT: [[LD6:%.*]] = load i8, ptr [[G6]], align 1
|
||||
; CHECK-NEXT: [[LD7:%.*]] = load i8, ptr [[G7]], align 1
|
||||
; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[LD0]] to i64
|
||||
; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[LD1]] to i64
|
||||
; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[LD2]] to i64
|
||||
; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[LD3]] to i64
|
||||
; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[LD4]] to i64
|
||||
; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[LD5]] to i64
|
||||
; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[LD6]] to i64
|
||||
; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[LD7]] to i64
|
||||
; CHECK-NEXT: [[S1:%.*]] = shl nuw nsw i64 [[Z1]], 8
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i64 [[Z2]], 16
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i64 [[Z3]], 24
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw nsw i64 [[Z4]], 32
|
||||
; CHECK-NEXT: [[S5:%.*]] = shl nuw nsw i64 [[Z5]], 40
|
||||
; CHECK-NEXT: [[S6:%.*]] = shl nuw nsw i64 [[Z6]], 48
|
||||
; CHECK-NEXT: [[S7:%.*]] = shl nuw i64 [[Z7]], 56
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i64 [[S1]], [[Z0]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i64 [[O1]], [[S2]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i64 [[O2]], [[S3]]
|
||||
; CHECK-NEXT: [[O4:%.*]] = or disjoint i64 [[O3]], [[S4]]
|
||||
; CHECK-NEXT: [[O5:%.*]] = or disjoint i64 [[O4]], [[S5]]
|
||||
; CHECK-NEXT: [[O6:%.*]] = or disjoint i64 [[O5]], [[S6]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = or disjoint i64 [[O6]], [[S7]]
|
||||
; CHECK-NEXT: ret i64 [[TMP2]]
|
||||
;
|
||||
%g1 = getelementptr inbounds i8, ptr %arg, i64 1
|
||||
@ -373,7 +614,44 @@ define i64 @load64le_disjoint(ptr %arg) {
|
||||
|
||||
define i64 @load64le_nop_shift_disjoint(ptr %arg) {
|
||||
; CHECK-LABEL: @load64le_nop_shift_disjoint(
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 1
|
||||
; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1
|
||||
; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2
|
||||
; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 3
|
||||
; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 4
|
||||
; CHECK-NEXT: [[G5:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 5
|
||||
; CHECK-NEXT: [[G6:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 6
|
||||
; CHECK-NEXT: [[G7:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 7
|
||||
; CHECK-NEXT: [[LD0:%.*]] = load i8, ptr [[ARG]], align 1
|
||||
; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[G1]], align 1
|
||||
; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[G2]], align 1
|
||||
; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[G3]], align 1
|
||||
; CHECK-NEXT: [[LD4:%.*]] = load i8, ptr [[G4]], align 1
|
||||
; CHECK-NEXT: [[LD5:%.*]] = load i8, ptr [[G5]], align 1
|
||||
; CHECK-NEXT: [[LD6:%.*]] = load i8, ptr [[G6]], align 1
|
||||
; CHECK-NEXT: [[LD7:%.*]] = load i8, ptr [[G7]], align 1
|
||||
; CHECK-NEXT: [[Z0:%.*]] = zext i8 [[LD0]] to i64
|
||||
; CHECK-NEXT: [[Z1:%.*]] = zext i8 [[LD1]] to i64
|
||||
; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[LD2]] to i64
|
||||
; CHECK-NEXT: [[Z3:%.*]] = zext i8 [[LD3]] to i64
|
||||
; CHECK-NEXT: [[Z4:%.*]] = zext i8 [[LD4]] to i64
|
||||
; CHECK-NEXT: [[Z5:%.*]] = zext i8 [[LD5]] to i64
|
||||
; CHECK-NEXT: [[Z6:%.*]] = zext i8 [[LD6]] to i64
|
||||
; CHECK-NEXT: [[Z7:%.*]] = zext i8 [[LD7]] to i64
|
||||
; CHECK-NEXT: [[S0:%.*]] = shl nuw nsw i64 [[Z0]], 0
|
||||
; CHECK-NEXT: [[S1:%.*]] = shl nuw nsw i64 [[Z1]], 8
|
||||
; CHECK-NEXT: [[S2:%.*]] = shl nuw nsw i64 [[Z2]], 16
|
||||
; CHECK-NEXT: [[S3:%.*]] = shl nuw nsw i64 [[Z3]], 24
|
||||
; CHECK-NEXT: [[S4:%.*]] = shl nuw nsw i64 [[Z4]], 32
|
||||
; CHECK-NEXT: [[S5:%.*]] = shl nuw nsw i64 [[Z5]], 40
|
||||
; CHECK-NEXT: [[S6:%.*]] = shl nuw nsw i64 [[Z6]], 48
|
||||
; CHECK-NEXT: [[S7:%.*]] = shl nuw i64 [[Z7]], 56
|
||||
; CHECK-NEXT: [[O1:%.*]] = or disjoint i64 [[S1]], [[S0]]
|
||||
; CHECK-NEXT: [[O2:%.*]] = or disjoint i64 [[O1]], [[S2]]
|
||||
; CHECK-NEXT: [[O3:%.*]] = or disjoint i64 [[O2]], [[S3]]
|
||||
; CHECK-NEXT: [[O4:%.*]] = or disjoint i64 [[O3]], [[S4]]
|
||||
; CHECK-NEXT: [[O5:%.*]] = or disjoint i64 [[O4]], [[S5]]
|
||||
; CHECK-NEXT: [[O6:%.*]] = or disjoint i64 [[O5]], [[S6]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = or disjoint i64 [[O6]], [[S7]]
|
||||
; CHECK-NEXT: ret i64 [[TMP2]]
|
||||
;
|
||||
%g1 = getelementptr inbounds i8, ptr %arg, i64 1
|
||||
@ -423,22 +701,84 @@ define i64 @load64le_nop_shift_disjoint(ptr %arg) {
|
||||
|
||||
define void @PR39538(ptr %t0, ptr %t1) {
|
||||
; CHECK-LABEL: @PR39538(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, ptr [[T0:%.*]], align 1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <4 x i32> <i32 1, i32 4, i32 9, i32 12>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = zext <4 x i8> [[TMP2]] to <4 x i32>
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <4 x i32> <i32 0, i32 5, i32 8, i32 13>
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32>
|
||||
; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <4 x i32> <i32 2, i32 6, i32 10, i32 14>
|
||||
; CHECK-NEXT: [[TMP7:%.*]] = zext <4 x i8> [[TMP6]] to <4 x i32>
|
||||
; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <4 x i32> <i32 3, i32 7, i32 11, i32 15>
|
||||
; CHECK-NEXT: [[TMP9:%.*]] = zext <4 x i8> [[TMP8]] to <4 x i32>
|
||||
; CHECK-NEXT: [[TMP10:%.*]] = shl nuw <4 x i32> [[TMP3]], <i32 16, i32 24, i32 16, i32 24>
|
||||
; CHECK-NEXT: [[TMP11:%.*]] = shl nuw <4 x i32> [[TMP5]], <i32 24, i32 16, i32 24, i32 16>
|
||||
; CHECK-NEXT: [[TMP12:%.*]] = shl nuw nsw <4 x i32> [[TMP7]], splat (i32 8)
|
||||
; CHECK-NEXT: [[TMP13:%.*]] = or <4 x i32> [[TMP11]], [[TMP10]]
|
||||
; CHECK-NEXT: [[TMP14:%.*]] = or <4 x i32> [[TMP13]], [[TMP12]]
|
||||
; CHECK-NEXT: [[TMP15:%.*]] = or <4 x i32> [[TMP14]], [[TMP9]]
|
||||
; CHECK-NEXT: store <4 x i32> [[TMP15]], ptr [[T1:%.*]], align 4
|
||||
; CHECK-NEXT: [[T6:%.*]] = getelementptr inbounds i8, ptr [[T0:%.*]], i64 1
|
||||
; CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 2
|
||||
; CHECK-NEXT: [[T16:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 3
|
||||
; CHECK-NEXT: [[T20:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 4
|
||||
; CHECK-NEXT: [[T24:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 5
|
||||
; CHECK-NEXT: [[T29:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 6
|
||||
; CHECK-NEXT: [[T34:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 7
|
||||
; CHECK-NEXT: [[T39:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 8
|
||||
; CHECK-NEXT: [[T43:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 9
|
||||
; CHECK-NEXT: [[T48:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 10
|
||||
; CHECK-NEXT: [[T53:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 11
|
||||
; CHECK-NEXT: [[T58:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 12
|
||||
; CHECK-NEXT: [[T62:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 13
|
||||
; CHECK-NEXT: [[T67:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 14
|
||||
; CHECK-NEXT: [[T72:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 15
|
||||
; CHECK-NEXT: [[T38:%.*]] = getelementptr inbounds i32, ptr [[T1:%.*]], i64 1
|
||||
; CHECK-NEXT: [[T57:%.*]] = getelementptr inbounds i32, ptr [[T1]], i64 2
|
||||
; CHECK-NEXT: [[T76:%.*]] = getelementptr inbounds i32, ptr [[T1]], i64 3
|
||||
; CHECK-NEXT: [[T3:%.*]] = load i8, ptr [[T0]], align 1
|
||||
; CHECK-NEXT: [[T7:%.*]] = load i8, ptr [[T6]], align 1
|
||||
; CHECK-NEXT: [[T12:%.*]] = load i8, ptr [[T11]], align 1
|
||||
; CHECK-NEXT: [[T17:%.*]] = load i8, ptr [[T16]], align 1
|
||||
; CHECK-NEXT: [[T21:%.*]] = load i8, ptr [[T20]], align 1
|
||||
; CHECK-NEXT: [[T25:%.*]] = load i8, ptr [[T24]], align 1
|
||||
; CHECK-NEXT: [[T30:%.*]] = load i8, ptr [[T29]], align 1
|
||||
; CHECK-NEXT: [[T35:%.*]] = load i8, ptr [[T34]], align 1
|
||||
; CHECK-NEXT: [[T40:%.*]] = load i8, ptr [[T39]], align 1
|
||||
; CHECK-NEXT: [[T44:%.*]] = load i8, ptr [[T43]], align 1
|
||||
; CHECK-NEXT: [[T49:%.*]] = load i8, ptr [[T48]], align 1
|
||||
; CHECK-NEXT: [[T54:%.*]] = load i8, ptr [[T53]], align 1
|
||||
; CHECK-NEXT: [[T59:%.*]] = load i8, ptr [[T58]], align 1
|
||||
; CHECK-NEXT: [[T63:%.*]] = load i8, ptr [[T62]], align 1
|
||||
; CHECK-NEXT: [[T68:%.*]] = load i8, ptr [[T67]], align 1
|
||||
; CHECK-NEXT: [[T73:%.*]] = load i8, ptr [[T72]], align 1
|
||||
; CHECK-NEXT: [[T4:%.*]] = zext i8 [[T3]] to i32
|
||||
; CHECK-NEXT: [[T8:%.*]] = zext i8 [[T7]] to i32
|
||||
; CHECK-NEXT: [[T13:%.*]] = zext i8 [[T12]] to i32
|
||||
; CHECK-NEXT: [[T18:%.*]] = zext i8 [[T17]] to i32
|
||||
; CHECK-NEXT: [[T22:%.*]] = zext i8 [[T21]] to i32
|
||||
; CHECK-NEXT: [[T26:%.*]] = zext i8 [[T25]] to i32
|
||||
; CHECK-NEXT: [[T31:%.*]] = zext i8 [[T30]] to i32
|
||||
; CHECK-NEXT: [[T36:%.*]] = zext i8 [[T35]] to i32
|
||||
; CHECK-NEXT: [[T41:%.*]] = zext i8 [[T40]] to i32
|
||||
; CHECK-NEXT: [[T45:%.*]] = zext i8 [[T44]] to i32
|
||||
; CHECK-NEXT: [[T50:%.*]] = zext i8 [[T49]] to i32
|
||||
; CHECK-NEXT: [[T55:%.*]] = zext i8 [[T54]] to i32
|
||||
; CHECK-NEXT: [[T60:%.*]] = zext i8 [[T59]] to i32
|
||||
; CHECK-NEXT: [[T64:%.*]] = zext i8 [[T63]] to i32
|
||||
; CHECK-NEXT: [[T69:%.*]] = zext i8 [[T68]] to i32
|
||||
; CHECK-NEXT: [[T74:%.*]] = zext i8 [[T73]] to i32
|
||||
; CHECK-NEXT: [[T5:%.*]] = shl nuw i32 [[T4]], 24
|
||||
; CHECK-NEXT: [[T23:%.*]] = shl nuw i32 [[T22]], 24
|
||||
; CHECK-NEXT: [[T42:%.*]] = shl nuw i32 [[T41]], 24
|
||||
; CHECK-NEXT: [[T61:%.*]] = shl nuw i32 [[T60]], 24
|
||||
; CHECK-NEXT: [[T9:%.*]] = shl nuw nsw i32 [[T8]], 16
|
||||
; CHECK-NEXT: [[T27:%.*]] = shl nuw nsw i32 [[T26]], 16
|
||||
; CHECK-NEXT: [[T46:%.*]] = shl nuw nsw i32 [[T45]], 16
|
||||
; CHECK-NEXT: [[T65:%.*]] = shl nuw nsw i32 [[T64]], 16
|
||||
; CHECK-NEXT: [[T14:%.*]] = shl nuw nsw i32 [[T13]], 8
|
||||
; CHECK-NEXT: [[T32:%.*]] = shl nuw nsw i32 [[T31]], 8
|
||||
; CHECK-NEXT: [[T51:%.*]] = shl nuw nsw i32 [[T50]], 8
|
||||
; CHECK-NEXT: [[T70:%.*]] = shl nuw nsw i32 [[T69]], 8
|
||||
; CHECK-NEXT: [[T10:%.*]] = or i32 [[T9]], [[T5]]
|
||||
; CHECK-NEXT: [[T15:%.*]] = or i32 [[T10]], [[T14]]
|
||||
; CHECK-NEXT: [[T19:%.*]] = or i32 [[T15]], [[T18]]
|
||||
; CHECK-NEXT: [[T28:%.*]] = or i32 [[T27]], [[T23]]
|
||||
; CHECK-NEXT: [[T33:%.*]] = or i32 [[T28]], [[T32]]
|
||||
; CHECK-NEXT: [[T37:%.*]] = or i32 [[T33]], [[T36]]
|
||||
; CHECK-NEXT: [[T47:%.*]] = or i32 [[T46]], [[T42]]
|
||||
; CHECK-NEXT: [[T52:%.*]] = or i32 [[T47]], [[T51]]
|
||||
; CHECK-NEXT: [[T56:%.*]] = or i32 [[T52]], [[T55]]
|
||||
; CHECK-NEXT: [[T66:%.*]] = or i32 [[T65]], [[T61]]
|
||||
; CHECK-NEXT: [[T71:%.*]] = or i32 [[T66]], [[T70]]
|
||||
; CHECK-NEXT: [[T75:%.*]] = or i32 [[T71]], [[T74]]
|
||||
; CHECK-NEXT: store i32 [[T19]], ptr [[T1]], align 4
|
||||
; CHECK-NEXT: store i32 [[T37]], ptr [[T38]], align 4
|
||||
; CHECK-NEXT: store i32 [[T56]], ptr [[T57]], align 4
|
||||
; CHECK-NEXT: store i32 [[T75]], ptr [[T76]], align 4
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%t6 = getelementptr inbounds i8, ptr %t0, i64 1
|
||||
|
||||
@ -10,10 +10,23 @@
|
||||
define i32 @_Z9load_le32Ph(ptr nocapture readonly %data) {
|
||||
; CHECK-LABEL: @_Z9load_le32Ph(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i8>, ptr [[DATA:%.*]], align 1
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i8> [[TMP0]] to <4 x i32>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = shl <4 x i32> [[TMP1]], <i32 0, i32 8, i32 16, i32 24>
|
||||
; CHECK-NEXT: [[OR11:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP2]])
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[DATA:%.*]], align 1
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[TMP0]] to i32
|
||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[DATA]], i64 1
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
|
||||
; CHECK-NEXT: [[CONV2:%.*]] = zext i8 [[TMP1]] to i32
|
||||
; CHECK-NEXT: [[SHL3:%.*]] = shl nuw nsw i32 [[CONV2]], 8
|
||||
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL3]], [[CONV]]
|
||||
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[DATA]], i64 2
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ARRAYIDX4]], align 1
|
||||
; CHECK-NEXT: [[CONV5:%.*]] = zext i8 [[TMP2]] to i32
|
||||
; CHECK-NEXT: [[SHL6:%.*]] = shl nuw nsw i32 [[CONV5]], 16
|
||||
; CHECK-NEXT: [[OR7:%.*]] = or i32 [[OR]], [[SHL6]]
|
||||
; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, ptr [[DATA]], i64 3
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX8]], align 1
|
||||
; CHECK-NEXT: [[CONV9:%.*]] = zext i8 [[TMP3]] to i32
|
||||
; CHECK-NEXT: [[SHL10:%.*]] = shl nuw i32 [[CONV9]], 24
|
||||
; CHECK-NEXT: [[OR11:%.*]] = or i32 [[OR7]], [[SHL10]]
|
||||
; CHECK-NEXT: ret i32 [[OR11]]
|
||||
;
|
||||
entry:
|
||||
|
||||
@ -10,10 +10,23 @@
|
||||
define i32 @_Z9load_le32Ph(ptr nocapture readonly %data) {
|
||||
; CHECK-LABEL: @_Z9load_le32Ph(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i8>, ptr [[DATA:%.*]], align 1
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i8> [[TMP0]] to <4 x i32>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = shl <4 x i32> [[TMP1]], <i32 0, i32 8, i32 16, i32 24>
|
||||
; CHECK-NEXT: [[OR11:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP2]])
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[DATA:%.*]], align 1
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[TMP0]] to i32
|
||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[DATA]], i64 1
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
|
||||
; CHECK-NEXT: [[CONV2:%.*]] = zext i8 [[TMP1]] to i32
|
||||
; CHECK-NEXT: [[SHL3:%.*]] = shl nuw nsw i32 [[CONV2]], 8
|
||||
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL3]], [[CONV]]
|
||||
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[DATA]], i64 2
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ARRAYIDX4]], align 1
|
||||
; CHECK-NEXT: [[CONV5:%.*]] = zext i8 [[TMP2]] to i32
|
||||
; CHECK-NEXT: [[SHL6:%.*]] = shl nuw nsw i32 [[CONV5]], 16
|
||||
; CHECK-NEXT: [[OR7:%.*]] = or i32 [[OR]], [[SHL6]]
|
||||
; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, ptr [[DATA]], i64 3
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX8]], align 1
|
||||
; CHECK-NEXT: [[CONV9:%.*]] = zext i8 [[TMP3]] to i32
|
||||
; CHECK-NEXT: [[SHL10:%.*]] = shl nuw i32 [[CONV9]], 24
|
||||
; CHECK-NEXT: [[OR11:%.*]] = or i32 [[OR7]], [[SHL10]]
|
||||
; CHECK-NEXT: ret i32 [[OR11]]
|
||||
;
|
||||
entry:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user