]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/70460 (Miscompilation of glibc on i686-linux starting with...
authorJakub Jelinek <jakub@redhat.com>
Thu, 31 Mar 2016 13:21:43 +0000 (15:21 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 31 Mar 2016 13:21:43 +0000 (15:21 +0200)
PR rtl-optimization/70460
* ira.c (indirect_jump_optimize): Don't substitute LABEL_REF
with operand from REG_LABEL_OPERAND, instead substitute
SET_SRC or REG_EQUAL note content if it is a LABEL_REF.
Don't do anything for REG_NON_LOCAL_GOTO jumps.

* gcc.c-torture/execute/pr70460.c: New test.

From-SVN: r234618

gcc/ChangeLog
gcc/ira.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr70460.c [new file with mode: 0644]

index b0db665b472bac69180669c965f56f3c0e305732..2d2631c82dba6de4ed9f6e152e4f2f3facab999d 100644 (file)
@@ -1,3 +1,11 @@
+2016-03-31  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/70460
+       * ira.c (indirect_jump_optimize): Don't substitute LABEL_REF
+       with operand from REG_LABEL_OPERAND, instead substitute
+       SET_SRC or REG_EQUAL note content if it is a LABEL_REF.
+       Don't do anything for REG_NON_LOCAL_GOTO jumps.
+
 2016-03-31  Alan Modra  <amodra@gmail.com>
 
        Backport from mainline
index 2c00990ff283568868e9941d393b37a444e94abe..ca1bf38b9e6512b9255c9450549dfb69ea542dac 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3937,7 +3937,8 @@ indirect_jump_optimize (void)
   FOR_EACH_BB_REVERSE_FN (bb, cfun)
     {
       rtx insn = BB_END (bb);
-      if (!JUMP_P (insn))
+      if (!JUMP_P (insn)
+         || find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
        continue;
 
       rtx x = pc_set (insn);
@@ -3951,19 +3952,18 @@ indirect_jump_optimize (void)
          if (!DF_REF_IS_ARTIFICIAL (def))
            {
              rtx def_insn = DF_REF_INSN (def);
-             rtx note = find_reg_note (def_insn, REG_LABEL_OPERAND, NULL_RTX);
-
-             if (note)
+             rtx lab = NULL_RTX;
+             rtx set = single_set (def_insn);
+             if (set && GET_CODE (SET_SRC (set)) == LABEL_REF)
+               lab = SET_SRC (set);
+             else
                {
-                 /* Substitute a LABEL_REF to the label given by the
-                    note rather than using SET_SRC of DEF_INSN.
-                    DEF_INSN might be loading the label constant from
-                    a constant pool, which isn't what we want in a
-                    direct branch.  */
-                 rtx lab = gen_rtx_LABEL_REF (Pmode, XEXP (note, 0));
-                 if (validate_replace_rtx (SET_SRC (x), lab, insn))
-                   rebuild_p = true;
+                 rtx eqnote = find_reg_note (def_insn, REG_EQUAL, NULL_RTX);
+                 if (eqnote && GET_CODE (XEXP (eqnote, 0)) == LABEL_REF)
+                   lab = XEXP (eqnote, 0);
                }
+             if (lab && validate_replace_rtx (SET_SRC (x), lab, insn))
+               rebuild_p = true;
            }
        }
     }
index 0b6ed07609b08f46d5966c3b6e831940d43cb951..c440eae34476e6fabd8a491bdec457e79827827b 100644 (file)
@@ -1,3 +1,8 @@
+2016-03-31  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/70460
+       * gcc.c-torture/execute/pr70460.c: New test.
+
 2016-02-29  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR target/69875
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr70460.c b/gcc/testsuite/gcc.c-torture/execute/pr70460.c
new file mode 100644 (file)
index 0000000..bfecea0
--- /dev/null
@@ -0,0 +1,29 @@
+/* PR rtl-optimization/70460 */
+
+int c;
+
+__attribute__((noinline, noclone)) void
+foo (int x)
+{
+  static int b[] = { &&lab1 - &&lab0, &&lab2 - &&lab0 };
+  void *a = &&lab0 + b[x];
+  goto *a;
+lab1:
+  c += 2;
+lab2:
+  c++;
+lab0:
+  ;
+}
+
+int
+main ()
+{
+  foo (0);
+  if (c != 3)
+    __builtin_abort ();
+  foo (1);
+  if (c != 4)
+    __builtin_abort ();
+  return 0;
+}