diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-06-22 14:04:06 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-06-22 14:04:06 +0000 |
commit | 1e564504bb17c65a46bbd7dc2ee6a45e78a8101e (patch) | |
tree | ef473bc65b017043e3345c764543a5b7bd8fe70d /llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | |
parent | 229a7812140c720ef45efb1e5711c388bc6c9d2a (diff) | |
download | bcm5719-llvm-1e564504bb17c65a46bbd7dc2ee6a45e78a8101e.tar.gz bcm5719-llvm-1e564504bb17c65a46bbd7dc2ee6a45e78a8101e.zip |
[SLPVectorizer] Relax alternate opcodes to accept any BinaryOperator pair
SLP currently only accepts (F)Add/(F)Sub alternate counterpart ops to be merged into an alternate shuffle.
This patch relaxes this to accept any pair of BinaryOperator opcodes instead, assuming the target's cost model accepts the vectorization+shuffle.
Differential Revision: https://reviews.llvm.org/D48477
llvm-svn: 335349
Diffstat (limited to 'llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp')
-rw-r--r-- | llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 38 |
1 files changed, 11 insertions, 27 deletions
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index eefb50a5037..a4d36e256e8 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -299,23 +299,6 @@ isShuffle(ArrayRef<Value *> VL) { : TargetTransformInfo::SK_PermuteSingleSrc; } -///\returns Opcode that can be clubbed with \p Op to create an alternate -/// sequence which can later be merged as a ShuffleVector instruction. -static unsigned getAltOpcode(unsigned Op) { - switch (Op) { - case Instruction::FAdd: - return Instruction::FSub; - case Instruction::FSub: - return Instruction::FAdd; - case Instruction::Add: - return Instruction::Sub; - case Instruction::Sub: - return Instruction::Add; - default: - return 0; - } -} - static bool sameOpcodeOrAlt(unsigned Opcode, unsigned AltOpcode, unsigned CheckedOpcode) { return Opcode == CheckedOpcode || AltOpcode == CheckedOpcode; @@ -361,19 +344,20 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL, if (llvm::any_of(VL, [](Value *V) { return !isa<Instruction>(V); })) return InstructionsState(VL[BaseIndex], 0, 0); + bool IsBinOp = isa<BinaryOperator>(VL[BaseIndex]); unsigned Opcode = cast<Instruction>(VL[BaseIndex])->getOpcode(); unsigned AltOpcode = Opcode; - bool HasAltOpcodes = llvm::any_of(VL, [Opcode](Value *V) { - return Opcode != cast<Instruction>(V)->getOpcode(); - }); - // Check for an alternate opcode pattern. - if (HasAltOpcodes) { - AltOpcode = getAltOpcode(Opcode); - for (int Cnt = 0, E = VL.size(); Cnt < E; Cnt++) { - unsigned InstOpcode = cast<Instruction>(VL[Cnt])->getOpcode(); - if (!sameOpcodeOrAlt(Opcode, AltOpcode, InstOpcode)) - return InstructionsState(VL[BaseIndex], 0, 0); + // Check for one alternate opcode from another BinaryOperator. + // TODO - can we support other operators (casts etc.)? + for (int Cnt = 0, E = VL.size(); Cnt < E; Cnt++) { + unsigned InstOpcode = cast<Instruction>(VL[Cnt])->getOpcode(); + if (!sameOpcodeOrAlt(Opcode, AltOpcode, InstOpcode)) { + if (Opcode == AltOpcode && IsBinOp && isa<BinaryOperator>(VL[Cnt])) { + AltOpcode = InstOpcode; + continue; + } + return InstructionsState(VL[BaseIndex], 0, 0); } } |