From 6a78e6da102f3dcf7f2fd98443f93f0dc361063d Mon Sep 17 00:00:00 2001
From: Kugan <kvivekanada@nvidia.com>
Date: Sun, 21 Jul 2024 16:22:17 +0530
Subject: [PATCH] abshalffloat[v6]

gcc/ChangeLog:

        * match.pd: Extend A CMP 0 ? A : -A into (type)A CMP 0 ? A : -A.
        Extend A CMP 0 ? A : -A into (type) A CMP 0 ? A : -A.

gcc/testsuite/ChangeLog:

        * g++.dg/absvect.C: New test.
        * gcc.dg/tree-ssa/absfloat16.c: New test.

Signed-off-by: Kugan Vivekanandarajah <kvivekananda@nvidia.com>
---
 gcc/match.pd                               | 77 ++++++++++++++++------
 gcc/testsuite/g++.dg/absvect.C             | 12 ++++
 gcc/testsuite/gcc.dg/tree-ssa/absfloat16.c | 14 ++++
 3 files changed, 82 insertions(+), 21 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/absvect.C
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/absfloat16.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 99968d316ed..fbb0f1ecb63 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6122,31 +6122,66 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	 && bitwise_equal_p (@0, @1))
      @1))
  )
- /* A >=/> 0 ? A : -A    same as abs (A) */
+ /* (type)A >=/> 0 ? A : -A    same as abs (A) */
  (for cmp (ge gt)
   (simplify
-   (cnd (cmp @0 zerop) @1 (negate @1))
-    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
-	 && !TYPE_UNSIGNED (TREE_TYPE(@0))
-	 && bitwise_equal_p (@0, @1))
-     (if (TYPE_UNSIGNED (type))
-      (absu:type @0)
-      (abs @0)))))
- /* A <=/< 0 ? A : -A    same as -abs (A) */
+   (cnd (cmp (convert?@0 @1) zerop) @2 (negate @2))
+    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE (@1))
+	 /* Support SEXT of @0 only.  */
+	 && !TYPE_UNSIGNED (TREE_TYPE (@1))
+	 && element_precision (TREE_TYPE (@1))
+		<= element_precision (TREE_TYPE (@0))
+	 && bitwise_equal_p (@1, @2))
+     (with {
+       tree stype = signed_type_for (TREE_TYPE (@2));
+      }
+      /* Handle nop convert first to prevent additional
+         convertion.  */
+      (if (INTEGRAL_TYPE_P (type)
+           && element_precision (TREE_TYPE (@1))
+	       == element_precision (TREE_TYPE (@0)))
+       (if (TYPE_UNSIGNED (type))
+	 (absu:type @0)
+	 (abs @0))
+       (if (TYPE_UNSIGNED (type))
+        (if (TYPE_UNSIGNED (TREE_TYPE (@2)))
+	 (absu (convert:stype @2))
+	 (absu @2))
+        (if (TYPE_UNSIGNED (TREE_TYPE (@2)))
+	 (abs (convert:stype @2))
+	 (abs @2)))))))
+ )
+ /* (type)A <=/< 0 ? A : -A    same as -abs (A) */
  (for cmp (le lt)
   (simplify
-   (cnd (cmp @0 zerop) @1 (negate @1))
-    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
-	 && !TYPE_UNSIGNED (TREE_TYPE(@0))
-	 && bitwise_equal_p (@0, @1))
-     (if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
-	   && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
-	  || TYPE_UNSIGNED (type))
-      (with {
-	tree utype = unsigned_type_for (TREE_TYPE(@0));
-       }
-       (convert (negate (absu:utype @0))))
-       (negate (abs @0)))))
+   (cnd (cmp (convert?@0 @1) zerop) @2 (negate @2))
+    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE (@1))
+	 /* Support SEXT of @0 only.  */
+	 && !TYPE_UNSIGNED (TREE_TYPE (@1))
+	 && element_precision (TREE_TYPE (@1))
+		<= element_precision (TREE_TYPE (@0))
+	 && bitwise_equal_p (@1, @2))
+     (with {
+       tree stype = signed_type_for (TREE_TYPE (@2));
+       tree utype = unsigned_type_for (TREE_TYPE (@1));
+      }
+      (if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (@1))
+	      && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
+	    || TYPE_UNSIGNED (type))
+       (if (TYPE_UNSIGNED (TREE_TYPE (@2)))
+	 (convert (negate (absu:utype (convert:stype @2))))
+	 (convert (negate (absu:utype @2))))
+       /* Handle nop convert first to prevent additional
+          convertion.  */
+       (if (INTEGRAL_TYPE_P (type)
+            && element_precision (TREE_TYPE (@1))
+	       == element_precision (TREE_TYPE (@0)))
+        (if (TYPE_UNSIGNED (type))
+         (convert (negate (absu:utype @0)))
+         (negate (abs @0)))
+        (if (TYPE_UNSIGNED (TREE_TYPE (@2)))
+         (negate (abs (convert:stype @2)))
+         (negate (abs @2))))))))
  )
 
  /* (A - B) == 0 ? (A - B) : (B - A)    same as (B - A) */
diff --git a/gcc/testsuite/g++.dg/absvect.C b/gcc/testsuite/g++.dg/absvect.C
new file mode 100644
index 00000000000..5cf2ca307f4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/absvect.C
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-phiopt1" } */
+/* { dg-final { scan-tree-dump-times " = ABS_EXPR <x_\[0-9]*\\\(D\\\)>;" 1 "phiopt1" } } */
+
+typedef int v2si __attribute__ ((vector_size (2 * sizeof(int))));
+typedef short v2hi __attribute__ ((vector_size (2 * sizeof(short))));
+
+v2hi  absvect1 (v2hi x, int i) {
+    v2hi neg = -x;
+    return (x > 0) ? x : neg;
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/absfloat16.c b/gcc/testsuite/gcc.dg/tree-ssa/absfloat16.c
new file mode 100644
index 00000000000..a417fe281a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/absfloat16.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-add-options float16 } */
+/* { dg-require-effective-target float16 } */
+/* { dg-options "-Ofast -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " = ABS_EXPR <x_\[0-9]*\\\(D\\\)>;" 1 "optimized" } } */
+
+_Float16  absfloat16(_Float16 x) {
+    if (x < 0.0f) {
+        return -x;
+    } else {
+        return x;
+    }
+}
+
-- 
2.43.2

