re PR rtl-optimization/64291 (Miscompile t-div in GMP's testsuite)
authorVladimir Makarov <vmakarov@redhat.com>
Thu, 18 Dec 2014 20:49:44 +0000 (20:49 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Thu, 18 Dec 2014 20:49:44 +0000 (20:49 +0000)
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  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/64291
* testsuite/gcc.target/i386/pr64291-[12].c: New tests.

From-SVN: r218874

gcc/ChangeLog
gcc/lra-remat.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr64291-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr64291-2.c [new file with mode: 0644]

index 6e7cfebb7d9508f712eeef43d592059b86764c43..8c3a610dae3ebaa805eef0efb45405c29316ab46 100644 (file)
@@ -1,3 +1,10 @@
+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
index 3b8a8069de9d85976a843fcfb1d81046ecbb883b..95ed01573fb4ae62cd4784f4cf14b5fbfa63cd5a 100644 (file)
@@ -350,12 +350,12 @@ finish_cand_table (void)
 
 \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)
 {
@@ -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;
index 5ad3d9ab82d91d2359374ee1c10ca5e48930f054..24696e0e67c9a5b3ce2d792bd266d709e2aea1cb 100644 (file)
@@ -1,3 +1,8 @@
+2014-12-18  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/64291
+       * testsuite/gcc.target/i386/pr64291-[12].c: New tests.
+
 2014-12-18  Paolo Carlini  <paolo.carlini@oracle.com>
 
        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 (file)
index 0000000..85253c0
--- /dev/null
@@ -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 (file)
index 0000000..2f3f929
--- /dev/null
@@ -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();}