https://gcc.gnu.org/g:8ca429aeafc2afc569900a00e77068c5e39985cb
commit r14-12661-g8ca429aeafc2afc569900a00e77068c5e39985cb Author: Richard Biener <[email protected]> Date: Wed Mar 18 10:15:00 2026 +0100 tree-optimization/124555 - guard abs patterns for vector support The following adds missing vector support checks to abs producing match.pd patterns. The g++.dg/absvect.C shows that we previously then lowered this to non-vector unless you add -msse4 on x86_64 at least. PR tree-optimization/124555 * match.pd ((A - B) >=/> 0 ? (A - B) : (B - A) -> abs (A - B)): Guard the vector case with target_supports_op_p checks. ((A - B) <=/< 0 ? (A - B) : (B - A) -> -abs (A - B)): Likewise. ((type)A >=/> 0 ? A : -A -> abs (A)): Likewise. ((type)A <=/< 0 ? A : -A -> -abs (A)): Likewise. * gcc.dg/torture/pr124555.c: New testcase. * g++.dg/absvect.C: Restrict dump scan to x86-64 and force -msse4 there. (cherry picked from commit c97e6d7be7d51cd812b2acde680cd9704bae3c70) Diff: --- gcc/match.pd | 17 +++++++++++++---- gcc/testsuite/g++.dg/absvect.C | 13 +++++++++++++ gcc/testsuite/gcc.dg/torture/pr124555.c | 25 +++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index 2d19f6472be5..d1b11483520e 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -5960,7 +5960,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (cnd (cmp @0 zerop) @1 (negate @1)) (if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0)) && !TYPE_UNSIGNED (TREE_TYPE(@0)) - && bitwise_equal_p (@0, @1)) + && bitwise_equal_p (@0, @1) + && (!VECTOR_TYPE_P (type) + || target_supports_op_p (type, ABS_EXPR, optab_vector))) (if (TYPE_UNSIGNED (type)) (absu:type @0) (abs @0))))) @@ -5970,7 +5972,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (cnd (cmp @0 zerop) @1 (negate @1)) (if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0)) && !TYPE_UNSIGNED (TREE_TYPE(@0)) - && bitwise_equal_p (@0, @1)) + && bitwise_equal_p (@0, @1) + && (!VECTOR_TYPE_P (type) + || target_supports_op_p (type, ABS_EXPR, optab_vector))) (if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))) || TYPE_UNSIGNED (type)) @@ -6006,7 +6010,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (cnd (cmp (minus@0 @1 @2) zerop) @0 (minus @2 @1)) (if (!HONOR_SIGNED_ZEROS (type) - && !TYPE_UNSIGNED (type)) + && !TYPE_UNSIGNED (type) + && (!VECTOR_TYPE_P (type) + || target_supports_op_p (type, ABS_EXPR, optab_vector))) (abs @0)))) /* (A - B) <=/< 0 ? (A - B) : (B - A) same as -abs (A - B) */ (for cmp (le lt) @@ -6015,7 +6021,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (!HONOR_SIGNED_ZEROS (type) && !TYPE_UNSIGNED (type)) (if (ANY_INTEGRAL_TYPE_P (type) - && !TYPE_OVERFLOW_WRAPS (type)) + && !TYPE_OVERFLOW_WRAPS (type) + && (!VECTOR_TYPE_P (type) + || (target_supports_op_p (type, ABS_EXPR, optab_vector) + && target_supports_op_p (type, NEGATE_EXPR, optab_vector)))) (with { tree utype = unsigned_type_for (type); } diff --git a/gcc/testsuite/g++.dg/absvect.C b/gcc/testsuite/g++.dg/absvect.C new file mode 100644 index 000000000000..d28ea846d74d --- /dev/null +++ b/gcc/testsuite/g++.dg/absvect.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -fdump-tree-phiopt1" } */ +/* { dg-additional-options "-msse4" { target { x86_64-*-* i?86-*-* } } } */ +/* { dg-final { scan-tree-dump-times " = ABS_EXPR <x_\[0-9]*\\\(D\\\)>;" 1 "phiopt1" { target { x86_64-*-* i?86-*-* } } } } */ + +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/torture/pr124555.c b/gcc/testsuite/gcc.dg/torture/pr124555.c new file mode 100644 index 000000000000..668ad7b904ba --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr124555.c @@ -0,0 +1,25 @@ +/* { dg-additional-options "-fwrapv" } */ + +int vsad8_c_y; +char *vsad8_c_s1, *vsad8_c_s2; +long vsad8_c_stride; +int vsad8_c() +{ + int score, x; + for (; vsad8_c_y; vsad8_c_y++) + { + x = 0; + for (; x < 8; x++) + score += (vsad8_c_s1[x] - vsad8_c_s2[x] - vsad8_c_s1[x + vsad8_c_stride] + + vsad8_c_s2[x + vsad8_c_stride]) >= 0 + ? vsad8_c_s1[x] - vsad8_c_s2[x] - + vsad8_c_s1[x + vsad8_c_stride] + + vsad8_c_s2[x + vsad8_c_stride] + : -(vsad8_c_s1[x] - vsad8_c_s2[x] - + vsad8_c_s1[x + vsad8_c_stride] + + vsad8_c_s2[x + vsad8_c_stride]); + vsad8_c_s1 += vsad8_c_stride; + vsad8_c_s2 += vsad8_c_stride; + } + return score; +}
