[llvm-branch-commits] [llvm] a902147 - [Hexagon] Custom-widen SETCC's operands

Krzysztof Parzyszek via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jan 11 10:33:46 PST 2021


Author: Krzysztof Parzyszek
Date: 2021-01-11T12:21:49-06:00
New Revision: a90214760d0414912953e77b5b314be2b8e7df77

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

LOG: [Hexagon] Custom-widen SETCC's operands

The result cannot be widened, unfortunately, because widening vNi1
would depend on the context in which it appears (i.e. the type alone
is not sufficient to tell if it needs to be widened).

Added: 
    llvm/test/CodeGen/Hexagon/autohvx/widen-setcc.ll

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index e174e5279ac1..cfccb14a09c9 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -486,6 +486,7 @@ class HexagonTargetLowering : public TargetLowering {
   SDValue SplitHvxMemOp(SDValue Op, SelectionDAG &DAG) const;
   SDValue WidenHvxLoad(SDValue Op, SelectionDAG &DAG) const;
   SDValue WidenHvxStore(SDValue Op, SelectionDAG &DAG) const;
+  SDValue WidenHvxSetCC(SDValue Op, SelectionDAG &DAG) const;
   SDValue WidenHvxExtend(SDValue Op, SelectionDAG &DAG) const;
   SDValue WidenHvxTruncate(SDValue Op, SelectionDAG &DAG) const;
 

diff  --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
index f228e0a23794..161035b93e8b 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
@@ -51,6 +51,13 @@ HexagonTargetLowering::initializeHVXLowering() {
     addRegisterClass(MVT::v256i8,  &Hexagon::HvxWRRegClass);
     addRegisterClass(MVT::v128i16, &Hexagon::HvxWRRegClass);
     addRegisterClass(MVT::v64i32,  &Hexagon::HvxWRRegClass);
+    // Treat v16i1 as a legal type, since there is no way to widen vNi1:
+    // the validity of vNi1 may depend on how the result was obtained.
+    // For example v32i1 is ok when it's a result of comparing v32i32,
+    // but would need to be widened if it came from comparing v32i16.
+    // This precludes using getTypeToTransformTo, since it doesn't have
+    // the necessary context to decide what to do.
+    addRegisterClass(MVT::v16i1, &Hexagon::HvxQRRegClass);
     addRegisterClass(MVT::v32i1, &Hexagon::HvxQRRegClass);
     addRegisterClass(MVT::v64i1, &Hexagon::HvxQRRegClass);
     addRegisterClass(MVT::v128i1, &Hexagon::HvxQRRegClass);
@@ -241,7 +248,6 @@ HexagonTargetLowering::initializeHVXLowering() {
   }
 
   // Handle store widening for short vectors.
-  std::vector<MVT> ShortTys;
   unsigned HwLen = Subtarget.getVectorLength();
   for (MVT ElemTy : Subtarget.getHVXElementTypes()) {
     if (ElemTy == MVT::i1)
@@ -254,6 +260,7 @@ HexagonTargetLowering::initializeHVXLowering() {
       if (Action == TargetLoweringBase::TypeWidenVector) {
         setOperationAction(ISD::LOAD,         VecTy, Custom);
         setOperationAction(ISD::STORE,        VecTy, Custom);
+        setOperationAction(ISD::SETCC,        VecTy, Custom);
         setOperationAction(ISD::TRUNCATE,     VecTy, Custom);
         setOperationAction(ISD::ANY_EXTEND,   VecTy, Custom);
         setOperationAction(ISD::SIGN_EXTEND,  VecTy, Custom);
@@ -1932,6 +1939,27 @@ HexagonTargetLowering::WidenHvxStore(SDValue Op, SelectionDAG &DAG) const {
                             MemOp, ISD::UNINDEXED, false, false);
 }
 
+SDValue
+HexagonTargetLowering::WidenHvxSetCC(SDValue Op, SelectionDAG &DAG) const {
+  const SDLoc &dl(Op);
+  SDValue Op0 = Op.getOperand(0), Op1 = Op.getOperand(1);
+  MVT ElemTy = ty(Op0).getVectorElementType();
+  unsigned HwLen = Subtarget.getVectorLength();
+
+  unsigned WideOpLen = (8 * HwLen) / ElemTy.getSizeInBits();
+  assert(WideOpLen * ElemTy.getSizeInBits() == 8 * HwLen);
+  MVT WideOpTy = MVT::getVectorVT(ElemTy, WideOpLen);
+
+  SDValue WideOp0 = appendUndef(Op0, WideOpTy, DAG);
+  SDValue WideOp1 = appendUndef(Op1, WideOpTy, DAG);
+  EVT ResTy =
+      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), WideOpTy);
+  SDValue SetCC = DAG.getNode(ISD::SETCC, dl, ResTy,
+                              {WideOp0, WideOp1, Op.getOperand(2)});
+  return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, ty(Op),
+                     {SetCC, getZero(dl, MVT::i32, DAG)});
+}
+
 SDValue
 HexagonTargetLowering::WidenHvxExtend(SDValue Op, SelectionDAG &DAG) const {
   const SDLoc &dl(Op);
@@ -2102,20 +2130,28 @@ HexagonTargetLowering::LowerHvxOperationWrapper(SDNode *N,
     case ISD::ANY_EXTEND:
     case ISD::SIGN_EXTEND:
     case ISD::ZERO_EXTEND:
-      assert(shouldWidenToHvx(ty(Op.getOperand(0)), DAG) && "Not widening?");
-      if (SDValue T = WidenHvxExtend(Op, DAG))
-        Results.push_back(T);
+      if (shouldWidenToHvx(ty(Op.getOperand(0)), DAG)) {
+        if (SDValue T = WidenHvxExtend(Op, DAG))
+          Results.push_back(T);
+      }
+      break;
+    case ISD::SETCC:
+      if (shouldWidenToHvx(ty(Op.getOperand(0)), DAG)) {
+        if (SDValue T = WidenHvxSetCC(Op, DAG))
+          Results.push_back(T);
+      }
       break;
     case ISD::TRUNCATE:
-      assert(shouldWidenToHvx(ty(Op.getOperand(0)), DAG) && "Not widening?");
-      if (SDValue T = WidenHvxTruncate(Op, DAG))
-        Results.push_back(T);
+      if (shouldWidenToHvx(ty(Op.getOperand(0)), DAG)) {
+        if (SDValue T = WidenHvxTruncate(Op, DAG))
+          Results.push_back(T);
+      }
       break;
     case ISD::STORE: {
-      assert(shouldWidenToHvx(ty(cast<StoreSDNode>(N)->getValue()), DAG) &&
-             "Not widening?");
-      SDValue Store = WidenHvxStore(SDValue(N, 0), DAG);
-      Results.push_back(Store);
+      if (shouldWidenToHvx(ty(cast<StoreSDNode>(N)->getValue()), DAG)) {
+        SDValue Store = WidenHvxStore(Op, DAG);
+        Results.push_back(Store);
+      }
       break;
     }
     case ISD::MLOAD:
@@ -2132,6 +2168,8 @@ HexagonTargetLowering::LowerHvxOperationWrapper(SDNode *N,
         Results.push_back(S);
       }
       break;
+    default:
+      break;
   }
 }
 
@@ -2144,21 +2182,24 @@ HexagonTargetLowering::ReplaceHvxNodeResults(SDNode *N,
     case ISD::ANY_EXTEND:
     case ISD::SIGN_EXTEND:
     case ISD::ZERO_EXTEND:
-      assert(shouldWidenToHvx(ty(Op), DAG) && "Not widening?");
-      if (SDValue T = WidenHvxExtend(Op, DAG))
-        Results.push_back(T);
+      if (shouldWidenToHvx(ty(Op), DAG)) {
+        if (SDValue T = WidenHvxExtend(Op, DAG))
+          Results.push_back(T);
+      }
       break;
     case ISD::TRUNCATE:
-      assert(shouldWidenToHvx(ty(Op), DAG) && "Not widening?");
-      if (SDValue T = WidenHvxTruncate(Op, DAG))
-        Results.push_back(T);
+      if (shouldWidenToHvx(ty(Op), DAG)) {
+        if (SDValue T = WidenHvxTruncate(Op, DAG))
+          Results.push_back(T);
+      }
       break;
     case ISD::LOAD: {
-      assert(shouldWidenToHvx(ty(Op), DAG) && "Not widening?");
-      SDValue Load = WidenHvxLoad(Op, DAG);
-      assert(Load->getOpcode() == ISD::MERGE_VALUES);
-      Results.push_back(Load.getOperand(0));
-      Results.push_back(Load.getOperand(1));
+      if (shouldWidenToHvx(ty(Op), DAG)) {
+        SDValue Load = WidenHvxLoad(Op, DAG);
+        assert(Load->getOpcode() == ISD::MERGE_VALUES);
+        Results.push_back(Load.getOperand(0));
+        Results.push_back(Load.getOperand(1));
+      }
       break;
     }
     case ISD::BITCAST:
@@ -2180,7 +2221,6 @@ HexagonTargetLowering::PerformHvxDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
   SelectionDAG &DAG = DCI.DAG;
   SDValue Op(N, 0);
   unsigned Opc = Op.getOpcode();
-
   if (DCI.isBeforeLegalizeOps())
     return SDValue();
 
@@ -2231,7 +2271,6 @@ HexagonTargetLowering::PerformHvxDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
 
 bool
 HexagonTargetLowering::shouldWidenToHvx(MVT Ty, SelectionDAG &DAG) const {
-  assert(!Subtarget.isHVXVectorType(Ty, true));
   auto Action = getPreferredHvxVectorAction(Ty);
   if (Action == TargetLoweringBase::TypeWidenVector) {
     EVT WideTy = getTypeToTransformTo(*DAG.getContext(), Ty);

diff  --git a/llvm/test/CodeGen/Hexagon/autohvx/widen-setcc.ll b/llvm/test/CodeGen/Hexagon/autohvx/widen-setcc.ll
new file mode 100644
index 000000000000..3475e86feb0c
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/autohvx/widen-setcc.ll
@@ -0,0 +1,21 @@
+; RUN: llc -march=hexagon -hexagon-hvx-widen=32 < %s | FileCheck %s
+
+; Make sure that this doesn't crash.
+; CHECK-LABEL: f0:
+; CHECK: vmem
+
+target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
+target triple = "hexagon"
+
+define dllexport void @f0(i16* %a0, <16 x i16> %a1) local_unnamed_addr #0 {
+b0:
+  %v0 = getelementptr i16, i16* %a0, i32 undef
+  %v1 = bitcast i16* %v0 to <16 x i16>*
+  %v2 = load <16 x i16>, <16 x i16>* undef, align 2
+  %v3 = icmp sgt <16 x i16> zeroinitializer, %v2
+  %v4 = select <16 x i1> %v3, <16 x i16> %a1, <16 x i16> %v2
+  store <16 x i16> %v4, <16 x i16>* %v1, align 2
+  ret void
+}
+
+attributes #0 = { "target-features"="+hvxv66,+hvx-length128b" }


        


More information about the llvm-branch-commits mailing list