https://gcc.gnu.org/g:454371d850797600872e20da9464504cb80b0788
commit r15-3887-g454371d850797600872e20da9464504cb80b0788 Author: Kugan Vivekanandarajah <kvivekana...@nvidia.com> Date: Thu Sep 26 15:56:06 2024 +1000 [match.pd] Handle abs pattern with convert 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 <kvivekana...@nvidia.com> Diff: --- gcc/match.pd | 56 +++++++++++++++++++----------- gcc/testsuite/g++.dg/absvect.C | 12 +++++++ gcc/testsuite/gcc.dg/tree-ssa/absfloat16.c | 14 ++++++++ 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index ca48c47fcc4e..e06a812e9766 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6467,31 +6467,45 @@ 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))))) + (if (types_match (@0, stype)) + (absu @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 (@2)) + && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (@2))) + || TYPE_UNSIGNED (TREE_TYPE (@2))) + (with { + tree stype = signed_type_for (TREE_TYPE (@2)); + tree utype = unsigned_type_for (TREE_TYPE (@2)); + } + (if (types_match (@0, stype)) + (convert (negate (absu:utype @0))) + (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 000000000000..5cf2ca307f43 --- /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 000000000000..a417fe281a90 --- /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; + } +} +