[llvm-branch-commits] [llvm] d1b606f - [VE] Extract & insert vector element isel

2021-01-08 Thread Simon Moll via llvm-branch-commits

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

2021-01-08 Thread Simon Moll via llvm-branch-commits

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

2021-01-08 Thread Simon Moll via llvm-branch-commits

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

2020-12-21 Thread Simon Moll via llvm-branch-commits

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

2020-12-23 Thread Simon Moll via llvm-branch-commits

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

2020-12-23 Thread Simon Moll via llvm-branch-commits

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

2020-11-23 Thread Simon Moll via llvm-branch-commits

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

2020-12-09 Thread Simon Moll via llvm-branch-commits

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