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; +}