This is a regression introduced in 64-bit mode on the mainline by the switch
to LRA, spotted by Jeff and fixed by Vladimir (much thanks to both).
Tested on SPARC/Solaris, applied on the mainline.
2017-04-19 Eric Botcazou <ebotca...@adacore.com>
Vladimir Makarov <vmaka...@redhat.com>
* config/sparc/predicates.md (input_operand): Add comment. Return
true for any memory operand when LRA is in progress.
* config/sparc/sparc.c (sparc_expand_move): Minor formatting fix.
2017-04-19 Eric Botcazou <ebotca...@adacore.com>
Jeff Law <l...@redhat.com>
* gcc.c-torture/compile/20170419-1.c: New test.
--
Eric Botcazou
Index: config/sparc/predicates.md
===================================================================
--- config/sparc/predicates.md (revision 246960)
+++ config/sparc/predicates.md (working copy)
@@ -373,6 +373,7 @@ (define_predicate "input_operand"
if (TARGET_ARCH32 && mode == DImode && GET_CODE (op) == CONST_INT)
return true;
+ /* Allow FP constants to be built in integer registers. */
if (mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
return true;
@@ -388,7 +389,14 @@ (define_predicate "input_operand"
/* Check for valid MEM forms. */
if (GET_CODE (op) == MEM)
- return memory_address_p (mode, XEXP (op, 0));
+ {
+ /* Except when LRA is precisely working hard to make them valid
+ and relying entirely on the constraints. */
+ if (lra_in_progress)
+ return true;
+
+ return memory_address_p (mode, XEXP (op, 0));
+ }
return false;
})
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c (revision 246960)
+++ config/sparc/sparc.c (working copy)
@@ -1911,9 +1911,8 @@ sparc_expand_move (machine_mode mode, rt
/* We are able to build any SF constant in integer registers
with at most 2 instructions. */
&& (mode == SFmode
- /* And any DF constant in integer registers. */
- || (mode == DFmode
- && ! can_create_pseudo_p ())))
+ /* And any DF constant in integer registers if needed. */
+ || (mode == DFmode && !can_create_pseudo_p ())))
return false;
operands[1] = force_const_mem (mode, operands[1]);
extern int __fpclassifyd (double x);
double fdim (double x, double y)
{
int c = __fpclassifyd (x);
if (c == 0)
return (x);
if (__fpclassifyd (y) == 0)
return (y);
if (c == 1)
return (__builtin_huge_val ());
return x > y ? x - y : 0.0;
}