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>
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 ();
}
{
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;
&& 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])
--- /dev/null
+/* { 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;
+}