|
| 1 | +//===-- VVPISelLowering.cpp - VE DAG Lowering Implementation --------------===// |
| 2 | +// |
| 3 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | +// See https://llvm.org/LICENSE.txt for license information. |
| 5 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | +// |
| 7 | +//===----------------------------------------------------------------------===// |
| 8 | +// |
| 9 | +// This file implements the lowering and legalization of vector instructions to |
| 10 | +// VVP_*layer SDNodes. |
| 11 | +// |
| 12 | +//===----------------------------------------------------------------------===// |
| 13 | + |
| 14 | +#include "VECustomDAG.h" |
| 15 | +#include "VEISelLowering.h" |
| 16 | + |
| 17 | +using namespace llvm; |
| 18 | + |
| 19 | +#define DEBUG_TYPE "ve-lower" |
| 20 | + |
| 21 | +SDValue VETargetLowering::legalizeInternalVectorOp(SDValue Op, |
| 22 | + SelectionDAG &DAG) const { |
| 23 | + VECustomDAG CDAG(DAG, Op); |
| 24 | + // TODO: Implement odd/even splitting. |
| 25 | + return legalizePackedAVL(Op, CDAG); |
| 26 | +} |
| 27 | + |
| 28 | +SDValue VETargetLowering::legalizePackedAVL(SDValue Op, |
| 29 | + VECustomDAG &CDAG) const { |
| 30 | + LLVM_DEBUG(dbgs() << "::legalizePackedAVL\n";); |
| 31 | + // Only required for VEC and VVP ops. |
| 32 | + if (!isVVPOrVEC(Op->getOpcode())) |
| 33 | + return Op; |
| 34 | + |
| 35 | + // Operation already has a legal AVL. |
| 36 | + auto AVL = getNodeAVL(Op); |
| 37 | + if (isLegalAVL(AVL)) |
| 38 | + return Op; |
| 39 | + |
| 40 | + // Half and round up EVL for 32bit element types. |
| 41 | + SDValue LegalAVL = AVL; |
| 42 | + if (isPackedVectorType(Op.getValueType())) { |
| 43 | + assert(maySafelyIgnoreMask(Op) && |
| 44 | + "TODO Shift predication from EVL into Mask"); |
| 45 | + |
| 46 | + if (auto *ConstAVL = dyn_cast<ConstantSDNode>(AVL)) { |
| 47 | + LegalAVL = CDAG.getConstant((ConstAVL->getZExtValue() + 1) / 2, MVT::i32); |
| 48 | + } else { |
| 49 | + auto ConstOne = CDAG.getConstant(1, MVT::i32); |
| 50 | + auto PlusOne = CDAG.getNode(ISD::ADD, MVT::i32, {AVL, ConstOne}); |
| 51 | + LegalAVL = CDAG.getNode(ISD::SRL, MVT::i32, {PlusOne, ConstOne}); |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + SDValue AnnotatedLegalAVL = CDAG.annotateLegalAVL(LegalAVL); |
| 56 | + |
| 57 | + // Copy the operand list. |
| 58 | + int NumOp = Op->getNumOperands(); |
| 59 | + auto AVLPos = getAVLPos(Op->getOpcode()); |
| 60 | + std::vector<SDValue> FixedOperands; |
| 61 | + for (int i = 0; i < NumOp; ++i) { |
| 62 | + if (AVLPos && (i == *AVLPos)) { |
| 63 | + FixedOperands.push_back(AnnotatedLegalAVL); |
| 64 | + continue; |
| 65 | + } |
| 66 | + FixedOperands.push_back(Op->getOperand(i)); |
| 67 | + } |
| 68 | + |
| 69 | + // Clone the operation with fixed operands. |
| 70 | + auto Flags = Op->getFlags(); |
| 71 | + SDValue NewN = |
| 72 | + CDAG.getNode(Op->getOpcode(), Op->getVTList(), FixedOperands, Flags); |
| 73 | + return NewN; |
| 74 | +} |
0 commit comments