Files
gcc48/gcc48-bnc970009.patch

177 lines
5.4 KiB
Diff
Raw Permalink Normal View History

r208204, fixes ICE on aarch64 building samba
also includes r203498 touching the same code
together fix PR52714 and PR58662
2014-02-27 Jeff Law <law@redhat.com>
PR rtl-optimization/52714
* combine.c (try_combine): When splitting an unrecognized PARALLEL
into two independent simple sets, if I3 is a jump, ensure the
pattern we place into I3 is a (set (pc) ...)
2014-02-27 Jeff Law <law@redhat.com>
PR rtl-optimization/52714
* gcc.c-torture/compile/pr52714.c: New test.
2013-10-13 Eric Botcazou <ebotcazou@adacore.com>
PR rtl-optimization/58662
* combine.c (try_combine): Take into account death nodes on I2 when
splitting a PARALLEL of two independent SETs. Fix dump message.
2013-10-13 Richard Biener <rguenther@suse.de>
* gcc.c-torture/execute/pr58662.c: New test.
Index: gcc/combine.c
===================================================================
--- gcc/combine.c (revision 234060)
+++ gcc/combine.c (working copy)
@@ -3697,29 +3697,48 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
&& ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0)))
&& contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1)))))
{
+ rtx set0 = XVECEXP (newpat, 0, 0);
+ rtx set1 = XVECEXP (newpat, 0, 1);
+
/* Normally, it doesn't matter which of the two is done first,
but the one that references cc0 can't be the second, and
one which uses any regs/memory set in between i2 and i3 can't
- be first. */
- if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
- DF_INSN_LUID (i2))
+ be first. The PARALLEL might also have been pre-existing in i3,
+ so we need to make sure that we won't wrongly hoist a SET to i2
+ that would conflict with a death note present in there. */
+ if (!use_crosses_set_p (SET_SRC (set1), DF_INSN_LUID (i2))
+ && !(REG_P (SET_DEST (set1))
+ && find_reg_note (i2, REG_DEAD, SET_DEST (set1)))
+ && !(GET_CODE (SET_DEST (set1)) == SUBREG
+ && find_reg_note (i2, REG_DEAD,
+ SUBREG_REG (SET_DEST (set1))))
#ifdef HAVE_cc0
- && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0))
+ && !reg_referenced_p (cc0_rtx, set0)
#endif
+ /* If I3 is a jump, ensure that set0 is a jump so that
+ we do not create invalid RTL. */
+ && (!JUMP_P (i3) || SET_DEST (set0) == pc_rtx)
)
{
- newi2pat = XVECEXP (newpat, 0, 1);
- newpat = XVECEXP (newpat, 0, 0);
+ newi2pat = set1;
+ newpat = set0;
}
- else if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 0)),
- DF_INSN_LUID (i2))
+ else if (!use_crosses_set_p (SET_SRC (set0), DF_INSN_LUID (i2))
+ && !(REG_P (SET_DEST (set0))
+ && find_reg_note (i2, REG_DEAD, SET_DEST (set0)))
+ && !(GET_CODE (SET_DEST (set0)) == SUBREG
+ && find_reg_note (i2, REG_DEAD,
+ SUBREG_REG (SET_DEST (set0))))
#ifdef HAVE_cc0
- && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 1))
+ && !reg_referenced_p (cc0_rtx, set1)
#endif
+ /* If I3 is a jump, ensure that set1 is a jump so that
+ we do not create invalid RTL. */
+ && (!JUMP_P (i3) || SET_DEST (set1) == pc_rtx)
)
{
- newi2pat = XVECEXP (newpat, 0, 0);
- newpat = XVECEXP (newpat, 0, 1);
+ newi2pat = set0;
+ newpat = set1;
}
else
{
@@ -4271,9 +4290,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
}
/* Update reg_stat[].nonzero_bits et al for any changes that may have
- been made to this insn. The order of
- set_nonzero_bits_and_sign_copies() is important. Because newi2pat
- can affect nonzero_bits of newpat */
+ been made to this insn. The order is important, because newi2pat
+ can affect nonzero_bits of newpat. */
if (newi2pat)
note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
@@ -4293,7 +4311,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
{
if (dump_file)
{
- fprintf (dump_file, "modifying insn i1 ");
+ fprintf (dump_file, "modifying insn i0 ");
dump_insn_slim (dump_file, i0);
}
df_insn_rescan (i0);
@@ -4331,7 +4349,6 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
/* Set new_direct_jump_p if a new return or simple jump instruction
has been created. Adjust the CFG accordingly. */
-
if (returnjump_p (i3) || any_uncondjump_p (i3))
{
*new_direct_jump_p = 1;
Index: gcc/testsuite/gcc.c-torture/compile/pr52714.c
===================================================================
--- gcc/testsuite/gcc.c-torture/compile/pr52714.c (revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr52714.c (working copy)
@@ -0,0 +1,25 @@
+
+int __re_compile_fastmap(unsigned char *p)
+{
+ unsigned char **stack;
+ unsigned size;
+ unsigned avail;
+
+ stack = __builtin_alloca(5 * sizeof(unsigned char*));
+ if (stack == 0)
+ return -2;
+ size = 5;
+ avail = 0;
+
+ for (;;) {
+ switch (*p++) {
+ case 0:
+ if (avail == size)
+ return -2;
+ stack[avail++] = p;
+ }
+ }
+
+ return 0;
+}
+
Index: gcc/testsuite/gcc.c-torture/execute/pr58662.c
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/pr58662.c (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr58662.c (working copy)
@@ -0,0 +1,22 @@
+extern void abort (void);
+
+int a, c, d;
+volatile int b;
+
+static int
+foo (int p1, short p2)
+{
+ return p1 / p2;
+}
+
+int
+main ()
+{
+ char e;
+ d = foo (a == 0, (0, 35536));
+ e = d % 14;
+ b = e && c;
+ if (b != 0)
+ abort ();
+ return 0;
+}