[llvm] r369124 - [Hexagon] Generate min/max instructions for 64-bit vectors

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 16 09:16:27 PDT 2019


Author: kparzysz
Date: Fri Aug 16 09:16:27 2019
New Revision: 369124

URL: http://llvm.org/viewvc/llvm-project?rev=369124&view=rev
Log:
[Hexagon] Generate min/max instructions for 64-bit vectors

Added:
    llvm/trunk/test/CodeGen/Hexagon/isel-minmax-v64bit.ll
Modified:
    llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
    llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h
    llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td
    llvm/trunk/lib/Target/Hexagon/HexagonPatternsHVX.td
    llvm/trunk/test/CodeGen/Hexagon/isel-vselect-v4i8.ll

Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp?rev=369124&r1=369123&r2=369124&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp Fri Aug 16 09:16:27 2019
@@ -1501,11 +1501,15 @@ HexagonTargetLowering::HexagonTargetLowe
     setOperationAction(ISD::STORE, VT, Custom);
   }
 
-  for (MVT VT : {MVT::v2i16, MVT::v4i8, MVT::v2i32, MVT::v4i16, MVT::v2i32}) {
-    setCondCodeAction(ISD::SETLT,  VT, Expand);
+  for (MVT VT : {MVT::v2i16, MVT::v4i8, MVT::v8i8, MVT::v2i32, MVT::v4i16,
+                 MVT::v2i32}) {
+    setCondCodeAction(ISD::SETNE,  VT, Expand);
     setCondCodeAction(ISD::SETLE,  VT, Expand);
-    setCondCodeAction(ISD::SETULT, VT, Expand);
+    setCondCodeAction(ISD::SETGE,  VT, Expand);
+    setCondCodeAction(ISD::SETLT,  VT, Expand);
     setCondCodeAction(ISD::SETULE, VT, Expand);
+    setCondCodeAction(ISD::SETUGE, VT, Expand);
+    setCondCodeAction(ISD::SETULT, VT, Expand);
   }
 
   // Custom-lower bitcasts from i8 to v8i1.
@@ -1560,6 +1564,8 @@ HexagonTargetLowering::HexagonTargetLowe
     setOperationAction(ISD::FSUB, MVT::f64, Legal);
   }
 
+  setTargetDAGCombine(ISD::VSELECT);
+
   if (Subtarget.useHVXOps())
     initializeHVXLowering();
 
@@ -1649,6 +1655,8 @@ const char* HexagonTargetLowering::getTa
   case HexagonISD::VINSERTW0:     return "HexagonISD::VINSERTW0";
   case HexagonISD::VROR:          return "HexagonISD::VROR";
   case HexagonISD::READCYCLE:     return "HexagonISD::READCYCLE";
+  case HexagonISD::PTRUE:         return "HexagonISD::PTRUE";
+  case HexagonISD::PFALSE:        return "HexagonISD::PFALSE";
   case HexagonISD::VZERO:         return "HexagonISD::VZERO";
   case HexagonISD::VSPLATW:       return "HexagonISD::VSPLATW";
   case HexagonISD::D2P:           return "HexagonISD::D2P";
