From 32b38e8972c738b4c8d0bd701d30c0c7daa30dbe Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Thu, 18 Dec 2014 20:49:44 +0000 Subject: [PATCH] re PR rtl-optimization/64291 (Miscompile t-div in GMP's testsuite) 2014-12-18 Vladimir Makarov 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 Vladimir Makarov PR rtl-optimization/64291 * testsuite/gcc.target/i386/pr64291-[12].c: New tests. From-SVN: r218874 --- gcc/ChangeLog | 7 ++++ gcc/lra-remat.c | 21 ++++++---- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/i386/pr64291-1.c | 51 +++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr64291-2.c | 4 ++ 5 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr64291-1.c create mode 100644 gcc/testsuite/gcc.target/i386/pr64291-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6e7cfebb7d9..8c3a610dae3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-12-18 Vladimir Makarov + + 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 * config/i386/i386.c (ix86_expand_call): Skip setting up RAX diff --git a/gcc/lra-remat.c b/gcc/lra-remat.c index 3b8a8069de9..95ed01573fb 100644 --- a/gcc/lra-remat.c +++ b/gcc/lra-remat.c @@ -350,12 +350,12 @@ finish_cand_table (void) -/* 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) { @@ -363,7 +363,7 @@ 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); @@ -406,7 +406,7 @@ operand_to_remat (rtx_insn *insn) 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) @@ -508,11 +508,14 @@ create_cands (void) 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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5ad3d9ab82d..24696e0e67c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-12-18 Vladimir Makarov + + PR rtl-optimization/64291 + * testsuite/gcc.target/i386/pr64291-[12].c: New tests. + 2014-12-18 Paolo Carlini PR c++/60955 diff --git a/gcc/testsuite/gcc.target/i386/pr64291-1.c b/gcc/testsuite/gcc.target/i386/pr64291-1.c new file mode 100644 index 00000000000..85253c0151a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr64291-1.c @@ -0,0 +1,51 @@ +/* { 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; +} diff --git a/gcc/testsuite/gcc.target/i386/pr64291-2.c b/gcc/testsuite/gcc.target/i386/pr64291-2.c new file mode 100644 index 00000000000..2f3f9293cfb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr64291-2.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +extern void abort (void); +void f(void*p,...){} +void g(void*p,long a,long b){if (a!=8) abort();} -- 2.30.2