Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
37 changes: 17 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,13 +2541,11 @@ 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, Instruction *VL0, const BoUpSLP &R)
Copy link
Member

Choose a reason for hiding this comment

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

Make VL0 a member of the сlass, it is used in too many cases

Copy link
Contributor Author

Choose a reason for hiding this comment

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

VL0 is only used by the constructor of VLOperands. I think you mean "Make VL0 a member of TreeEntry"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we need to put VL0 into TreeEntry, I suggest we open the original PR (#113880 (comment)) and review there.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, no, no, need it.

: 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);
}

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

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

Choose a reason for hiding this comment

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

Instead of passing VL0 here, I think you can safely use MainOp member instruction

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need this one #118609.

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

Expand Down Expand Up @@ -8446,7 +8442,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(VL0, *this);
buildTree_rec(TE->getOperand(1), Depth + 1, {TE, 1});
return;
}
Expand Down Expand Up @@ -8484,7 +8480,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
case TreeEntry::NeedToGather:
llvm_unreachable("Unexpected loads state.");
}
TE->setOperand(VL, *this);
TE->setOperand(VL0, *this);
if (State == TreeEntry::ScatterVectorize)
buildTree_rec(PointerOps, Depth + 1, {TE, 0});
return;
Expand Down Expand Up @@ -8524,7 +8520,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(VL0, *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 @@ -8552,7 +8548,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
LLVM_DEBUG(dbgs() << "SLP: added a vector of compares.\n");

ValueList Left, Right;
VLOperands Ops(VL, *this);
VLOperands Ops(VL, VL0, *this);
if (cast<CmpInst>(VL0)->isCommutative()) {
// Commutative predicate - collect + sort operands of the instructions
// so that each side is more likely to have the same opcode.
Expand Down Expand Up @@ -8621,7 +8617,8 @@ 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(VL0, *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 +8684,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(VL0, *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 +8700,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(VL0, *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 +8756,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
return;
}

TE->setOperand(VL, *this, isa<BinaryOperator>(VL0) || CI);
TE->setOperand(VL0, *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