diff --git a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp --- a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp +++ b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp @@ -271,8 +271,6 @@ bool identifyNodes(Instruction *RootI); /// Perform the actual replacement of the underlying instruction graph. - /// Returns false if the deinterleaving operation should be cancelled for the - /// current graph. void replaceNodes(); }; @@ -598,8 +596,16 @@ Rotation == ComplexDeinterleavingRotation::Rotation_270) ? CommonOperand : nullptr); - NodePtr CNode = identifyNodeWithImplicitAdd( - cast(CR), cast(CI), PartialMatch); + + auto *CRInst = dyn_cast(CR); + auto *CIInst = dyn_cast(CI); + + if (!CRInst || !CIInst) { + LLVM_DEBUG(dbgs() << " - Common operands are not instructions.\n"); + return nullptr; + } + + NodePtr CNode = identifyNodeWithImplicitAdd(CRInst, CIInst, PartialMatch); if (!CNode) { LLVM_DEBUG(dbgs() << " - No cnode identified\n"); return nullptr; @@ -633,20 +639,21 @@ ComplexDeinterleavingGraph::identifyAdd(Instruction *Real, Instruction *Imag) { LLVM_DEBUG(dbgs() << "identifyAdd " << *Real << " / " << *Imag << "\n"); - // Determine rotation - ComplexDeinterleavingRotation Rotation; - if ((Real->getOpcode() == Instruction::FSub && - Imag->getOpcode() == Instruction::FAdd) || - (Real->getOpcode() == Instruction::Sub && - Imag->getOpcode() == Instruction::Add)) - Rotation = ComplexDeinterleavingRotation::Rotation_90; - else if ((Real->getOpcode() == Instruction::FAdd && - Imag->getOpcode() == Instruction::FSub) || - (Real->getOpcode() == Instruction::Add && - Imag->getOpcode() == Instruction::Sub)) - Rotation = ComplexDeinterleavingRotation::Rotation_270; - else { - LLVM_DEBUG(dbgs() << " - Unhandled case, rotation is not assigned.\n"); + unsigned RotKey = 0; + RotKey |= Real->getOpcode() == Instruction::FSub || + Real->getOpcode() == Instruction::Sub; + RotKey |= ((Imag->getOpcode() == Instruction::FSub || + Imag->getOpcode() == Instruction::Sub) + << 1); + if ((RotKey & 2) == 2) + RotKey ^= 1; + + ComplexDeinterleavingRotation Rotation = + (ComplexDeinterleavingRotation)RotKey; + + if (Rotation == llvm::ComplexDeinterleavingRotation::Rotation_0 || + Rotation == llvm::ComplexDeinterleavingRotation::Rotation_180) { + LLVM_DEBUG(dbgs() << " - Unsupported rotation.\n"); return nullptr; } @@ -832,7 +839,8 @@ // Check all instructions have internal uses for (const auto &Node : CompositeNodes) { if (!Node->hasAllInternalUses(AllInstructions)) { - LLVM_DEBUG(dbgs() << " - Invalid internal uses\n"); + LLVM_DEBUG(dbgs() << " - Invalid internal uses in " << Node.get() + << "\n"); return false; } } @@ -845,12 +853,14 @@ return Node->ReplacementNode; Value *Input0 = replaceNode(Node->Operands[0]); - Value *Input1 = replaceNode(Node->Operands[1]); + Value *Input1 = + Node->Operands.size() > 1 ? replaceNode(Node->Operands[1]) : nullptr; Value *Accumulator = Node->Operands.size() > 2 ? replaceNode(Node->Operands[2]) : nullptr; - assert(Input0->getType() == Input1->getType() && - "Node inputs need to be of the same type"); + if (Input1) + assert(Input0->getType() == Input1->getType() && + "Node inputs need to be of the same type"); Node->ReplacementNode = TL->createComplexDeinterleavingIR( Node->Real, Node->Operation, Node->Rotation, Input0, Input1, Accumulator);