@@ -2464,6 +2472,23 @@ HexagonTargetLowering::LowerBUILD_VECTOR
     return buildVector64(Ops, dl, VecTy, DAG);
 
   if (VecTy == MVT::v8i1 || VecTy == MVT::v4i1 || VecTy == MVT::v2i1) {
+    // Check if this is a special case or all-0 or all-1.
+    bool All0 = true, All1 = true;
+    for (SDValue P : Ops) {
+      auto *CN = dyn_cast<ConstantSDNode>(P.getNode());
+      if (CN == nullptr) {
+        All0 = All1 = false;
+        break;
+      }
+      uint32_t C = CN->getZExtValue();
+      All0 &= (C == 0);
+      All1 &= (C == 1);
+    }
+    if (All0)
+      return DAG.getNode(HexagonISD::PFALSE, dl, VecTy);
+    if (All1)
+      return DAG.getNode(HexagonISD::PTRUE, dl, VecTy);
+
     // For each i1 element in the resulting predicate register, put 1
     // shifted by the index of the element into a general-purpose register,
     // then or them together and transfer it back into a predicate register.
@@ -2890,7 +2915,37 @@ HexagonTargetLowering::PerformDAGCombine
   if (isHvxOperation(Op)) {
     if (SDValue V = PerformHvxDAGCombine(N, DCI))
       return V;
+    return SDValue();
   }
+
+  const SDLoc &dl(Op);
+  unsigned Opc = Op.getOpcode();
+
+  if (Opc == HexagonISD::P2D) {
+    SDValue P = Op.getOperand(0);
+    switch (P.getOpcode()) {
+      case HexagonISD::PTRUE:
+        return DCI.DAG.getConstant(-1, dl, ty(Op));
+      case HexagonISD::PFALSE:
+        return getZero(dl, ty(Op), DCI.DAG);
+      default:
+        break;
+    }
+  } else if (Opc == ISD::VSELECT) {
+    // This is pretty much duplicated in HexagonISelLoweringHVX...
+    //
+    // (vselect (xor x, ptrue), v0, v1) -> (vselect x, v1, v0)
+    SDValue Cond = Op.getOperand(0);
+    if (Cond->getOpcode() == ISD::XOR) {
+      SDValue C0 = Cond.getOperand(0), C1 = Cond.getOperand(1);
+      if (C1->getOpcode() == HexagonISD::PTRUE) {
+        SDValue VSel = DCI.DAG.getNode(ISD::VSELECT, dl, ty(Op), C0,
+                                       Op.getOperand(2), Op.getOperand(1));
+        return VSel;
+      }
+    }
+  }
+
   return SDValue();
 }
 

Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h?rev=369124&r1=369123&r2=369124&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h Fri Aug 16 09:16:27 2019
@@ -68,6 +68,8 @@ namespace HexagonISD {
       EH_RETURN,
       DCFETCH,
       READCYCLE,
+      PTRUE,
+      PFALSE,
       D2P,         // Convert 8-byte value to 8-bit predicate register. [*]
       P2D,         // Convert 8-bit predicate register to 8-byte value. [*]
       V2Q,         // Convert HVX vector to a vector predicate reg. [*]

Modified: llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td?rev=369124&r1=369123&r2=369124&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td Fri Aug 16 09:16:27 2019
@@ -99,13 +99,21 @@ def HWI8:   PatLeaf<(VecPI8  HvxWR:$R)>;
 def HWI16:  PatLeaf<(VecPI16 HvxWR:$R)>;
 def HWI32:  PatLeaf<(VecPI32 HvxWR:$R)>;
 
+def SDTVecLeaf:
+  SDTypeProfile<1, 0, [SDTCisVec<0>]>;
 def SDTVecVecIntOp:
   SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1,2>,
                        SDTCisVT<3,i32>]>;
 
+def HexagonPTRUE:      SDNode<"HexagonISD::PTRUE",      SDTVecLeaf>;
+def HexagonPFALSE:     SDNode<"HexagonISD::PFALSE",     SDTVecLeaf>;
 def HexagonVALIGN:     SDNode<"HexagonISD::VALIGN",     SDTVecVecIntOp>;
 def HexagonVALIGNADDR: SDNode<"HexagonISD::VALIGNADDR", SDTIntUnaryOp>;
 
+def ptrue:  PatFrag<(ops), (HexagonPTRUE)>;
+def pfalse: PatFrag<(ops), (HexagonPFALSE)>;
+def pnot:   PatFrag<(ops node:$Pu), (xor node:$Pu, ptrue)>;
+
 def valign: PatFrag<(ops node:$Vt, node:$Vs, node:$Ru),
                     (HexagonVALIGN node:$Vt, node:$Vs, node:$Ru)>;
 def valignaddr: PatFrag<(ops node:$Addr), (HexagonVALIGNADDR node:$Addr)>;
@@ -320,6 +328,17 @@ multiclass SelMinMax_pats<PatFrag CmpOp,
            (InstB Val:$A, Val:$B)>;
 }
 
