https://gcc.gnu.org/g:182f0056f5c137213eef3ba70f5ad885ddc55f9a

commit r17-2532-g182f0056f5c137213eef3ba70f5ad885ddc55f9a
Author: Philipp Tomsich <[email protected]>
Date:   Sun Jul 19 18:26:41 2026 +0200

    match.pd: Make the (trunc)copysign(extend x, extend y) vector-safe 
[PR126291]
    
    The (convert (copysigns (convert@2 @0) (convert @1))) rules evaluate
    TYPE_PRECISION on the outer and inner types after only types_match, so
    a vectorized copysign chain like
    
      vect_1 = (vector(2) float) vect_0;
      vect_2 = (vector(2) float) vect_3;
      vect_4 = .COPYSIGN (vect_1, vect_2);
      vect_5 = (vector(2) double) vect_4;
    
    trips the vector_type tree check while gimple_simplify evaluates the
    guard (the ICE does not require the precision test to hold: evaluating
    TYPE_PRECISION on a vector type is what triggers it).
    
    Use element_precision, mirroring the abs fix.  No equivalent of the
    target_supports_op_p check is needed here, since the existing
    direct_internal_fn_supported_p guard already handles vector types
    correctly.
    The REAL_CST variant cannot match vectors (a vector constant is a
    VECTOR_CST), but is converted as well for consistency.
    
    Bootstrapped and regtested on x86_64-pc-linux-gnu.
    
            PR tree-optimization/126291
    
    gcc/ChangeLog:
    
            * match.pd ((trunc)copysign ((extend)x, (extend)y) -> copysign
            (x, y), (trunc)copysign ((extend)x, CST) -> copysign (x, CST)):
            Use element_precision.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/pr126291-2.c: New test.

Diff:
---
 gcc/match.pd                                  |  4 ++--
 gcc/testsuite/gcc.target/aarch64/pr126291-2.c | 10 ++++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index b3738fdde1da..cfb43202e762 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -9518,7 +9518,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && !HONOR_SNANS (@2)
        && types_match (type, TREE_TYPE (@0))
        && types_match (type, TREE_TYPE (@1))
-       && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (@2))
+       && element_precision (type) < element_precision (TREE_TYPE (@2))
        && direct_internal_fn_supported_p (IFN_COPYSIGN,
                                          type, OPTIMIZE_FOR_BOTH))
     (IFN_COPYSIGN @0 @1)))
@@ -9528,7 +9528,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (if (optimize
        && !HONOR_SNANS (@2)
        && types_match (type, TREE_TYPE (@0))
-       && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (@2))
+       && element_precision (type) < element_precision (TREE_TYPE (@2))
        && direct_internal_fn_supported_p (IFN_COPYSIGN,
                                          type, OPTIMIZE_FOR_BOTH))
     (if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (@1)))
diff --git a/gcc/testsuite/gcc.target/aarch64/pr126291-2.c 
b/gcc/testsuite/gcc.target/aarch64/pr126291-2.c
new file mode 100644
index 000000000000..dc5edfaaaab2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr126291-2.c
@@ -0,0 +1,10 @@
+/* PR tree-optimization/126291 */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+void
+f (double *restrict out, const double *x, const double *y, long n)
+{
+  for (long i = 0; i < n; i++)
+    out[i] = __builtin_copysignf ((float) x[i], (float) y[i]);
+}

Reply via email to