From f5b39c33b6171afc2cb1373cbab6ef93c1b5348e 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.
	* gcc.dg/tree-ssa/phi-opt-37.c: Check phiopt2 dump.

Signed-off-by: Kugan Vivekanandarajah <kvivekananda@nvidia.com>
---
 gcc/match.pd                               | 52 +++++++++++++---------
 gcc/testsuite/g++.dg/absvect.C             | 12 +++++
 gcc/testsuite/gcc.dg/tree-ssa/absfloat16.c | 14 ++++++
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c |  6 +--
 4 files changed, 60 insertions(+), 24 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..72cbf73d443 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6122,31 +6122,41 @@ 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) */
- (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))
+   (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 (@1)
+             <= element_precision (@0)
+        && bitwise_equal_p (@1, @2))
+    (if (TYPE_UNSIGNED (TREE_TYPE (@2)))
       (with {
-	tree utype = unsigned_type_for (TREE_TYPE(@0));
+        tree stype = signed_type_for (TREE_TYPE (@2));
        }
-       (convert (negate (absu:utype @0))))
-       (negate (abs @0)))))
+      (absu (convert:stype @2)))
+      (abs @2)))))
+ /* (type)A <=/< 0 ? A : -A    same as -abs (A) */
+ (for cmp (le lt)
+  (simplify
+   (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 (@1)
+	      <= element_precision (@0)
+	 && bitwise_equal_p (@1, @2))
+      (if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (@1))
+	      && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
+	    || TYPE_UNSIGNED (TREE_TYPE(@2)))
+	(with {
+	  tree stype = signed_type_for (TREE_TYPE (@2));
+	  tree utype = unsigned_type_for (TREE_TYPE (@1));
+	 }
+	(convert (negate (absu:utype (convert:stype @2)))))
+	(convert (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;
+    }
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c
index f1ff472aaff..bac316527ac 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-phiopt1" } */
+/* { dg-options "-O1 -fdump-tree-phiopt2" } */
 
 unsigned abs_with_convert0 (int x)
 {
@@ -20,5 +20,5 @@ unsigned abs_with_convert1 (unsigned x)
   return x;
 }
 
-/* { dg-final { scan-tree-dump-times "ABSU_EXPR <"  2  "phiopt1" } } */
-/* { dg-final { scan-tree-dump-not   "if "        "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times "ABSU_EXPR <"  2  "phiopt2" } } */
+/* { dg-final { scan-tree-dump-not   "if "        "phiopt2" } } */
-- 
2.43.2

