From 1e564504bb17c65a46bbd7dc2ee6a45e78a8101e Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Fri, 22 Jun 2018 14:04:06 +0000 Subject: [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 --- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 38 +++++++------------------ 1 file changed, 11 insertions(+), 27 deletions(-) (limited to 'llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp') 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 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 VL, if (llvm::any_of(VL, [](Value *V) { return !isa(V); })) return InstructionsState(VL[BaseIndex], 0, 0); + bool IsBinOp = isa(VL[BaseIndex]); unsigned Opcode = cast(VL[BaseIndex])->getOpcode(); unsigned AltOpcode = Opcode; - bool HasAltOpcodes = llvm::any_of(VL, [Opcode](Value *V) { - return Opcode != cast(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(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(VL[Cnt])->getOpcode(); + if (!sameOpcodeOrAlt(Opcode, AltOpcode, InstOpcode)) { + if (Opcode == AltOpcode && IsBinOp && isa(VL[Cnt])) { + AltOpcode = InstOpcode; + continue; + } + return InstructionsState(VL[BaseIndex], 0, 0); } } -- cgit v1.2.3