[llvm-branch-commits] [llvm] d1b606f - [VE] Extract & insert vector element isel
Author: Simon Moll Date: 2021-01-08T11:46:59+01:00 New Revision: d1b606f897bee5f16ce9c459d3a79c8119018d9c URL: https://github.com/llvm/llvm-project/commit/d1b606f897bee5f16ce9c459d3a79c8119018d9c DIFF: https://github.com/llvm/llvm-project/commit/d1b606f897bee5f16ce9c459d3a79c8119018d9c.diff LOG: [VE] Extract & insert vector element isel Isel and tests for extract_vector_elt and insert_vector_elt. Reviewed By: kaz7 Differential Revision: https://reviews.llvm.org/D93687 Added: llvm/test/CodeGen/VE/Vector/extract_elt.ll llvm/test/CodeGen/VE/Vector/insert_elt.ll Modified: llvm/lib/Target/VE/VEISelLowering.cpp llvm/lib/Target/VE/VEISelLowering.h llvm/lib/Target/VE/VEInstrInfo.td llvm/lib/Target/VE/VEInstrPatternsVec.td Removed: diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp index 230ce42d46b3..a0d00ebca010 100644 --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -74,6 +74,8 @@ bool VETargetLowering::CanLowerReturn( static const MVT AllVectorVTs[] = {MVT::v256i32, MVT::v512i32, MVT::v256i64, MVT::v256f32, MVT::v512f32, MVT::v256f64}; +static const MVT AllPackedVTs[] = {MVT::v512i32, MVT::v512f32}; + void VETargetLowering::initRegisterClasses() { // Set up the register classes. addRegisterClass(MVT::i32, &VE::I32RegClass); @@ -292,6 +294,8 @@ void VETargetLowering::initSPUActions() { void VETargetLowering::initVPUActions() { for (MVT LegalVecVT : AllVectorVTs) { setOperationAction(ISD::BUILD_VECTOR, LegalVecVT, Custom); +setOperationAction(ISD::INSERT_VECTOR_ELT, LegalVecVT, Legal); +setOperationAction(ISD::EXTRACT_VECTOR_ELT, LegalVecVT, Legal); // Translate all vector instructions with legal element types to VVP_* // nodes. // TODO We will custom-widen into VVP_* nodes in the future. While we are @@ -301,6 +305,11 @@ void VETargetLowering::initVPUActions() { setOperationAction(ISD::ISD_NAME, LegalVecVT, Custom); #include "VVPNodes.def" } + + for (MVT LegalPackedVT : AllPackedVTs) { +setOperationAction(ISD::INSERT_VECTOR_ELT, LegalPackedVT, Custom); +setOperationAction(ISD::EXTRACT_VECTOR_ELT, LegalPackedVT, Custom); + } } SDValue @@ -1662,6 +1671,11 @@ SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::VAARG: return lowerVAARG(Op, DAG); + case ISD::INSERT_VECTOR_ELT: +return lowerINSERT_VECTOR_ELT(Op, DAG); + case ISD::EXTRACT_VECTOR_ELT: +return lowerEXTRACT_VECTOR_ELT(Op, DAG); + #define ADD_BINARY_VVP_OP(VVP_NAME, ISD_NAME) case ISD::ISD_NAME: #include "VVPNodes.def" return lowerToVVP(Op, DAG); @@ -2661,3 +2675,100 @@ SDValue VETargetLowering::lowerToVVP(SDValue Op, SelectionDAG &DAG) const { } llvm_unreachable("lowerToVVP called for unexpected SDNode."); } + +SDValue VETargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op, + SelectionDAG &DAG) const { + assert(Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT && "Unknown opcode!"); + MVT VT = Op.getOperand(0).getSimpleValueType(); + + // Special treatment for packed V64 types. + assert(VT == MVT::v512i32 || VT == MVT::v512f32); + // Example of codes: + // %packed_v = extractelt %vr, %idx / 2 + // %v = %packed_v >> (%idx % 2 * 32) + // %res = %v & 0x + + SDValue Vec = Op.getOperand(0); + SDValue Idx = Op.getOperand(1); + SDLoc DL(Op); + SDValue Result = Op; + if (0 /* Idx->isConstant() */) { +// TODO: optimized implementation using constant values + } else { +SDValue Const1 = DAG.getConstant(1, DL, MVT::i64); +SDValue HalfIdx = DAG.getNode(ISD::SRL, DL, MVT::i64, {Idx, Const1}); +SDValue PackedElt = +SDValue(DAG.getMachineNode(VE::LVSvr, DL, MVT::i64, {Vec, HalfIdx}), 0); +SDValue AndIdx = DAG.getNode(ISD::AND, DL, MVT::i64, {Idx, Const1}); +SDValue Shift = DAG.getNode(ISD::XOR, DL, MVT::i64, {AndIdx, Const1}); +SDValue Const5 = DAG.getConstant(5, DL, MVT::i64); +Shift = DAG.getNode(ISD::SHL, DL, MVT::i64, {Shift, Const5}); +PackedElt = DAG.getNode(ISD::SRL, DL, MVT::i64, {PackedElt, Shift}); +SDValue Mask = DAG.getConstant(0xL, DL, MVT::i64); +PackedElt = DAG.getNode(ISD::AND, DL, MVT::i64, {PackedElt, Mask}); +SDValue SubI32 = DAG.getTargetConstant(VE::sub_i32, DL, MVT::i32); +Result = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, +MVT::i32, PackedElt, SubI32), + 0); + +if (Op.getSimpleValueType() == MVT::f32) { + Result = DAG.getBitcast(MVT::f32, Result); +} else { + assert(Op.getSimpleValueType() == MVT::i32); +} + } + return Result; +} + +SDValue VETargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op, +
[llvm-branch-commits] [llvm] eeba70a - [VE] Expand single-element BUILD_VECTOR to INSERT_VECTOR_ELT
Author: Simon Moll Date: 2021-01-08T11:48:01+01:00 New Revision: eeba70a463c70c76868421e08c4036c70bfad994 URL: https://github.com/llvm/llvm-project/commit/eeba70a463c70c76868421e08c4036c70bfad994 DIFF: https://github.com/llvm/llvm-project/commit/eeba70a463c70c76868421e08c4036c70bfad994.diff LOG: [VE] Expand single-element BUILD_VECTOR to INSERT_VECTOR_ELT We do this mostly to be able to test the insert_vector_elt isel patterns. As long as we don't, most single element insertions show up as `BUILD_VECTOR` in the backend. Reviewed By: kaz7 Differential Revision: https://reviews.llvm.org/D93759 Added: llvm/test/CodeGen/VE/Vector/expand_single_elem_build_vec.ll Modified: llvm/lib/Target/VE/VEISelLowering.cpp llvm/test/CodeGen/VE/Vector/insert_elt.ll Removed: diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp index a0d00ebca010..a1b464091cd8 100644 --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -1602,6 +1602,32 @@ SDValue VETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, } } +static bool getUniqueInsertion(SDNode *N, unsigned &UniqueIdx) { + if (!isa(N)) +return false; + const auto *BVN = cast(N); + + // Find first non-undef insertion. + unsigned Idx; + for (Idx = 0; Idx < BVN->getNumOperands(); ++Idx) { +auto ElemV = BVN->getOperand(Idx); +if (!ElemV->isUndef()) + break; + } + // Catch the (hypothetical) all-undef case. + if (Idx == BVN->getNumOperands()) +return false; + // Remember insertion. + UniqueIdx = Idx++; + // Verify that all other insertions are undef. + for (; Idx < BVN->getNumOperands(); ++Idx) { +auto ElemV = BVN->getOperand(Idx); +if (!ElemV->isUndef()) + return false; + } + return true; +} + static SDValue getSplatValue(SDNode *N) { if (auto *BuildVec = dyn_cast(N)) { return BuildVec->getSplatValue(); @@ -1615,6 +1641,17 @@ SDValue VETargetLowering::lowerBUILD_VECTOR(SDValue Op, unsigned NumEls = Op.getValueType().getVectorNumElements(); MVT ElemVT = Op.getSimpleValueType().getVectorElementType(); + // If there is just one element, expand to INSERT_VECTOR_ELT. + unsigned UniqueIdx; + if (getUniqueInsertion(Op.getNode(), UniqueIdx)) { +SDValue AccuV = DAG.getUNDEF(Op.getValueType()); +auto ElemV = Op->getOperand(UniqueIdx); +SDValue IdxV = DAG.getConstant(UniqueIdx, DL, MVT::i64); +return DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, Op.getValueType(), AccuV, + ElemV, IdxV); + } + + // Else emit a broadcast. if (SDValue ScalarV = getSplatValue(Op.getNode())) { // lower to VEC_BROADCAST MVT LegalResVT = MVT::getVectorVT(ElemVT, 256); diff --git a/llvm/test/CodeGen/VE/Vector/expand_single_elem_build_vec.ll b/llvm/test/CodeGen/VE/Vector/expand_single_elem_build_vec.ll new file mode 100644 index ..42c455319246 --- /dev/null +++ b/llvm/test/CodeGen/VE/Vector/expand_single_elem_build_vec.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -march=ve -mattr=+vpu | FileCheck %s + +; Function Attrs: norecurse nounwind readnone +; Check that a single-element insertion is lowered to a insert_vector_elt node for isel. +define fastcc <256 x i32> @expand_single_elem_build_vec(i32 %x, i32 %y) { +; CHECK-LABEL: expand_single_elem_build_vec: +; CHECK: # %bb.0: +; CHECK-NEXT:and %s0, %s0, (32)0 +; CHECK-NEXT:lsv %v0(42), %s0 +; CHECK-NEXT:b.l.t (, %s10) + %r = insertelement <256 x i32> undef, i32 %x, i32 42 + ret <256 x i32> %r +} diff --git a/llvm/test/CodeGen/VE/Vector/insert_elt.ll b/llvm/test/CodeGen/VE/Vector/insert_elt.ll index 7ccd45690e9d..3004699e26d4 100644 --- a/llvm/test/CodeGen/VE/Vector/insert_elt.ll +++ b/llvm/test/CodeGen/VE/Vector/insert_elt.ll @@ -15,9 +15,7 @@ define fastcc <256 x i64> @insert_rr_v256i64(i32 signext %idx, i64 %s) { define fastcc <256 x i64> @insert_ri7_v256i64(i64 %s) { ; CHECK-LABEL: insert_ri7_v256i64: ; CHECK: # %bb.0: -; CHECK-NEXT:lea %s0, 256 -; CHECK-NEXT:lvl %s0 -; CHECK-NEXT:vbrd %v0, %s0 +; CHECK-NEXT:lsv %v0(127), %s0 ; CHECK-NEXT:b.l.t (, %s10) %ret = insertelement <256 x i64> undef, i64 %s, i32 127 ret <256 x i64> %ret @@ -26,9 +24,8 @@ define fastcc <256 x i64> @insert_ri7_v256i64(i64 %s) { define fastcc <256 x i64> @insert_ri8_v256i64(i64 %s) { ; CHECK-LABEL: insert_ri8_v256i64: ; CHECK: # %bb.0: -; CHECK-NEXT:lea %s0, 256 -; CHECK-NEXT:lvl %s0 -; CHECK-NEXT:vbrd %v0, %s0 +; CHECK-NEXT:lea %s1, 128 +; CHECK-NEXT:lsv %v0(%s1), %s0 ; CHECK-NEXT:b.l.t (, %s10) %ret = insertelement <256 x i64> undef, i64 %s, i32 128 ret <256 x i64> %ret @@ -37,9 +34,7 @@ define fastcc <256 x i64> @insert_ri8_v256i64(i64 %s) { define fastcc <512 x i64> @insert_ri_v512i64(i64 %s) { ; CHECK-LABEL: insert_ri_v512i64: ; CHECK: # %bb.0: -; CHECK-NEXT:lea %s0,
[llvm-branch-commits] [llvm] 611d3c6 - [VP] ISD helper functions [VE] isel for vp_add, vp_and
Author: Simon Moll Date: 2021-01-08T14:29:45+01:00 New Revision: 611d3c63f32d0d8a7f8e56d425849c610adbd806 URL: https://github.com/llvm/llvm-project/commit/611d3c63f32d0d8a7f8e56d425849c610adbd806 DIFF: https://github.com/llvm/llvm-project/commit/611d3c63f32d0d8a7f8e56d425849c610adbd806.diff LOG: [VP] ISD helper functions [VE] isel for vp_add, vp_and This implements vp_add, vp_and for the VE target by lowering them to the VVP_* layer. We also add helper functions for VP SDNodes (isVPSDNode, getVPMaskIdx, getVPExplicitVectorLengthIdx). Reviewed By: kaz7 Differential Revision: https://reviews.llvm.org/D93766 Added: Modified: llvm/include/llvm/CodeGen/ISDOpcodes.h llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/lib/Target/VE/VEISelLowering.cpp llvm/lib/Target/VE/VVPNodes.def llvm/test/CodeGen/VE/Vector/vp_add.ll llvm/test/CodeGen/VE/Vector/vp_and.ll Removed: diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index fd7b48b1b207..5b35266dcbaa 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -1196,6 +1196,15 @@ static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END + 500; /// For example ISD::AND for ISD::VECREDUCE_AND. NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode); +/// Whether this is a vector-predicated Opcode. +bool isVPOpcode(unsigned Opcode); + +/// The operand position of the vector mask. +Optional getVPMaskIdx(unsigned Opcode); + +/// The operand position of the explicit vector length parameter. +Optional getVPExplicitVectorLengthIdx(unsigned Opcode); + //======// /// MemIndexedMode enum - This enum defines the load / store indexed /// addressing modes. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 504e62087cb1..b13cb4f019a8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -377,6 +377,41 @@ ISD::NodeType ISD::getVecReduceBaseOpcode(unsigned VecReduceOpcode) { } } +bool ISD::isVPOpcode(unsigned Opcode) { + switch (Opcode) { + default: +return false; +#define BEGIN_REGISTER_VP_SDNODE(SDOPC, ...) \ + case ISD::SDOPC: \ +return true; +#include "llvm/IR/VPIntrinsics.def" + } +} + +/// The operand position of the vector mask. +Optional ISD::getVPMaskIdx(unsigned Opcode) { + switch (Opcode) { + default: +return None; +#define BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, TDNAME, MASKPOS, ...) \ + case ISD::SDOPC: \ +return MASKPOS; +#include "llvm/IR/VPIntrinsics.def" + } +} + +/// The operand position of the explicit vector length parameter. +Optional ISD::getVPExplicitVectorLengthIdx(unsigned Opcode) { + switch (Opcode) { + default: +return None; +#define BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, TDNAME, MASKPOS, EVLPOS) \ + case ISD::SDOPC: \ +return EVLPOS; +#include "llvm/IR/VPIntrinsics.def" + } +} + ISD::NodeType ISD::getExtForLoadExtType(bool IsFP, ISD::LoadExtType ExtType) { switch (ExtType) { case ISD::EXTLOAD: diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp index a1b464091cd8..d377f8e27cfd 100644 --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -301,6 +301,8 @@ void VETargetLowering::initVPUActions() { // TODO We will custom-widen into VVP_* nodes in the future. While we are // buildling the infrastructure for this, we only do this for legal vector // VTs. +#define HANDLE_VP_TO_VVP(VP_OPC, VVP_NAME) \ + setOperationAction(ISD::VP_OPC, LegalVecVT, Custom); #define ADD_VVP_OP(VVP_NAME, ISD_NAME) \ setOperationAction(ISD::ISD_NAME, LegalVecVT, Custom); #include "VVPNodes.def" @@ -1666,7 +1668,11 @@ SDValue VETargetLowering::lowerBUILD_VECTOR(SDValue Op, } SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { - switch (Op.getOpcode()) { + unsigned Opcode = Op.getOpcode(); + if (ISD::isVPOpcode(Opcode)) +return lowerToVVP(Op, DAG); + + switch (Opcode) { default: llvm_unreachable("Should not custom lower this!"); case ISD::ATOMIC_FENCE: @@ -2664,8 +2670,11 @@ bool VETargetLowering::hasAndNot(SDValue Y) const { } /// \returns the VVP_* SDNode opcode corresponsing to \p OC. -static Optional getVVPOpcode(unsigned OC) { - switch (OC) { +static Optional getVVPOpcode(unsigned Opcode) { + switch (Opcode) { +#define HANDLE_VP_TO_VVP(VPOPC, VVPNAME)
[llvm-branch-commits] [llvm] 93da221 - [VP][NFC] ISD::VP_Sub -> ISD::VP_SUB
Author: Simon Moll Date: 2020-12-21T11:43:07+01:00 New Revision: 93da221eaf7ab6ed8afa57f13e5155e6e2286337 URL: https://github.com/llvm/llvm-project/commit/93da221eaf7ab6ed8afa57f13e5155e6e2286337 DIFF: https://github.com/llvm/llvm-project/commit/93da221eaf7ab6ed8afa57f13e5155e6e2286337.diff LOG: [VP][NFC] ISD::VP_Sub -> ISD::VP_SUB Added: Modified: llvm/include/llvm/IR/VPIntrinsics.def Removed: diff --git a/llvm/include/llvm/IR/VPIntrinsics.def b/llvm/include/llvm/IR/VPIntrinsics.def index 3073866da4c9..981548c6dde9 100644 --- a/llvm/include/llvm/IR/VPIntrinsics.def +++ b/llvm/include/llvm/IR/VPIntrinsics.def @@ -131,7 +131,7 @@ HELPER_REGISTER_BINARY_INT_VP(vp_shl, VP_SHL, Shl) HELPER_REGISTER_BINARY_INT_VP(vp_srem, VP_SREM, SRem) // llvm.vp.sub(x,y,mask,vlen) -HELPER_REGISTER_BINARY_INT_VP(vp_sub, VP_Sub, Sub) +HELPER_REGISTER_BINARY_INT_VP(vp_sub, VP_SUB, Sub) // llvm.vp.udiv(x,y,mask,vlen) HELPER_REGISTER_BINARY_INT_VP(vp_udiv, VP_UDIV, UDiv) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] c3acda0 - [VE] Vector 'and' isel and tests
Author: Simon Moll Date: 2020-12-23T13:29:29+01:00 New Revision: c3acda0798f9b10ac3187ad941bbd8af82fb84a1 URL: https://github.com/llvm/llvm-project/commit/c3acda0798f9b10ac3187ad941bbd8af82fb84a1 DIFF: https://github.com/llvm/llvm-project/commit/c3acda0798f9b10ac3187ad941bbd8af82fb84a1.diff LOG: [VE] Vector 'and' isel and tests Reviewed By: kaz7 Differential Revision: https://reviews.llvm.org/D93709 Added: llvm/test/CodeGen/VE/Vector/vec_and.ll Modified: llvm/lib/Target/VE/VVPInstrInfo.td llvm/lib/Target/VE/VVPInstrPatternsVec.td llvm/lib/Target/VE/VVPNodes.def Removed: diff --git a/llvm/lib/Target/VE/VVPInstrInfo.td b/llvm/lib/Target/VE/VVPInstrInfo.td index 81fbfe03b48f..2c88d5099a7b 100644 --- a/llvm/lib/Target/VE/VVPInstrInfo.td +++ b/llvm/lib/Target/VE/VVPInstrInfo.td @@ -40,4 +40,7 @@ class vvp_commutative : def vvp_add: SDNode<"VEISD::VVP_ADD", SDTIntBinOpVVP>; def c_vvp_add : vvp_commutative; +def vvp_and: SDNode<"VEISD::VVP_AND", SDTIntBinOpVVP>; +def c_vvp_and : vvp_commutative; + // } Binary Operators diff --git a/llvm/lib/Target/VE/VVPInstrPatternsVec.td b/llvm/lib/Target/VE/VVPInstrPatternsVec.td index 2345173314a4..7003fb387670 100644 --- a/llvm/lib/Target/VE/VVPInstrPatternsVec.td +++ b/llvm/lib/Target/VE/VVPInstrPatternsVec.td @@ -66,3 +66,6 @@ multiclass VectorBinaryArith_ShortLong< defm : VectorBinaryArith_ShortLong; +defm : VectorBinaryArith_ShortLong; diff --git a/llvm/lib/Target/VE/VVPNodes.def b/llvm/lib/Target/VE/VVPNodes.def index 4319b332388e..1f9cbd790235 100644 --- a/llvm/lib/Target/VE/VVPNodes.def +++ b/llvm/lib/Target/VE/VVPNodes.def @@ -27,6 +27,7 @@ // Integer arithmetic. ADD_BINARY_VVP_OP(VVP_ADD,ADD) +ADD_BINARY_VVP_OP(VVP_AND,AND) #undef ADD_BINARY_VVP_OP #undef ADD_VVP_OP diff --git a/llvm/test/CodeGen/VE/Vector/vec_and.ll b/llvm/test/CodeGen/VE/Vector/vec_and.ll new file mode 100644 index ..8597e1aa511e --- /dev/null +++ b/llvm/test/CodeGen/VE/Vector/vec_and.ll @@ -0,0 +1,132 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=ve -mattr=+vpu | FileCheck %s + +; <256 x i32> + +; Function Attrs: nounwind +define fastcc <256 x i32> @and_vv_v256i32(<256 x i32> %x, <256 x i32> %y) { +; CHECK-LABEL: and_vv_v256i32: +; CHECK: # %bb.0: +; CHECK-NEXT:lea %s0, 256 +; CHECK-NEXT:lvl %s0 +; CHECK-NEXT:pvand.lo %v0, %v0, %v1 +; CHECK-NEXT:b.l.t (, %s10) + %z = and <256 x i32> %x, %y + ret <256 x i32> %z +} + +; Function Attrs: nounwind +define fastcc <256 x i32> @and_sv_v256i32(i32 %x, <256 x i32> %y) { +; CHECK-LABEL: and_sv_v256i32: +; CHECK: # %bb.0: +; CHECK-NEXT:and %s0, %s0, (32)0 +; CHECK-NEXT:lea %s1, 256 +; CHECK-NEXT:lvl %s1 +; CHECK-NEXT:pvand.lo %v0, %s0, %v0 +; CHECK-NEXT:b.l.t (, %s10) + %xins = insertelement <256 x i32> undef, i32 %x, i32 0 + %vx = shufflevector <256 x i32> %xins, <256 x i32> undef, <256 x i32> zeroinitializer + %z = and <256 x i32> %vx, %y + ret <256 x i32> %z +} + +; Function Attrs: nounwind +define fastcc <256 x i32> @and_vs_v256i32(<256 x i32> %x, i32 %y) { +; CHECK-LABEL: and_vs_v256i32: +; CHECK: # %bb.0: +; CHECK-NEXT:and %s0, %s0, (32)0 +; CHECK-NEXT:lea %s1, 256 +; CHECK-NEXT:lvl %s1 +; CHECK-NEXT:pvand.lo %v0, %s0, %v0 +; CHECK-NEXT:b.l.t (, %s10) + %yins = insertelement <256 x i32> undef, i32 %y, i32 0 + %vy = shufflevector <256 x i32> %yins, <256 x i32> undef, <256 x i32> zeroinitializer + %z = and <256 x i32> %x, %vy + ret <256 x i32> %z +} + + + +; <256 x i64> + +; Function Attrs: nounwind +define fastcc <256 x i64> @and_vv_v256i64(<256 x i64> %x, <256 x i64> %y) { +; CHECK-LABEL: and_vv_v256i64: +; CHECK: # %bb.0: +; CHECK-NEXT:lea %s0, 256 +; CHECK-NEXT:lvl %s0 +; CHECK-NEXT:vand %v0, %v0, %v1 +; CHECK-NEXT:b.l.t (, %s10) + %z = and <256 x i64> %x, %y + ret <256 x i64> %z +} + +; Function Attrs: nounwind +define fastcc <256 x i64> @and_sv_v256i64(i64 %x, <256 x i64> %y) { +; CHECK-LABEL: and_sv_v256i64: +; CHECK: # %bb.0: +; CHECK-NEXT:lea %s1, 256 +; CHECK-NEXT:lvl %s1 +; CHECK-NEXT:vand %v0, %s0, %v0 +; CHECK-NEXT:b.l.t (, %s10) + %xins = insertelement <256 x i64> undef, i64 %x, i32 0 + %vx = shufflevector <256 x i64> %xins, <256 x i64> undef, <256 x i32> zeroinitializer + %z = and <256 x i64> %vx, %y + ret <256 x i64> %z +} + +; Function Attrs: nounwind +define fastcc <256 x i64> @and_vs_v256i64(<256 x i64> %x, i64 %y) { +; CHECK-LABEL: and_vs_v256i64: +; CHECK: # %bb.0: +; CHECK-NEXT:lea %s1, 256 +; CHECK-NEXT:lvl %s1 +; CHECK-NEXT:vand %v0, %s0, %v0 +; CHECK-NEXT:b.l.t (, %s10) + %yins = insertelement <256 x i64> undef, i64 %y, i32 0 + %vy = shufflevector <256 x i64> %yins, <256 x i64> undef, <256 x i32> zeroinitializer + %z = and <256 x i64> %x, %vy + r
[llvm-branch-commits] [llvm] acaa6e4 - [NFC] Uniquify 'const' in TargetTransformInfoImpl.h
Author: Simon Moll Date: 2020-12-23T14:21:41+01:00 New Revision: acaa6e4260cb5b2aa88f465eafea320d5f3f249c URL: https://github.com/llvm/llvm-project/commit/acaa6e4260cb5b2aa88f465eafea320d5f3f249c DIFF: https://github.com/llvm/llvm-project/commit/acaa6e4260cb5b2aa88f465eafea320d5f3f249c.diff LOG: [NFC] Uniquify 'const' in TargetTransformInfoImpl.h Some member functions of class TargetTransformInfoImplBase in TargetTransformInfoImpl.h are marked const while others are not. Yet all of the should be marked const since they are just providing default TTI values. This patch fixes the inconsistency. Authored-by: Jinzheng Tu Reviewed By: simoll Differential revision: https://reviews.llvm.org/D93573 Added: Modified: llvm/include/llvm/Analysis/TargetTransformInfoImpl.h Removed: diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h index 6415e7bfe7c3..620bfb885b54 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -46,7 +46,7 @@ class TargetTransformInfoImplBase { int getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef Operands, - TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) { + TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) const { // In the basic model, we just assume that all-constant GEPs will be folded // into their uses via addressing modes. for (unsigned Idx = 0, Size = Operands.size(); Idx != Size; ++Idx) @@ -59,28 +59,30 @@ class TargetTransformInfoImplBase { unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, unsigned &JTSize, ProfileSummaryInfo *PSI, -BlockFrequencyInfo *BFI) { +BlockFrequencyInfo *BFI) const { (void)PSI; (void)BFI; JTSize = 0; return SI.getNumCases(); } - unsigned getInliningThresholdMultiplier() { return 1; } + unsigned getInliningThresholdMultiplier() const { return 1; } - int getInlinerVectorBonusPercent() { return 150; } + int getInlinerVectorBonusPercent() const { return 150; } - unsigned getMemcpyCost(const Instruction *I) { return TTI::TCC_Expensive; } + unsigned getMemcpyCost(const Instruction *I) const { +return TTI::TCC_Expensive; + } - bool hasBranchDivergence() { return false; } + bool hasBranchDivergence() const { return false; } - bool useGPUDivergenceAnalysis() { return false; } + bool useGPUDivergenceAnalysis() const { return false; } - bool isSourceOfDivergence(const Value *V) { return false; } + bool isSourceOfDivergence(const Value *V) const { return false; } - bool isAlwaysUniform(const Value *V) { return false; } + bool isAlwaysUniform(const Value *V) const { return false; } - unsigned getFlatAddressSpace() { return -1; } + unsigned getFlatAddressSpace() const { return -1; } bool collectFlatAddressOperands(SmallVectorImpl &OpIndexes, Intrinsic::ID IID) const { @@ -96,7 +98,7 @@ class TargetTransformInfoImplBase { return nullptr; } - bool isLoweredToCall(const Function *F) { + bool isLoweredToCall(const Function *F) const { assert(F && "A concrete function must be provided to this routine."); // FIXME: These should almost certainly not be handled here, and instead @@ -134,7 +136,7 @@ class TargetTransformInfoImplBase { bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE, AssumptionCache &AC, TargetLibraryInfo *LibInfo, -HardwareLoopInfo &HWLoopInfo) { +HardwareLoopInfo &HWLoopInfo) const { return false; } @@ -170,39 +172,39 @@ class TargetTransformInfoImplBase { } void getUnrollingPreferences(Loop *, ScalarEvolution &, - TTI::UnrollingPreferences &) {} + TTI::UnrollingPreferences &) const {} void getPeelingPreferences(Loop *, ScalarEvolution &, - TTI::PeelingPreferences &) {} + TTI::PeelingPreferences &) const {} - bool isLegalAddImmediate(int64_t Imm) { return false; } + bool isLegalAddImmediate(int64_t Imm) const { return false; } - bool isLegalICmpImmediate(int64_t Imm) { return false; } + bool isLegalICmpImmediate(int64_t Imm) const { return false; } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, - Instruction *I = nullptr) { + Instruction *I = nullptr) const { // Guess that on
[llvm-branch-commits] [llvm] b955c7e - [VE] VE Vector Predicated SDNode, vector add isel and tests
Author: Simon Moll Date: 2020-11-23T17:17:07+01:00 New Revision: b955c7e63001068f7829827c327dc96ca9a05e8c URL: https://github.com/llvm/llvm-project/commit/b955c7e63001068f7829827c327dc96ca9a05e8c DIFF: https://github.com/llvm/llvm-project/commit/b955c7e63001068f7829827c327dc96ca9a05e8c.diff LOG: [VE] VE Vector Predicated SDNode, vector add isel and tests VE Vector Predicated (VVP) SDNodes form an intermediate layer between VE vector instructions and the initial SDNodes. We introduce 'vvp_add' with isel and tests as the first of these VVP nodes. VVP nodes have a mask and explicit vector length operand, which we will make proper use of later. Reviewed By: kaz7 Differential Revision: https://reviews.llvm.org/D91802 Added: llvm/lib/Target/VE/VVPInstrInfo.td llvm/lib/Target/VE/VVPInstrPatternsVec.td llvm/lib/Target/VE/VVPNodes.def llvm/test/CodeGen/VE/Vector/vec_add.ll Modified: llvm/lib/Target/VE/VEISelLowering.cpp llvm/lib/Target/VE/VEISelLowering.h llvm/lib/Target/VE/VEInstrInfo.td llvm/lib/Target/VE/VEInstrPatternsVec.td Removed: diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp index 30b6aa96edec..cc7f5f6800ec 100644 --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -254,8 +254,17 @@ void VETargetLowering::initSPUActions() { } void VETargetLowering::initVPUActions() { - for (MVT LegalVecVT : AllVectorVTs) + for (MVT LegalVecVT : AllVectorVTs) { setOperationAction(ISD::BUILD_VECTOR, LegalVecVT, Custom); +// Translate all vector instructions with legal element types to VVP_* +// nodes. +// TODO We will custom-widen into VVP_* nodes in the future. While we are +// buildling the infrastructure for this, we only do this for legal vector +// VTs. +#define ADD_VVP_OP(VVP_NAME, ISD_NAME) \ + setOperationAction(ISD::ISD_NAME, LegalVecVT, Custom); +#include "VVPNodes.def" + } } SDValue @@ -846,6 +855,10 @@ const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const { TARGET_NODE_CASE(VEC_BROADCAST) TARGET_NODE_CASE(RET_FLAG) TARGET_NODE_CASE(GLOBAL_BASE_REG) + +// Register the VVP_* SDNodes. +#define ADD_VVP_OP(VVP_NAME, ...) TARGET_NODE_CASE(VVP_NAME) +#include "VVPNodes.def" } #undef TARGET_NODE_CASE return nullptr; @@ -1403,6 +1416,10 @@ SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { return lowerVASTART(Op, DAG); case ISD::VAARG: return lowerVAARG(Op, DAG); + +#define ADD_BINARY_VVP_OP(VVP_NAME, ISD_NAME) case ISD::ISD_NAME: +#include "VVPNodes.def" +return lowerToVVP(Op, DAG); } } /// } Custom Lower @@ -1665,3 +1682,53 @@ bool VETargetLowering::hasAndNot(SDValue Y) const { // It's ok for generic registers. return true; } + +/// \returns the VVP_* SDNode opcode corresponsing to \p OC. +static Optional getVVPOpcode(unsigned OC) { + switch (OC) { +#define ADD_VVP_OP(VVPNAME, SDNAME) \ + case VEISD::VVPNAME: \ + case ISD::SDNAME: \ +return VEISD::VVPNAME; +#include "VVPNodes.def" + } + return None; +} + +SDValue VETargetLowering::lowerToVVP(SDValue Op, SelectionDAG &DAG) const { + // Can we represent this as a VVP node. + auto OCOpt = getVVPOpcode(Op->getOpcode()); + if (!OCOpt.hasValue()) +return SDValue(); + unsigned VVPOC = OCOpt.getValue(); + + // The representative and legalized vector type of this operation. + EVT OpVecVT = Op.getValueType(); + EVT LegalVecVT = getTypeToTransformTo(*DAG.getContext(), OpVecVT); + + // Materialize the VL parameter. + SDLoc DL(Op); + SDValue AVL = DAG.getConstant(OpVecVT.getVectorNumElements(), DL, MVT::i32); + MVT MaskVT = MVT::v256i1; + SDValue ConstTrue = DAG.getConstant(1, DL, MVT::i32); + SDValue Mask = DAG.getNode(VEISD::VEC_BROADCAST, DL, MaskVT, + ConstTrue); // emit a VEISD::VEC_BROADCAST here. + + // Categories we are interested in. + bool IsBinaryOp = false; + + switch (VVPOC) { +#define ADD_BINARY_VVP_OP(VVPNAME, ...) \ + case VEISD::VVPNAME: \ +IsBinaryOp = true; \ +break; +#include "VVPNodes.def" + } + + if (IsBinaryOp) { +assert(LegalVecVT.isSimple()); +return DAG.getNode(VVPOC, DL, LegalVecVT, Op->getOperand(0), + Op->getOperand(1), Mask, AVL); + } + llvm_unreachable("lowerToVVP called for unexpected SDNode."); +} diff --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h index e12bef882d8a..9924db647f46 100644 --- a/llvm/lib/Target/VE/
[llvm-branch-commits] [llvm] 3ffbc79 - [VP] Build VP SDNodes
Author: Simon Moll Date: 2020-12-09T11:36:51+01:00 New Revision: 3ffbc7935718bd792f2947e90dfcf61e8cc5fb97 URL: https://github.com/llvm/llvm-project/commit/3ffbc7935718bd792f2947e90dfcf61e8cc5fb97 DIFF: https://github.com/llvm/llvm-project/commit/3ffbc7935718bd792f2947e90dfcf61e8cc5fb97.diff LOG: [VP] Build VP SDNodes Translate VP intrinsics to VP_* SDNodes. The tests check whether a matching vp_* SDNode is emitted. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D91441 Added: llvm/test/CodeGen/VE/Vector/vp_add.ll llvm/test/CodeGen/VE/Vector/vp_and.ll llvm/test/CodeGen/VE/Vector/vp_ashr.ll llvm/test/CodeGen/VE/Vector/vp_lshr.ll llvm/test/CodeGen/VE/Vector/vp_mul.ll llvm/test/CodeGen/VE/Vector/vp_or.ll llvm/test/CodeGen/VE/Vector/vp_sdiv.ll llvm/test/CodeGen/VE/Vector/vp_shl.ll llvm/test/CodeGen/VE/Vector/vp_srem.ll llvm/test/CodeGen/VE/Vector/vp_sub.ll llvm/test/CodeGen/VE/Vector/vp_udiv.ll llvm/test/CodeGen/VE/Vector/vp_urem.ll llvm/test/CodeGen/VE/Vector/vp_xor.ll Modified: llvm/include/llvm/CodeGen/ISDOpcodes.h llvm/include/llvm/IR/VPIntrinsics.def llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp llvm/lib/IR/IntrinsicInst.cpp Removed: diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index adbcb7cc75b0..008fea45c6f4 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -1157,6 +1157,10 @@ enum NodeType { VECREDUCE_UMAX, VECREDUCE_UMIN, +// Vector Predication +#define BEGIN_REGISTER_VP_SDNODE(VPSDID, ...) VPSDID, +#include "llvm/IR/VPIntrinsics.def" + /// BUILTIN_OP_END - This must be the last enum value in this list. /// The target-specific pre-isel opcode values start here. BUILTIN_OP_END diff --git a/llvm/include/llvm/IR/VPIntrinsics.def b/llvm/include/llvm/IR/VPIntrinsics.def index 68e7ea0c8069..3073866da4c9 100644 --- a/llvm/include/llvm/IR/VPIntrinsics.def +++ b/llvm/include/llvm/IR/VPIntrinsics.def @@ -17,68 +17,140 @@ // Provide definitions of macros so that users of this file do not have to // define everything to use it... // -#ifndef REGISTER_VP_INTRINSIC -#define REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) +// Register a VP intrinsic and begin its property scope. +// All VP intrinsic scopes are top level, ie it is illegal to place a +// BEGIN_REGISTER_VP_INTRINSIC within a VP intrinsic scope. +// \p VPID The VP intrinsic id. +// \p MASKPOS The mask operand position. +// \p EVLPOS The explicit vector length operand position. +#ifndef BEGIN_REGISTER_VP_INTRINSIC +#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, EVLPOS) #endif -// Map this VP intrinsic to its functional Opcode +// End the property scope of a VP intrinsic. +#ifndef END_REGISTER_VP_INTRINSIC +#define END_REGISTER_VP_INTRINSIC(VPID) +#endif + +// Register a new VP SDNode and begin its property scope. +// When the SDNode scope is nested within a VP intrinsic scope, it is implicitly registered as the canonical SDNode for this VP intrinsic. +// There is one VP intrinsic that maps directly to one SDNode that goes by the +// same name. Since the operands are also the same, we open the property +// scopes for both the VPIntrinsic and the SDNode at once. +// \p SDOPC The SelectionDAG Node id (eg VP_ADD). +// \p LEGALPOS The operand position of the SDNode that is used for legalizing +// this SDNode. This can be `-1`, in which case the return type of +// the SDNode is used. +// \p TDNAME The name of the TableGen definition of this SDNode. +// \p MASKPOS The mask operand position. +// \p EVLPOS The explicit vector length operand position. +#ifndef BEGIN_REGISTER_VP_SDNODE +#define BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, TDNAME, MASKPOS, EVLPOS) +#endif + +// End the property scope of a new VP SDNode. +#ifndef END_REGISTER_VP_SDNODE +#define END_REGISTER_VP_SDNODE(SDOPC) +#endif + +// Helper macros for the common "1:1 - Intrinsic : SDNode" case. +// +// There is one VP intrinsic that maps directly to one SDNode that goes by the +// same name. Since the operands are also the same, we open the property +// scopes for both the VPIntrinsic and the SDNode at once. +// +// \p INTRIN The canonical name (eg `vp_add`, which at the same time is the +// name of the intrinsic and the TableGen def of the SDNode). +// \p MASKPOS The mask operand position. +// \p EVLPOS The explicit vector length operand position. +// \p SDOPCThe SelectionDAG Node id (eg VP_ADD). +// \p LEGALPOS The operand position of the SDNode that is used for legalizing +// this SDNode. This can be `-1`, in which case the return type of +// the SDNode is used. +#define BE