[llvm] 820df6e - [Hexagon] Lower vector predicate store

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 24 13:43:39 PST 2020


Author: Ikhlas Ajbar
Date: 2020-02-24T15:43:04-06:00
New Revision: 820df6e679143786d41808b7bfc9ad023ed217d2

URL: https://github.com/llvm/llvm-project/commit/820df6e679143786d41808b7bfc9ad023ed217d2
DIFF: https://github.com/llvm/llvm-project/commit/820df6e679143786d41808b7bfc9ad023ed217d2.diff

LOG: [Hexagon] Lower vector predicate store

This patch lowers store of vector predicate of type v128i1.

Added: 
    llvm/test/CodeGen/Hexagon/store-vector-pred.ll

Modified: 
    llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
    llvm/lib/Target/Hexagon/HexagonISelLowering.h
    llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index ee50ff7ef3dd..f3967573c70e 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1681,6 +1681,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::STORE, VT, Custom);
   }
 
+  setOperationAction(ISD::STORE, MVT::v128i1, Custom);
+
   for (MVT VT : {MVT::v2i16, MVT::v4i8, MVT::v8i8, MVT::v2i32, MVT::v4i16,
                  MVT::v2i32}) {
     setCondCodeAction(ISD::SETNE,  VT, Expand);

diff  --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index b411a03bd502..7239c1dc71d2 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -456,6 +456,8 @@ namespace HexagonISD {
     SDValue LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerHvxShift(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerHvxIntrinsic(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerHvxStore(SDValue Op, SelectionDAG &DAG) const;
+    SDValue HvxVecPredBitcastComputation(SDValue Op, SelectionDAG &DAG) const;
 
     SDValue SplitHvxPairOp(SDValue Op, SelectionDAG &DAG) const;
     SDValue SplitHvxMemOp(SDValue Op, SelectionDAG &DAG) const;

diff  --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
index 7f99c1588b8f..2b5257e47712 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
@@ -1437,17 +1437,12 @@ HexagonTargetLowering::LowerHvxMulh(SDValue Op, SelectionDAG &DAG) const {
   return T7;
 }
 
-SDValue HexagonTargetLowering::LowerHvxBitcast(SDValue Op,
-                                               SelectionDAG &DAG) const {
-  auto *N = Op.getNode();
-  EVT VT = N->getValueType(0);
+// This function does the computation needed to bitcast a vector of predicate
+// register to a vector of integers.
+SDValue
+HexagonTargetLowering::HvxVecPredBitcastComputation(SDValue Op,
+                                                    SelectionDAG &DAG) const {
   const SDLoc &dl(Op);
-  SDValue Q0 = N->getOperand(0);
-  EVT VTOp = Q0.getNode()->getValueType(0);
-  if (!(VT == MVT::i64 || VT == MVT::i32) ||
-      !(VTOp == MVT::v64i1 || VTOp == MVT::v32i1)) {
-    return Op;
-  }
   MVT VecTy;
   int Length;
   if (Subtarget.useHVX64BOps()) {
@@ -1463,7 +1458,7 @@ SDValue HexagonTargetLowering::LowerHvxBitcast(SDValue Op,
   SDValue InstrC8421 = getInstr(Hexagon::A2_tfrsi, dl, MVT::i32, C8421, DAG);
   // v0 = vand(q0,r0)
   SDValue Vand =
-      getInstr(Hexagon::V6_vandqrt, dl, VecTy, {Q0, InstrC8421}, DAG);
+      getInstr(Hexagon::V6_vandqrt, dl, VecTy, {Op, InstrC8421}, DAG);
 
   // Or the bytes in each word into a single byte: that will form packs
   // of 4 bits of the output.
@@ -1548,6 +1543,22 @@ SDValue HexagonTargetLowering::LowerHvxBitcast(SDValue Op,
   SDValue Vror2 = getInstr(Hexagon::V6_vror, dl, VecTy, {Vor3, InstrC4}, DAG);
   // v0 = vor(v0,v1)
   SDValue Vor4 = getInstr(Hexagon::V6_vor, dl, VecTy, {Vor3, Vror2}, DAG);
+  return Vor4;
+}
+
+SDValue HexagonTargetLowering::LowerHvxBitcast(SDValue Op,
+                                               SelectionDAG &DAG) const {
+  auto *N = Op.getNode();
+  EVT VT = N->getValueType(0);
+  const SDLoc &dl(Op);
+  SDValue Q0 = N->getOperand(0);
+  EVT VTOp = Q0.getNode()->getValueType(0);
+  if (!(VT == MVT::i64 || VT == MVT::i32) ||
+      !(VTOp == MVT::v64i1 || VTOp == MVT::v32i1))
+    return Op;
+
+  SDValue Vor4 = HvxVecPredBitcastComputation(Q0, DAG);
+
   // The output is v.w[8]:v.w[0]
   // r3 = #0
   SDValue C0 = DAG.getTargetConstant(0, dl, MVT::i32);
@@ -1567,6 +1578,53 @@ SDValue HexagonTargetLowering::LowerHvxBitcast(SDValue Op,
   return Res;
 }
 
+SDValue HexagonTargetLowering::LowerHvxStore(SDValue Op,
+                                             SelectionDAG &DAG) const {
+  auto *N = Op.getNode();
+  const SDLoc &dl(Op);
+  SDValue Q0 = N->getOperand(1);
+  EVT VTOp = Q0.getNode()->getValueType(0);
+  if (Op.getOpcode() != ISD::STORE || VTOp != MVT::v128i1)
+    return Op;
+  SDValue Vor4 = HvxVecPredBitcastComputation(Q0, DAG);
+  // The output is v.w[8]:v.w[0]
+  // r3 = #0
+  SDValue C0 = DAG.getTargetConstant(0, dl, MVT::i32);
+  SDValue InstrC0 = getInstr(Hexagon::A2_tfrsi, dl, MVT::i32, C0, DAG);
+  // r0 = vextract(v0,r3)
+  SDValue Vextract0 =
+      getInstr(Hexagon::V6_extractw, dl, MVT::i32, {Vor4, InstrC0}, DAG);
+  // r3 = #32
+  SDValue C32 = DAG.getTargetConstant(32, dl, MVT::i32);
+  SDValue InstrC32 = getInstr(Hexagon::A2_tfrsi, dl, MVT::i32, C32, DAG);
+  // r1 = vextract(v0,r3)
+  SDValue Vextract1 =
+      getInstr(Hexagon::V6_extractw, dl, MVT::i32, {Vor4, InstrC32}, DAG);
+  SDValue Combine0 =
+      getInstr(Hexagon::A2_combinew, dl, MVT::i64, {Vextract1, Vextract0}, DAG);
+  // r3 = #64
+  SDValue C64 = DAG.getTargetConstant(64, dl, MVT::i32);
+  SDValue InstrC64 = getInstr(Hexagon::A2_tfrsi, dl, MVT::i32, C64, DAG);
+  // r0 = vextract(v0,r3)
+  SDValue Vextract2 =
+      getInstr(Hexagon::V6_extractw, dl, MVT::i32, {Vor4, InstrC64}, DAG);
+  // r3 = #96
+  SDValue C96 = DAG.getTargetConstant(96, dl, MVT::i32);
+  SDValue InstrC96 = getInstr(Hexagon::A2_tfrsi, dl, MVT::i32, C96, DAG);
+  // r1 = vextract(v0,r3)
+  SDValue Vextract3 =
+      getInstr(Hexagon::V6_extractw, dl, MVT::i32, {Vor4, InstrC96}, DAG);
+  SDValue Combine1 =
+      getInstr(Hexagon::A2_combinew, dl, MVT::i64, {Vextract3, Vextract2}, DAG);
+  StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
+  SDValue C8 = DAG.getTargetConstant(8, dl, MVT::i32);
+  const SDValue Ops1[] = {ST->getBasePtr(), C8, Combine1, ST->getChain()};
+  SDValue Store1 = getInstr(Hexagon::S2_storerd_io, dl, MVT::Other, Ops1, DAG);
+  const SDValue Ops0[] = {ST->getBasePtr(), C0, Combine0, Store1};
+  SDValue Store0 = getInstr(Hexagon::S2_storerd_io, dl, MVT::Other, Ops0, DAG);
+  return Store0;
+}
+
 SDValue
 HexagonTargetLowering::LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const {
   // Sign- and zero-extends are legal.
@@ -1740,6 +1798,7 @@ HexagonTargetLowering::LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const {
     case ISD::SETCC:
     case ISD::INTRINSIC_VOID:          return Op;
     case ISD::INTRINSIC_WO_CHAIN:      return LowerHvxIntrinsic(Op, DAG);
+    case ISD::STORE:                   return LowerHvxStore(Op, DAG);
     // Unaligned loads will be handled by the default lowering.
     case ISD::LOAD:                    return SDValue();
   }

diff  --git a/llvm/test/CodeGen/Hexagon/store-vector-pred.ll b/llvm/test/CodeGen/Hexagon/store-vector-pred.ll
new file mode 100644
index 000000000000..0c7949787c14
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/store-vector-pred.ll
@@ -0,0 +1,47 @@
+; RUN: llc  < %s | FileCheck %s
+
+; This test checks that store a vector predicate of type v128i1 is lowered
+; and two double stores are generated.
+
+; CHECK-DAG: memd(r{{[0-9]+}}+#0) = r{{[0-9]+}}:{{[0-9]+}}
+; CHECK-DAG: memd(r{{[0-9]+}}+#8) = r{{[0-9]+}}:{{[0-9]+}}
+
+target triple = "hexagon"
+
+define dso_local void @raac_UnpackADIFHeader() local_unnamed_addr #0 {
+entry:
+  br i1 undef, label %cleanup, label %if.end
+
+if.end:
+  %0 = load i8, i8* undef, align 1
+  %conv13.i = zext i8 %0 to i32
+  %trip.count.minus.1216 = add nsw i32 %conv13.i, -1
+  %broadcast.splatinsert221 = insertelement <128 x i32> undef, i32 %trip.count.minus.1216, i32 0
+  %broadcast.splat222 = shufflevector <128 x i32> %broadcast.splatinsert221, <128 x i32> undef, <128 x i32> zeroinitializer
+  %1 = icmp ule <128 x i32> undef, %broadcast.splat222
+  %wide.masked.load223 = call <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>* nonnull undef, i32 1, <128 x i1> %1, <128 x i8> undef)
+  %2 = lshr <128 x i8> %wide.masked.load223, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
+  %3 = and <128 x i8> %2, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
+  %4 = zext <128 x i8> %3 to <128 x i32>
+  %5 = add nsw <128 x i32> undef, %4
+  %6 = select <128 x i1> %1, <128 x i32> %5, <128 x i32> undef
+  %bin.rdx225 = add <128 x i32> %6, undef
+  %bin.rdx227 = add <128 x i32> %bin.rdx225, undef
+  %bin.rdx229 = add <128 x i32> %bin.rdx227, undef
+  %bin.rdx231 = add <128 x i32> %bin.rdx229, undef
+  %bin.rdx233 = add <128 x i32> %bin.rdx231, undef
+  %bin.rdx235 = add <128 x i32> %bin.rdx233, undef
+  %bin.rdx237 = add <128 x i32> %bin.rdx235, undef
+  %7 = extractelement <128 x i32> %bin.rdx237, i32 0
+  %nChans = getelementptr inbounds i8, i8* null, i32 2160
+  %8 = bitcast i8* %nChans to i32*
+  store i32 %7, i32* %8, align 4
+  br label %cleanup
+
+cleanup:
+  ret void
+  }
+
+declare <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>*, i32 immarg, <128 x i1>, <128 x i8>)
+
+attributes #0 = { "target-features"="+hvx-length128b,+hvxv67,+v67,-long-calls" }


        


More information about the llvm-commits mailing list