+multiclass MinMax_pats<InstHexagon PickT, InstHexagon PickS,
+                       PatFrag Sel, PatFrag CmpOp,
+                       ValueType CmpType, PatFrag CmpPred> {
+  def: Pat<(Sel (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)),
+                CmpPred:$Vt, CmpPred:$Vs),
+           (PickT CmpPred:$Vs, CmpPred:$Vt)>;
+  def: Pat<(Sel (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)),
+                CmpPred:$Vs, CmpPred:$Vt),
+           (PickS CmpPred:$Vs, CmpPred:$Vt)>;
+}
+
 
 // Frags for commonly used SDNodes.
 def Add: pf2<add>;    def And: pf2<and>;    def Sra: pf2<sra>;
@@ -497,7 +516,9 @@ def: Pat<(v2i16 (trunc V2I32:$Rs)),
 //
 
 def: Pat<(not I1:$Ps),      (C2_not I1:$Ps)>;
-def: Pat<(not V8I1:$Ps),    (C2_not V8I1:$Ps)>;
+def: Pat<(pnot V2I1:$Ps),   (C2_not V2I1:$Ps)>;
+def: Pat<(pnot V4I1:$Ps),   (C2_not V4I1:$Ps)>;
+def: Pat<(pnot V8I1:$Ps),   (C2_not V8I1:$Ps)>;
 def: Pat<(add I1:$Ps, -1),  (C2_not I1:$Ps)>;
 
 multiclass BoolOpR_RR_pat<InstHexagon MI, PatFrag Op> {
@@ -823,6 +844,14 @@ def: Pat<(vselect V4I1:$Pu, V4I16:$Rs, V
 def: Pat<(vselect V2I1:$Pu, V2I32:$Rs, V2I32:$Rt),
          (C2_vmux V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)>;
 
+def: Pat<(vselect (pnot V8I1:$Pu), V8I8:$Rs, V8I8:$Rt),
+         (C2_vmux V8I1:$Pu, V8I8:$Rt, V8I8:$Rs)>;
+def: Pat<(vselect (pnot V4I1:$Pu), V4I16:$Rs, V4I16:$Rt),
+         (C2_vmux V4I1:$Pu, V4I16:$Rt, V4I16:$Rs)>;
+def: Pat<(vselect (pnot V2I1:$Pu), V2I32:$Rs, V2I32:$Rt),
+         (C2_vmux V2I1:$Pu, V2I32:$Rt, V2I32:$Rs)>;
+
+
 // From LegalizeDAG.cpp: (Pu ? Pv : Pw) <=> (Pu & Pv) | (!Pu & Pw).
 def: Pat<(select I1:$Pu, I1:$Pv, I1:$Pw),
          (C2_or (C2_and  I1:$Pu, I1:$Pv),
@@ -855,32 +884,44 @@ let AddedComplexity = 200 in {
 }
 
 let AddedComplexity = 200 in {
-  defm: SelMinMax_pats<setge,  I32, A2_max,   A2_min>;
-  defm: SelMinMax_pats<setgt,  I32, A2_max,   A2_min>;
-  defm: SelMinMax_pats<setle,  I32, A2_min,   A2_max>;
-  defm: SelMinMax_pats<setlt,  I32, A2_min,   A2_max>;
-  defm: SelMinMax_pats<setuge, I32, A2_maxu,  A2_minu>;
-  defm: SelMinMax_pats<setugt, I32, A2_maxu,  A2_minu>;
-  defm: SelMinMax_pats<setule, I32, A2_minu,  A2_maxu>;
-  defm: SelMinMax_pats<setult, I32, A2_minu,  A2_maxu>;
-
-  defm: SelMinMax_pats<setge,  I64, A2_maxp,  A2_minp>;
-  defm: SelMinMax_pats<setgt,  I64, A2_maxp,  A2_minp>;
-  defm: SelMinMax_pats<setle,  I64, A2_minp,  A2_maxp>;
-  defm: SelMinMax_pats<setlt,  I64, A2_minp,  A2_maxp>;
-  defm: SelMinMax_pats<setuge, I64, A2_maxup, A2_minup>;
-  defm: SelMinMax_pats<setugt, I64, A2_maxup, A2_minup>;
-  defm: SelMinMax_pats<setule, I64, A2_minup, A2_maxup>;
-  defm: SelMinMax_pats<setult, I64, A2_minup, A2_maxup>;
+  defm: MinMax_pats<A2_min,   A2_max,   select,  setgt, i1, I32>;
+  defm: MinMax_pats<A2_min,   A2_max,   select,  setge, i1, I32>;
+  defm: MinMax_pats<A2_max,   A2_min,   select,  setlt, i1, I32>;
+  defm: MinMax_pats<A2_max,   A2_min,   select,  setle, i1, I32>;
+  defm: MinMax_pats<A2_minu,  A2_maxu,  select, setugt, i1, I32>;
+  defm: MinMax_pats<A2_minu,  A2_maxu,  select, setuge, i1, I32>;
+  defm: MinMax_pats<A2_maxu,  A2_minu,  select, setult, i1, I32>;
+  defm: MinMax_pats<A2_maxu,  A2_minu,  select, setule, i1, I32>;
+
+  defm: MinMax_pats<A2_minp,  A2_maxp,  select,  setgt, i1, I64>;
+  defm: MinMax_pats<A2_minp,  A2_maxp,  select,  setge, i1, I64>;
+  defm: MinMax_pats<A2_maxp,  A2_minp,  select,  setlt, i1, I64>;
+  defm: MinMax_pats<A2_maxp,  A2_minp,  select,  setle, i1, I64>;
+  defm: MinMax_pats<A2_minup, A2_maxup, select, setugt, i1, I64>;
+  defm: MinMax_pats<A2_minup, A2_maxup, select, setuge, i1, I64>;
+  defm: MinMax_pats<A2_maxup, A2_minup, select, setult, i1, I64>;
+  defm: MinMax_pats<A2_maxup, A2_minup, select, setule, i1, I64>;
 }
 
 let AddedComplexity = 100 in {
-  defm: SelMinMax_pats<setolt, F32, F2_sfmin, F2_sfmax>;
-  defm: SelMinMax_pats<setole, F32, F2_sfmin, F2_sfmax>;
-  defm: SelMinMax_pats<setogt, F32, F2_sfmax, F2_sfmin>;
-  defm: SelMinMax_pats<setoge, F32, F2_sfmax, F2_sfmin>;
-}
-
+  defm: MinMax_pats<F2_sfmin, F2_sfmax, select, setogt, i1, F32>;
+  defm: MinMax_pats<F2_sfmin, F2_sfmax, select, setoge, i1, F32>;
+  defm: MinMax_pats<F2_sfmax, F2_sfmin, select, setolt, i1, F32>;
+  defm: MinMax_pats<F2_sfmax, F2_sfmin, select, setole, i1, F32>;
+}
+
+defm: MinMax_pats<A2_vminb,  A2_vmaxb,  vselect,  setgt,  v8i1,  V8I8>;
+defm: MinMax_pats<A2_vminb,  A2_vmaxb,  vselect,  setge,  v8i1,  V8I8>;
+defm: MinMax_pats<A2_vminh,  A2_vmaxh,  vselect,  setgt,  v4i1, V4I16>;
+defm: MinMax_pats<A2_vminh,  A2_vmaxh,  vselect,  setge,  v4i1, V4I16>;
+defm: MinMax_pats<A2_vminw,  A2_vmaxw,  vselect,  setgt,  v2i1, V2I32>;
+defm: MinMax_pats<A2_vminw,  A2_vmaxw,  vselect,  setge,  v2i1, V2I32>;
+defm: MinMax_pats<A2_vminub, A2_vmaxub, vselect, setugt,  v8i1,  V8I8>;
+defm: MinMax_pats<A2_vminub, A2_vmaxub, vselect, setuge,  v8i1,  V8I8>;
+defm: MinMax_pats<A2_vminuh, A2_vmaxuh, vselect, setugt,  v4i1, V4I16>;
+defm: MinMax_pats<A2_vminuh, A2_vmaxuh, vselect, setuge,  v4i1, V4I16>;
+defm: MinMax_pats<A2_vminuw, A2_vmaxuw, vselect, setugt,  v2i1, V2I32>;
+defm: MinMax_pats<A2_vminuw, A2_vmaxuw, vselect, setuge,  v2i1, V2I32>;
 
 // --(7) Insert/extract --------------------------------------------------
 //

Modified: llvm/trunk/lib/Target/Hexagon/HexagonPatternsHVX.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonPatternsHVX.td?rev=369124&r1=369123&r2=369124&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonPatternsHVX.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonPatternsHVX.td Fri Aug 16 09:16:27 2019
@@ -1,5 +1,3 @@
-def SDTVecLeaf:
-  SDTypeProfile<1, 0, [SDTCisVec<0>]>;
 def SDTVecBinOp:
   SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1,2>]>;
 
@@ -259,28 +257,18 @@ class Vneg1<ValueType VecTy>
 class Vnot<ValueType VecTy>
   : PatFrag<(ops node:$Vs), (xor $Vs, Vneg1<VecTy>)>;
 
-multiclass VMinMax_pat<InstHexagon MinInst, InstHexagon MaxInst, PatFrag CmpOp,
-                       ValueType CmpType, PatFrag CmpPred> {
-  def: Pat<(vselect (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)),
-                             CmpPred:$Vt, CmpPred:$Vs),
-           (MinInst CmpPred:$Vs, CmpPred:$Vt)>;
-  def: Pat<(vselect (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)),
-                             CmpPred:$Vs, CmpPred:$Vt),
-           (MaxInst CmpPred:$Vs, CmpPred:$Vt)>;
-}
-
 let Predicates = [UseHVX] in {
   let AddedComplexity = 220 in {
-    defm: VMinMax_pat<V6_vminb,  V6_vmaxb,   setgt,  VecQ8,  HVI8>;
-    defm: VMinMax_pat<V6_vminb,  V6_vmaxb,   setge,  VecQ8,  HVI8>;
-    defm: VMinMax_pat<V6_vminub, V6_vmaxub, setugt,  VecQ8,  HVI8>;
-    defm: VMinMax_pat<V6_vminub, V6_vmaxub, setuge,  VecQ8,  HVI8>;
-    defm: VMinMax_pat<V6_vminh,  V6_vmaxh,   setgt, VecQ16, HVI16>;
-    defm: VMinMax_pat<V6_vminh,  V6_vmaxh,   setge, VecQ16, HVI16>;
-    defm: VMinMax_pat<V6_vminuh, V6_vmaxuh, setugt, VecQ16, HVI16>;
-    defm: VMinMax_pat<V6_vminuh, V6_vmaxuh, setuge, VecQ16, HVI16>;
-    defm: VMinMax_pat<V6_vminw,  V6_vmaxw,   setgt, VecQ32, HVI32>;
-    defm: VMinMax_pat<V6_vminw,  V6_vmaxw,   setge, VecQ32, HVI32>;
+    defm: MinMax_pats<V6_vminb,  V6_vmaxb,  vselect,  setgt,  VecQ8,  HVI8>;
+    defm: MinMax_pats<V6_vminb,  V6_vmaxb,  vselect,  setge,  VecQ8,  HVI8>;
+    defm: MinMax_pats<V6_vminub, V6_vmaxub, vselect, setugt,  VecQ8,  HVI8>;
+    defm: MinMax_pats<V6_vminub, V6_vmaxub, vselect, setuge,  VecQ8,  HVI8>;
+    defm: MinMax_pats<V6_vminh,  V6_vmaxh,  vselect,  setgt, VecQ16, HVI16>;
+    defm: MinMax_pats<V6_vminh,  V6_vmaxh,  vselect,  setge, VecQ16, HVI16>;
+    defm: MinMax_pats<V6_vminuh, V6_vmaxuh, vselect, setugt, VecQ16, HVI16>;
+    defm: MinMax_pats<V6_vminuh, V6_vmaxuh, vselect, setuge, VecQ16, HVI16>;
+    defm: MinMax_pats<V6_vminw,  V6_vmaxw,  vselect,  setgt, VecQ32, HVI32>;
+    defm: MinMax_pats<V6_vminw,  V6_vmaxw,  vselect,  setge, VecQ32, HVI32>;
   }
 }
 

