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_apinski@quicinc.com>
This commit is contained in:
Andrew Pinski 2025-03-10 23:10:01 -07:00
parent 17ef5cad94
commit 0bbdffc5d4
3 changed files with 43 additions and 12 deletions

View file

@ -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;

View file

@ -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])

View file

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