[Hexagon] Add HVX patterns for ISD::ABS
authorKrzysztof Parzyszek <kparzysz@quicinc.com>
Mon, 19 Sep 2022 17:05:03 +0000 (10:05 -0700)
committerKrzysztof Parzyszek <kparzysz@quicinc.com>
Mon, 19 Sep 2022 17:12:15 +0000 (10:12 -0700)
llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
llvm/test/CodeGen/Hexagon/autohvx/abs.ll [new file with mode: 0644]

index 85adbd5..1729bf0 100755 (executable)
@@ -163,6 +163,7 @@ HexagonTargetLowering::initializeHVXLowering() {
     setIndexedLoadAction(ISD::POST_INC,  T, Legal);
     setIndexedStoreAction(ISD::POST_INC, T, Legal);
 
+    setOperationAction(ISD::ABS,            T, Legal);
     setOperationAction(ISD::AND,            T, Legal);
     setOperationAction(ISD::OR,             T, Legal);
     setOperationAction(ISD::XOR,            T, Legal);
@@ -257,6 +258,7 @@ HexagonTargetLowering::initializeHVXLowering() {
     setOperationAction(ISD::STORE,    T, Custom);
     setOperationAction(ISD::MLOAD,    T, Custom);
     setOperationAction(ISD::MSTORE,   T, Custom);
+    setOperationAction(ISD::ABS,      T, Custom);
     setOperationAction(ISD::CTLZ,     T, Custom);
     setOperationAction(ISD::CTTZ,     T, Custom);
     setOperationAction(ISD::CTPOP,    T, Custom);
@@ -2407,6 +2409,7 @@ HexagonTargetLowering::LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const {
         if (ty(Op).getSizeInBits() == ty(Op.getOperand(0)).getSizeInBits())
           return opJoin(SplitVectorOp(Op, DAG), SDLoc(Op), DAG);
         break;
+      case ISD::ABS:
       case ISD::CTPOP:
       case ISD::CTLZ:
       case ISD::CTTZ:
index 6fb1313..119330e 100644 (file)
@@ -879,3 +879,28 @@ let Predicates = [UseHVXV68, UseHVXFloatingPoint] in {
   def: Pat<(VecQ32 (setone HVF32:$Vt, HVF32:$Vu)),
            (V6_pred_not (V6_veqw HvxVR:$Vt, HvxVR:$Vu))>;
 }
+
+let Predicates = [UseHVXV60] in {
+  // V60 doesn't have vabsb or byte shifts.
+  // Do the "mask = x >> width-1; abs = (x + mask) ^ mask" trick.
+  // v31:30.h = vsxt(Inp.b)             ; generate masks in odd bytes in
+  //                                    ; interleaved half-words
+  // v29:28.b = vshuffoe(v31.b,v30.b)   ; collect odd/even bytes, masks = v29
+  // v27.b    = vadd(Inp.b,v29.b)       ; x + masks
+  // Abs      = vxor(v27,v29)           ;   ^ masks
+  def: Pat<(VecI8 (abs HVI8:$Vs)),
+    (V6_vxor HvxVR:$Vs,
+      (V6_vaddb HvxVR:$Vs,
+        (HiVec
+          (V6_vshufoeb
+            (HiVec (V6_vsb HvxVR:$Vs)),
+            (LoVec (V6_vsb HvxVR:$Vs))))))>;
+}
+
+let Predicates = [UseHVXV62], AddedComplexity = 20 in {
+  def: Pat<(VecI8 (abs HVI8:$Vs)), (V6_vabsb HvxVR:$Vs)>;
+}
+
+def: Pat<(VecI16 (abs HVI16:$Vs)), (V6_vabsh HvxVR:$Vs)>;
+def: Pat<(VecI32 (abs HVI32:$Vs)), (V6_vabsw HvxVR:$Vs)>;
+
diff --git a/llvm/test/CodeGen/Hexagon/autohvx/abs.ll b/llvm/test/CodeGen/Hexagon/autohvx/abs.ll
new file mode 100644 (file)
index 0000000..f22537d
--- /dev/null
@@ -0,0 +1,66 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+define <128 x i8> @abs80(<128 x i8> %a0) #0 {
+; CHECK-LABEL: abs80:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    {
+; CHECK-NEXT:     v3:2.h = vsxt(v0.b)
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     v3:2.b = vshuffoe(v3.b,v2.b)
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     v1.b = vadd(v0.b,v3.b)
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     v0 = vxor(v0,v1)
+; CHECK-NEXT:     jumpr r31
+; CHECK-NEXT:    }
+  %v0 = sub <128 x i8> zeroinitializer, %a0
+  %v1 = icmp sgt <128 x i8> %a0, zeroinitializer
+  %v2 = select <128 x i1> %v1, <128 x i8> %a0, <128 x i8> %v0
+  ret <128 x i8> %v2
+}
+
+define <128 x i8> @abs81(<128 x i8> %a0) #1 {
+; CHECK-LABEL: abs81:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    {
+; CHECK-NEXT:     v0.b = vabs(v0.b)
+; CHECK-NEXT:     jumpr r31
+; CHECK-NEXT:    }
+  %v0 = sub <128 x i8> zeroinitializer, %a0
+  %v1 = icmp sgt <128 x i8> %a0, zeroinitializer
+  %v2 = select <128 x i1> %v1, <128 x i8> %a0, <128 x i8> %v0
+  ret <128 x i8> %v2
+}
+
+define <64 x i16> @abs16(<64 x i16> %a0) #0 {
+; CHECK-LABEL: abs16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    {
+; CHECK-NEXT:     v0.h = vabs(v0.h)
+; CHECK-NEXT:     jumpr r31
+; CHECK-NEXT:    }
+  %v0 = sub <64 x i16> zeroinitializer, %a0
+  %v1 = icmp sgt <64 x i16> %a0, zeroinitializer
+  %v2 = select <64 x i1> %v1, <64 x i16> %a0, <64 x i16> %v0
+  ret <64 x i16> %v2
+}
+
+define <32 x i32> @abs32(<32 x i32> %a0) #0 {
+; CHECK-LABEL: abs32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    {
+; CHECK-NEXT:     v0.w = vabs(v0.w)
+; CHECK-NEXT:     jumpr r31
+; CHECK-NEXT:    }
+  %v0 = sub <32 x i32> zeroinitializer, %a0
+  %v1 = icmp sgt <32 x i32> %a0, zeroinitializer
+  %v2 = select <32 x i1> %v1, <32 x i32> %a0, <32 x i32> %v0
+  ret <32 x i32> %v2
+}
+
+attributes #0 = { nounwind readnone "target-features"="+hvxv60,+hvx-length128b" }
+attributes #1 = { nounwind readnone "target-features"="+hvxv62,+hvx-length128b" }