Added: llvm/trunk/test/CodeGen/Hexagon/isel-minmax-v64bit.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/isel-minmax-v64bit.ll?rev=369124&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/isel-minmax-v64bit.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/isel-minmax-v64bit.ll Fri Aug 16 09:16:27 2019
@@ -0,0 +1,202 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; min
+
+; CHECK-LABEL: test_00:
+; CHECK: r1:0 = vminb(r3:2,r1:0)
+define <8 x i8> @test_00(<8 x i8> %a0, <8 x i8> %a1) #0 {
+  %v0 = icmp slt <8 x i8> %a0, %a1
+  %v1 = select <8 x i1> %v0, <8 x i8> %a0, <8 x i8> %a1
+  ret <8 x i8> %v1
+}
+
+; CHECK-LABEL: test_01:
+; CHECK: r1:0 = vminb(r1:0,r3:2)
+define <8 x i8> @test_01(<8 x i8> %a0, <8 x i8> %a1) #0 {
+  %v0 = icmp sle <8 x i8> %a0, %a1
+  %v1 = select <8 x i1> %v0, <8 x i8> %a0, <8 x i8> %a1
+  ret <8 x i8> %v1
+}
+
+; CHECK-LABEL: test_02:
+; CHECK: r1:0 = vminh(r3:2,r1:0)
+define <4 x i16> @test_02(<4 x i16> %a0, <4 x i16> %a1) #0 {
+  %v0 = icmp slt <4 x i16> %a0, %a1
+  %v1 = select <4 x i1> %v0, <4 x i16> %a0, <4 x i16> %a1
+  ret <4 x i16> %v1
+}
+
+; CHECK-LABEL: test_03:
+; CHECK: r1:0 = vminh(r1:0,r3:2)
+define <4 x i16> @test_03(<4 x i16> %a0, <4 x i16> %a1) #0 {
+  %v0 = icmp sle <4 x i16> %a0, %a1
+  %v1 = select <4 x i1> %v0, <4 x i16> %a0, <4 x i16> %a1
+  ret <4 x i16> %v1
+}
+
+; CHECK-LABEL: test_04:
+; CHECK: r1:0 = vminw(r3:2,r1:0)
+define <2 x i32> @test_04(<2 x i32> %a0, <2 x i32> %a1) #0 {
+  %v0 = icmp slt <2 x i32> %a0, %a1
+  %v1 = select <2 x i1> %v0, <2 x i32> %a0, <2 x i32> %a1
+  ret <2 x i32> %v1
+}
+
+; CHECK-LABEL: test_05:
+; CHECK: r1:0 = vminw(r1:0,r3:2)
+define <2 x i32> @test_05(<2 x i32> %a0, <2 x i32> %a1) #0 {
+  %v0 = icmp sle <2 x i32> %a0, %a1
+  %v1 = select <2 x i1> %v0, <2 x i32> %a0, <2 x i32> %a1
+  ret <2 x i32> %v1
+}
+
+; minu
+
+; CHECK-LABEL: test_06:
+; CHECK: r1:0 = vminub(r3:2,r1:0)
+define <8 x i8> @test_06(<8 x i8> %a0, <8 x i8> %a1) #0 {
+  %v0 = icmp ult <8 x i8> %a0, %a1
+  %v1 = select <8 x i1> %v0, <8 x i8> %a0, <8 x i8> %a1
+  ret <8 x i8> %v1
+}
+
+; CHECK-LABEL: test_07:
+; CHECK: r1:0 = vminub(r1:0,r3:2)
+define <8 x i8> @test_07(<8 x i8> %a0, <8 x i8> %a1) #0 {
+  %v0 = icmp ule <8 x i8> %a0, %a1
+  %v1 = select <8 x i1> %v0, <8 x i8> %a0, <8 x i8> %a1
+  ret <8 x i8> %v1
+}
+
+; CHECK-LABEL: test_08:
+; CHECK: r1:0 = vminuh(r3:2,r1:0)
+define <4 x i16> @test_08(<4 x i16> %a0, <4 x i16> %a1) #0 {
+  %v0 = icmp ult <4 x i16> %a0, %a1
+  %v1 = select <4 x i1> %v0, <4 x i16> %a0, <4 x i16> %a1
+  ret <4 x i16> %v1
+}
+
+; CHECK-LABEL: test_09:
+; CHECK: r1:0 = vminuh(r1:0,r3:2)
+define <4 x i16> @test_09(<4 x i16> %a0, <4 x i16> %a1) #0 {
+  %v0 = icmp ule <4 x i16> %a0, %a1
+  %v1 = select <4 x i1> %v0, <4 x i16> %a0, <4 x i16> %a1
+  ret <4 x i16> %v1
+}
+
+; CHECK-LABEL: test_0a:
+; CHECK: r1:0 = vminuw(r3:2,r1:0)
+define <2 x i32> @test_0a(<2 x i32> %a0, <2 x i32> %a1) #0 {
+  %v0 = icmp ult <2 x i32> %a0, %a1
+  %v1 = select <2 x i1> %v0, <2 x i32> %a0, <2 x i32> %a1
+  ret <2 x i32> %v1
+}
+
+; CHECK-LABEL: test_0b:
+; CHECK: r1:0 = vminuw(r1:0,r3:2)
+define <2 x i32> @test_0b(<2 x i32> %a0, <2 x i32> %a1) #0 {
+  %v0 = icmp ule <2 x i32> %a0, %a1
+  %v1 = select <2 x i1> %v0, <2 x i32> %a0, <2 x i32> %a1
+  ret <2 x i32> %v1
+}
+
+; max
+
+; CHECK-LABEL: test_0c:
+; CHECK: r1:0 = vmaxb(r1:0,r3:2)
+define <8 x i8> @test_0c(<8 x i8> %a0, <8 x i8> %a1) #0 {
+  %v0 = icmp sgt <8 x i8> %a0, %a1
+  %v1 = select <8 x i1> %v0, <8 x i8> %a0, <8 x i8> %a1
+  ret <8 x i8> %v1
+}
+
+; CHECK-LABEL: test_0d:
+; CHECK: r1:0 = vmaxb(r3:2,r1:0)
+define <8 x i8> @test_0d(<8 x i8> %a0, <8 x i8> %a1) #0 {
+  %v0 = icmp sge <8 x i8> %a0, %a1
+  %v1 = select <8 x i1> %v0, <8 x i8> %a0, <8 x i8> %a1
+  ret <8 x i8> %v1
+}
+
+; CHECK-LABEL: test_0e:
+; CHECK: r1:0 = vmaxh(r1:0,r3:2)
+define <4 x i16> @test_0e(<4 x i16> %a0, <4 x i16> %a1) #0 {
+  %v0 = icmp sgt <4 x i16> %a0, %a1
+  %v1 = select <4 x i1> %v0, <4 x i16> %a0, <4 x i16> %a1
+  ret <4 x i16> %v1
+}
+
+; CHECK-LABEL: test_0f:
+; CHECK: r1:0 = vmaxh(r3:2,r1:0)
+define <4 x i16> @test_0f(<4 x i16> %a0, <4 x i16> %a1) #0 {
+  %v0 = icmp sge <4 x i16> %a0, %a1
+  %v1 = select <4 x i1> %v0, <4 x i16> %a0, <4 x i16> %a1
+  ret <4 x i16> %v1
+}
+
+; CHECK-LABEL: test_10:
+; CHECK: r1:0 = vmaxw(r1:0,r3:2)
+define <2 x i32> @test_10(<2 x i32> %a0, <2 x i32> %a1) #0 {
+  %v0 = icmp sgt <2 x i32> %a0, %a1
+  %v1 = select <2 x i1> %v0, <2 x i32> %a0, <2 x i32> %a1
+  ret <2 x i32> %v1
+}
+
+; CHECK-LABEL: test_11:
+; CHECK: r1:0 = vmaxw(r3:2,r1:0)
+define <2 x i32> @test_11(<2 x i32> %a0, <2 x i32> %a1) #0 {
+  %v0 = icmp sge <2 x i32> %a0, %a1
+  %v1 = select <2 x i1> %v0, <2 x i32> %a0, <2 x i32> %a1
+  ret <2 x i32> %v1
+}
+
+; maxu
+
+; CHECK-LABEL: test_12:
+; CHECK: r1:0 = vmaxub(r1:0,r3:2)
+define <8 x i8> @test_12(<8 x i8> %a0, <8 x i8> %a1) #0 {
+  %v0 = icmp ugt <8 x i8> %a0, %a1
+  %v1 = select <8 x i1> %v0, <8 x i8> %a0, <8 x i8> %a1
+  ret <8 x i8> %v1
+}
+
+; CHECK-LABEL: test_13:
+; CHECK: r1:0 = vmaxub(r3:2,r1:0)
+define <8 x i8> @test_13(<8 x i8> %a0, <8 x i8> %a1) #0 {
+  %v0 = icmp uge <8 x i8> %a0, %a1
+  %v1 = select <8 x i1> %v0, <8 x i8> %a0, <8 x i8> %a1
+  ret <8 x i8> %v1
+}
+
+; CHECK-LABEL: test_14:
+; CHECK: r1:0 = vmaxuh(r1:0,r3:2)
+define <4 x i16> @test_14(<4 x i16> %a0, <4 x i16> %a1) #0 {
+  %v0 = icmp ugt <4 x i16> %a0, %a1
+  %v1 = select <4 x i1> %v0, <4 x i16> %a0, <4 x i16> %a1
+  ret <4 x i16> %v1
+}
+
+; CHECK-LABEL: test_15:
+; CHECK: r1:0 = vmaxuh(r3:2,r1:0)
+define <4 x i16> @test_15(<4 x i16> %a0, <4 x i16> %a1) #0 {
+  %v0 = icmp uge <4 x i16> %a0, %a1
+  %v1 = select <4 x i1> %v0, <4 x i16> %a0, <4 x i16> %a1
+  ret <4 x i16> %v1
+}
+
+; CHECK-LABEL: test_16:
+; CHECK: r1:0 = vmaxuw(r1:0,r3:2)
+define <2 x i32> @test_16(<2 x i32> %a0, <2 x i32> %a1) #0 {
+  %v0 = icmp ugt <2 x i32> %a0, %a1
+  %v1 = select <2 x i1> %v0, <2 x i32> %a0, <2 x i32> %a1
+  ret <2 x i32> %v1
+}
+
+; CHECK-LABEL: test_17:
+; CHECK: r1:0 = vmaxuw(r3:2,r1:0)
+define <2 x i32> @test_17(<2 x i32> %a0, <2 x i32> %a1) #0 {
+  %v0 = icmp uge <2 x i32> %a0, %a1
+  %v1 = select <2 x i1> %v0, <2 x i32> %a0, <2 x i32> %a1
+  ret <2 x i32> %v1
+}
+

Modified: llvm/trunk/test/CodeGen/Hexagon/isel-vselect-v4i8.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/isel-vselect-v4i8.ll?rev=369124&r1=369123&r2=369124&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/isel-vselect-v4i8.ll (original)
+++ llvm/trunk/test/CodeGen/Hexagon/isel-vselect-v4i8.ll Fri Aug 16 09:16:27 2019
@@ -1,6 +1,6 @@
 ; RUN: llc -march=hexagon < %s | FileCheck %s
 ; This used to crash with "cannot select (v4i8 vselect ...)"
-; CHECK: vmux
+; CHECK: vtrunehb
 
 define <4 x i8> @f0(<4 x i8> %a0, <4 x i8> %a1) #0 {
   %v0 = icmp slt <4 x i8> %a0, %a1




More information about the llvm-commits mailing list