https://gcc.gnu.org/g:0bbdffc5d4f723f6a41b713519b156ea46ce5fc8

commit r15-7974-g0bbdffc5d4f723f6a41b713519b156ea46ce5fc8
Author: Andrew Pinski <quic_apin...@quicinc.com>
Date:   Mon Mar 10 23:10:01 2025 -0700

    aarch64: Fix DFP constants [PR119131]
    
    After r15-6660-g45d306a835cb3f865, in some cases
    DFP constants would cause an ICE. This is due to
    do a mismatch of a few things. The predicate of the move
    uses aarch64_valid_fp_move to say if the constant is valid or not.
    But after reload/LRA when can_create_pseudo_p returns false; 
aarch64_valid_fp_move
    would return false for constants that were valid for the constraints
    of the instruction. A strictor predicate compared to the constraint is 
wrong.
    In this case `Uvi` is the constraint while aarch64_valid_fp_move allows it
    via aarch64_can_const_movi_rtx_p for !DECIMAL_FLOAT_MODE_P, there is no 
such check
    for DECIMAL_FLOAT_MODE_P.
    
    The fix is to remove the check !DECIMAL_FLOAT_MODE_P in 
aarch64_valid_fp_move
    and in the define_expand. As now the predicate allows a superset of what is 
allowed
    by the constraints.
    aarch64_float_const_representable_p should be rejecting DFP modes as they 
can't be used
    with instructions like `mov s0, 1.0`.
    
    Changes since v1:
    * v2: Add check to aarch64_float_const_representable_p for DFP.
    
    Built and tested on aarch64-linux-gnu with no regressions.
    
            PR target/119131
    
    gcc/ChangeLog:
    
            * config/aarch64/aarch64.cc (aarch64_valid_fp_move): Remove check
            for !DECIMAL_FLOAT_MODE_P.
            (aarch64_float_const_representable_p): Reject decimal floating 
modes.
            * config/aarch64/aarch64.md (mov<mode>): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/pr119131-1.c: New test.
    
    Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>

Diff:
---
 gcc/config/aarch64/aarch64.cc             | 21 +++++++++++----------
 gcc/config/aarch64/aarch64.md             |  3 +--
 gcc/testsuite/gcc.dg/torture/pr119131-1.c | 31 +++++++++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 36b65df50c57..41054b54b383 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -11328,17 +11328,14 @@ aarch64_valid_fp_move (rtx dst, rtx src, machine_mode 
mode)
   if (MEM_P (src))
     return true;
 
-  if (!DECIMAL_FLOAT_MODE_P (mode))
-    {
-      if (aarch64_can_const_movi_rtx_p (src, mode)
-         || aarch64_float_const_representable_p (src)
-         || aarch64_float_const_zero_rtx_p (src))
-       return true;
+  if (aarch64_can_const_movi_rtx_p (src, mode)
+      || aarch64_float_const_representable_p (src)
+      || aarch64_float_const_zero_rtx_p (src))
+    return true;
 
-      /* Block FP immediates which are split during expand.  */
-      if (aarch64_float_const_rtx_p (src))
-       return false;
-    }
+  /* Block FP immediates which are split during expand.  */
+  if (aarch64_float_const_rtx_p (src))
+    return false;
 
   return can_create_pseudo_p ();
 }
@@ -25611,6 +25608,10 @@ aarch64_float_const_representable_p (rtx x)
 {
   x = unwrap_const_vec_duplicate (x);
   machine_mode mode = GET_MODE (x);
+
+  if (DECIMAL_FLOAT_MODE_P (mode))
+    return false;
+
   if (!CONST_DOUBLE_P (x))
     return false;
 
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 03188a64ab17..031e621c98a1 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1762,8 +1762,7 @@
              && aarch64_float_const_zero_rtx_p (operands[1])))
       operands[1] = force_reg (<MODE>mode, operands[1]);
 
-    if (!DECIMAL_FLOAT_MODE_P (<MODE>mode)
-       && GET_CODE (operands[1]) == CONST_DOUBLE
+    if (GET_CODE (operands[1]) == CONST_DOUBLE
        && can_create_pseudo_p ()
        && !aarch64_can_const_movi_rtx_p (operands[1], <MODE>mode)
        && !aarch64_float_const_representable_p (operands[1])
diff --git a/gcc/testsuite/gcc.dg/torture/pr119131-1.c 
b/gcc/testsuite/gcc.dg/torture/pr119131-1.c
new file mode 100644
index 000000000000..c62f702f98c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr119131-1.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target dfp } */
+/* PR target/119131 */
+
+typedef __attribute__((__vector_size__ (64))) char C;
+typedef __attribute__((__vector_size__ (64))) _Decimal32 D;
+int a, b;
+_Decimal32 f;
+C e;
+C c;
+
+void
+foo (D d)
+{
+  d -= *(_Decimal32 *) __builtin_memset (&f, 0, 4);
+  b += a;
+  if (a)
+    b /= 0; /* { dg-warning "division by zero" } */
+  c = (C) d + e;
+}
+
+void
+foo1 (D d)
+{
+  __builtin_memset (&f, 0, 4);
+  d -= *(_Decimal32 *)&f;
+  b += a;
+  if (a)
+    b /= 0;/* { dg-warning "division by zero" } */
+  c = (C) d + e;
+}

Reply via email to