diff options
| author | Dinar Temirbulatov <dtemirbulatov@gmail.com> | 2019-06-05 15:26:28 +0000 |
|---|---|---|
| committer | Dinar Temirbulatov <dtemirbulatov@gmail.com> | 2019-06-05 15:26:28 +0000 |
| commit | 15c657d13d6f12ec4f9c77af8c5034caca9ba7d7 (patch) | |
| tree | fae1ec56093b37ea1ac5f8d31c3df69cb4fa343c /llvm/lib/Transforms/Vectorize | |
| parent | ad62a3a2992744dc9e16fcb248841d7e27be3b7e (diff) | |
| download | bcm5719-llvm-15c657d13d6f12ec4f9c77af8c5034caca9ba7d7.tar.gz bcm5719-llvm-15c657d13d6f12ec4f9c77af8c5034caca9ba7d7.zip | |
[SLP] Fix regression in broadcasts caused by operand reordering patch D59973.
This patch fixes a regression caused by the operand reordering refactoring patch https://reviews.llvm.org/D59973 .
The fix changes the strategy to Splat instead of Opcode, if broadcast opportunities are found.
Please see the lit test for some examples.
Committed on behalf of @vporpo (Vasileios Porpodas)
Differential Revision: https://reviews.llvm.org/D62427
llvm-svn: 362613
Diffstat (limited to 'llvm/lib/Transforms/Vectorize')
| -rw-r--r-- | llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 72fc9cf41ef..2da9ead14ca 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -917,6 +917,32 @@ public: /// Clears the data. void clear() { OpsVec.clear(); } + /// \Returns true if there are enough operands identical to \p Op to fill + /// the whole vector. + /// Note: This modifies the 'IsUsed' flag, so a cleanUsed() must follow. + bool shouldBroadcast(Value *Op, unsigned OpIdx, unsigned Lane) { + bool OpAPO = getData(OpIdx, Lane).APO; + for (unsigned Ln = 0, Lns = getNumLanes(); Ln != Lns; ++Ln) { + if (Ln == Lane) + continue; + // This is set to true if we found a candidate for broadcast at Lane. + bool FoundCandidate = false; + for (unsigned OpI = 0, OpE = getNumOperands(); OpI != OpE; ++OpI) { + OperandData &Data = getData(OpI, Ln); + if (Data.APO != OpAPO || Data.IsUsed) + continue; + if (Data.V == Op) { + FoundCandidate = true; + Data.IsUsed = true; + break; + } + } + if (!FoundCandidate) + return false; + } + return true; + } + public: /// Initialize with all the operands of the instruction vector \p RootVL. VLOperands(ArrayRef<Value *> RootVL, const DataLayout &DL, @@ -971,8 +997,13 @@ public: // side. if (isa<LoadInst>(OpLane0)) ReorderingModes[OpIdx] = ReorderingMode::Load; - else if (isa<Instruction>(OpLane0)) - ReorderingModes[OpIdx] = ReorderingMode::Opcode; + else if (isa<Instruction>(OpLane0)) { + // Check if OpLane0 should be broadcast. + if (shouldBroadcast(OpLane0, OpIdx, FirstLane)) + ReorderingModes[OpIdx] = ReorderingMode::Splat; + else + ReorderingModes[OpIdx] = ReorderingMode::Opcode; + } else if (isa<Constant>(OpLane0)) ReorderingModes[OpIdx] = ReorderingMode::Constant; else if (isa<Argument>(OpLane0)) @@ -990,9 +1021,8 @@ public: for (int Pass = 0; Pass != 2; ++Pass) { // Skip the second pass if the first pass did not fail. bool StrategyFailed = false; - // Mark the operand data as free to use for all but the first pass. - if (Pass > 0) - clearUsed(); + // Mark all operand data as free to use. + clearUsed(); // We keep the original operand order for the FirstLane, so reorder the // rest of the lanes. We are visiting the nodes in a circular fashion, // using FirstLane as the center point and increasing the radius |

