+2014-12-18 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/64291
+ * lra-remat.c (bad_for_rematerialization_p): Add UNPSEC_VLOATILE.
+ (create_cands): Process only output reload insn with potential
+ cands.
+
2014-12-18 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (ix86_expand_call): Skip setting up RAX
\f
-/* Return true if X contains memory or UNSPEC. We can not just check
- insn operands as memory or unspec might be not an operand itself
- but contain an operand. Insn with memory access is not profitable
- for rematerialization. Rematerialization of UNSPEC might result in
- wrong code generation as the UNPEC effect is unknown
- (e.g. generating a label). */
+/* Return true if X contains memory or some UNSPEC. We can not just
+ check insn operands as memory or unspec might be not an operand
+ itself but contain an operand. Insn with memory access is not
+ profitable for rematerialization. Rematerialization of UNSPEC
+ might result in wrong code generation as the UNPEC effect is
+ unknown (e.g. generating a label). */
static bool
bad_for_rematerialization_p (rtx x)
{
const char *fmt;
enum rtx_code code;
- if (MEM_P (x) || GET_CODE (x) == UNSPEC)
+ if (MEM_P (x) || GET_CODE (x) == UNSPEC || GET_CODE (x) == UNSPEC_VOLATILE)
return true;
code = GET_CODE (x);
fmt = GET_RTX_FORMAT (code);
if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed)
return -1;
else if (reg->type == OP_OUT && ! reg->subreg_p
- && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL)
+ && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL)
{
/* We permits only one spilled reg. */
if (found_reg != NULL)
if ((set = single_set (insn)) != NULL
&& REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))
- && (src_regno = REGNO (SET_SRC (set))) >= FIRST_PSEUDO_REGISTER
+ && ((src_regno = REGNO (SET_SRC (set)))
+ >= lra_constraint_new_regno_start)
&& (dst_regno = REGNO (SET_DEST (set))) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[dst_regno] < 0
&& (insn2 = regno_potential_cand[src_regno].insn) != NULL
&& BLOCK_FOR_INSN (insn2) == BLOCK_FOR_INSN (insn))
+ /* It is an output reload insn after insn can be
+ rematerialized (potential candidate). */
create_cand (insn2, regno_potential_cand[src_regno].nop, dst_regno);
if (nop < 0)
goto fail;
--- /dev/null
+/* { dg-options "-O2" } */
+/* { dg-additional-sources pr64291-2.c } */
+/* { dg-do run } */
+void f(void*,...);
+void g(void*,long,long);
+int nnn=0;
+long test=0;
+
+typedef struct
+{
+ int _mp_size;
+ unsigned long *_mp_d;
+} __mpz_struct;
+typedef __mpz_struct mpz_t[1];
+
+int main ()
+{
+ mpz_t n, d;
+ long nn, dn;
+ unsigned long *np, *dup, *dnp, *qp;
+ long alloc, itch;
+
+ f (n);
+ f (d);
+ qp = (unsigned long*)__builtin_alloca(4099*8) + 1;
+ dnp = (unsigned long*)__builtin_alloca (2049*8);
+ alloc = 1;
+ for (test = 0; test < 1; test++)
+ {
+ dn = d->_mp_size;
+ dup = d->_mp_d;
+ f (dnp, dup, dn);
+ dnp[dn - 1] |= 1UL<<63;
+ f (0);
+ nn = nnn;
+ np = n->_mp_d;
+ qp[-1] = -757136820;
+ qp[nn - dn + 1] = 14883681;
+ f (0);
+ if (dn >= 6)
+ f (0);
+ itch = nn + 1;
+ if (itch + 1> alloc)
+ {
+ g(0,alloc*8,(itch+1)*8);
+ alloc = itch + 1;
+ }
+ f (np, nn);
+ }
+ return 0;
+}