Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 22 additions & 20 deletions llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2403,14 +2403,13 @@ class BoUpSLP {
}

/// Go through the instructions in VL and append their operands.
void appendOperandsOfVL(ArrayRef<Value *> VL) {
void appendOperandsOfVL(ArrayRef<Value *> VL, Instruction *VL0) {
assert(!VL.empty() && "Bad VL");
assert((empty() || VL.size() == getNumLanes()) &&
"Expected same number of lanes");
// IntrinsicInst::isCommutative returns true if swapping the first "two"
// arguments to the intrinsic produces the same result.
constexpr unsigned IntrinsicNumOperands = 2;
auto *VL0 = cast<Instruction>(*find_if(VL, IsaPred<Instruction>));
unsigned NumOperands = VL0->getNumOperands();
ArgSize = isa<IntrinsicInst>(VL0) ? IntrinsicNumOperands : NumOperands;
OpsVec.resize(NumOperands);
Expand Down Expand Up @@ -2542,15 +2541,19 @@ class BoUpSLP {

public:
/// Initialize with all the operands of the instruction vector \p RootVL.
VLOperands(ArrayRef<Value *> RootVL, const BoUpSLP &R)
VLOperands(ArrayRef<Value *> RootVL, const BoUpSLP &R, Instruction *VL0)
: TLI(*R.TLI), DL(*R.DL), SE(*R.SE), R(R),
L(R.LI->getLoopFor(
(cast<Instruction>(*find_if(RootVL, IsaPred<Instruction>))
->getParent()))) {
L(R.LI->getLoopFor((VL0->getParent()))) {
// Append all the operands of RootVL.
appendOperandsOfVL(RootVL);
appendOperandsOfVL(RootVL, VL0);
}

/// Initialize with all the operands of the instruction vector \p RootVL.
VLOperands(ArrayRef<Value *> RootVL, const BoUpSLP &R)
: VLOperands(
RootVL, R,
cast<Instruction>(*find_if(RootVL, IsaPred<Instruction>))) {}

/// \Returns a value vector with the operands across all lanes for the
/// opearnd at \p OpIdx.
ValueList getVL(unsigned OpIdx) const {
Expand Down Expand Up @@ -3338,14 +3341,13 @@ class BoUpSLP {
copy(OpVL, Operands[OpIdx].begin());
}

/// Set this bundle's operand from \p VL.
void setOperand(ArrayRef<Value *> VL, const BoUpSLP &R,
bool RequireReorder = false) {
VLOperands Ops(VL, R);
/// Set this bundle's operand from Scalars.
void setOperand(const BoUpSLP &R, bool RequireReorder = false) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to pass first instruction as an argument rather than redo the search for it

auto *I0 = cast<Instruction>(*find_if(Scalars, IsaPred<Instruction>));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still looking for the instruction here, better to pass it as an argument or make it part of VLOperands class, just like Scalars

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I0 is passed to VLOperands Ops(Scalars, R, I0); to reduce the search. Is this not good?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still redo search here

VLOperands Ops(Scalars, R, I0);
if (RequireReorder)
Ops.reorder();
for (unsigned I :
seq<unsigned>(cast<Instruction>(VL[0])->getNumOperands()))
for (unsigned I : seq<unsigned>(I0->getNumOperands()))
setOperand(I, Ops.getVL(I));
}

Expand Down Expand Up @@ -8446,7 +8448,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
{}, CurrentOrder);
LLVM_DEBUG(dbgs() << "SLP: added inserts bundle.\n");

TE->setOperand(VL, *this);
TE->setOperand(*this);
buildTree_rec(TE->getOperand(1), Depth + 1, {TE, 1});
return;
}
Expand Down Expand Up @@ -8484,7 +8486,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
case TreeEntry::NeedToGather:
llvm_unreachable("Unexpected loads state.");
}
TE->setOperand(VL, *this);
TE->setOperand(*this);
if (State == TreeEntry::ScatterVectorize)
buildTree_rec(PointerOps, Depth + 1, {TE, 0});
return;
Expand Down Expand Up @@ -8524,7 +8526,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
ReuseShuffleIndices);
LLVM_DEBUG(dbgs() << "SLP: added a vector of casts.\n");

TE->setOperand(VL, *this);
TE->setOperand(*this);
for (unsigned I : seq<unsigned>(VL0->getNumOperands()))
buildTree_rec(TE->getOperand(I), Depth + 1, {TE, I});
if (ShuffleOrOp == Instruction::Trunc) {
Expand Down Expand Up @@ -8621,7 +8623,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
ReuseShuffleIndices);
LLVM_DEBUG(dbgs() << "SLP: added a vector of un/bin op.\n");

TE->setOperand(VL, *this, isa<BinaryOperator>(VL0) && isCommutative(VL0));
TE->setOperand(*this, isa<BinaryOperator>(VL0) && isCommutative(VL0));
for (unsigned I : seq<unsigned>(VL0->getNumOperands()))
buildTree_rec(TE->getOperand(I), Depth + 1, {TE, I});
return;
Expand Down Expand Up @@ -8687,7 +8689,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
fixupOrderingIndices(CurrentOrder);
TreeEntry *TE = newTreeEntry(VL, Bundle /*vectorized*/, S, UserTreeIdx,
ReuseShuffleIndices, CurrentOrder);
TE->setOperand(VL, *this);
TE->setOperand(*this);
buildTree_rec(TE->getOperand(0), Depth + 1, {TE, 0});
if (Consecutive)
LLVM_DEBUG(dbgs() << "SLP: added a vector of stores.\n");
Expand All @@ -8703,7 +8705,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,

TreeEntry *TE = newTreeEntry(VL, Bundle /*vectorized*/, S, UserTreeIdx,
ReuseShuffleIndices);
TE->setOperand(VL, *this, isCommutative(VL0));
TE->setOperand(*this, isCommutative(VL0));
for (unsigned I : seq<unsigned>(CI->arg_size())) {
// For scalar operands no need to create an entry since no need to
// vectorize it.
Expand Down Expand Up @@ -8759,7 +8761,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
return;
}

TE->setOperand(VL, *this, isa<BinaryOperator>(VL0) || CI);
TE->setOperand(*this, isa<BinaryOperator>(VL0) || CI);
for (unsigned I : seq<unsigned>(VL0->getNumOperands()))
buildTree_rec(TE->getOperand(I), Depth + 1, {TE, I});
return;
Expand Down
19 changes: 19 additions & 0 deletions llvm/test/Transforms/SLPVectorizer/fix-113880.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=slp-vectorizer -S -slp-max-reg-size=1024 %s | FileCheck %s

define ptr @test() {
; CHECK-LABEL: @test(
; CHECK-NEXT: store <4 x double> <double poison, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00>, ptr null, align 8
; CHECK-NEXT: ret ptr null
;
store double poison, ptr null, align 8
%1 = getelementptr i8, ptr null, i64 8
%2 = fmul double 0.000000e+00, 0.000000e+00
store double %2, ptr %1, align 8
%3 = getelementptr i8, ptr null, i64 16
%4 = fmul double 0.000000e+00, 0.000000e+00
store double %4, ptr %3, align 8
%5 = getelementptr i8, ptr null, i64 24
store double %2, ptr %5, align 8
ret ptr null
}
Loading