From 80ab32d69e5c426612def4f77107383a7928ff55 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 3 Nov 2010 09:30:21 +0100 Subject: [PATCH] re PR rtl-optimization/46034 (internal compiler error: segmentation fault) PR rtl-optimization/46034 PR rtl-optimization/46212 PR rtl-optimization/46248 * combine.c (try_combine): If added_sets_2 where i0dest_in_i0src and i0 feeds i1 and i1 feeds i2 or i0 feeds i2, make a copy of i1src before i0dest -> i0src substitution and pass 1 instead of 0 as last argument to subst on i2pat. * gcc.c-torture/compile/pr46034.c: New test. * gcc.c-torture/compile/pr46248.c: New test. * gcc.dg/pr46212.c: New test. From-SVN: r166231 --- gcc/ChangeLog | 10 ++++++ gcc/combine.c | 13 +++++--- gcc/testsuite/ChangeLog | 9 ++++++ gcc/testsuite/gcc.c-torture/compile/pr46034.c | 14 ++++++++ gcc/testsuite/gcc.c-torture/compile/pr46248.c | 32 +++++++++++++++++++ gcc/testsuite/gcc.dg/pr46212.c | 23 +++++++++++++ 6 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr46034.c create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr46248.c create mode 100644 gcc/testsuite/gcc.dg/pr46212.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd97bd9d348..2ccafe18338 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2010-11-03 Jakub Jelinek + + PR rtl-optimization/46034 + PR rtl-optimization/46212 + PR rtl-optimization/46248 + * combine.c (try_combine): If added_sets_2 where i0dest_in_i0src + and i0 feeds i1 and i1 feeds i2 or i0 feeds i2, make a copy of i1src + before i0dest -> i0src substitution and pass 1 instead of 0 as last + argument to subst on i2pat. + 2010-11-02 Ian Lance Taylor * configure.ac: Use AC_SYS_LARGEFILE. diff --git a/gcc/combine.c b/gcc/combine.c index 88b3ca5e15f..3bf65698185 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -2502,6 +2502,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p) rtx i3dest_killed = 0; /* SET_DEST and SET_SRC of I2, I1 and I0. */ rtx i2dest = 0, i2src = 0, i1dest = 0, i1src = 0, i0dest = 0, i0src = 0; + rtx i1src_copy = 0; /* Set if I2DEST was reused as a scratch register. */ bool i2scratch = false; /* The PATTERNs of I0, I1, and I2, or a copy of them in certain cases. */ @@ -3128,6 +3129,11 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p) return 0; } + /* Following subst may modify i1src, make a copy of it + before it is for added_sets_2 handling if needed. */ + if (i0_feeds_i1_n && added_sets_2 && i1_feeds_i2_n) + i1src_copy = copy_rtx (i1src); + n_occurrences = 0; subst_low_luid = DF_INSN_LUID (i0); newpat = subst (newpat, i0dest, i0src, 0, @@ -3200,11 +3206,10 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p) if (added_sets_2) { rtx t = i2pat; - if (i0_feeds_i2_n) - t = subst (t, i0dest, i0src, 0, 0); if (i1_feeds_i2_n) - t = subst (t, i1dest, i1src, 0, 0); - if (i0_feeds_i1_n && i1_feeds_i2_n) + t = subst (t, i1dest, i1src_copy ? i1src_copy : i1src, 0, + i0_feeds_i1_n && i0dest_in_i0src); + if ((i0_feeds_i1_n && i1_feeds_i2_n) || i0_feeds_i2_n) t = subst (t, i0dest, i0src, 0, 0); XVECEXP (newpat, 0, --total_sets) = t; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 87da982a36d..439dd5ccc51 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2010-11-03 Jakub Jelinek + + PR rtl-optimization/46034 + PR rtl-optimization/46212 + PR rtl-optimization/46248 + * gcc.c-torture/compile/pr46034.c: New test. + * gcc.c-torture/compile/pr46248.c: New test. + * gcc.dg/pr46212.c: New test. + 2010-11-02 Eric Botcazou * gnat.dg/sizetype4.adb: New test. diff --git a/gcc/testsuite/gcc.c-torture/compile/pr46034.c b/gcc/testsuite/gcc.c-torture/compile/pr46034.c new file mode 100644 index 00000000000..02eda0572e4 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr46034.c @@ -0,0 +1,14 @@ +/* PR rtl-optimization/46034 */ + +void bar (int); + +void +foo (int x, int y) +{ + int i; + for (i = 0; i < x; i++) + { + y = __builtin_abs (y); + bar (y / 2); + } +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr46248.c b/gcc/testsuite/gcc.c-torture/compile/pr46248.c new file mode 100644 index 00000000000..6d3be2a6545 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr46248.c @@ -0,0 +1,32 @@ +/* PR rtl-optimization/46248 */ + +struct S +{ + int s; +}; + +void +foo (unsigned char *x, int y, struct S *z) +{ + const int l1 = y; + const int l2 = y + l1; + const int l3 = y + l2; + const int l4 = y + l3; + const int l5 = y + l4; + const int l6 = y + l5; + const int l7 = y + l6; + int i; + for (i = 0; i < 8; i++) + { + int a = x[l3] - x[l4]; + int b = x[l4] - x[l5]; + int c = x[l5] - x[l6]; + int d = (b >= 0 ? b : -b) - (((a >= 0 ? a : -a) + (c >= 0 ? c : -c)) >> 1); + if (d < z->s * 2) + { + int v = d * (-b > 0 ? 1 : -1); + x[l2] += v >> 3; + x[l7] -= v >> 3; + } + } +} diff --git a/gcc/testsuite/gcc.dg/pr46212.c b/gcc/testsuite/gcc.dg/pr46212.c new file mode 100644 index 00000000000..9dbb601e026 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr46212.c @@ -0,0 +1,23 @@ +/* PR rtl-optimization/46212 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -funroll-loops" } */ +/* { dg-options "-O3 -funroll-loops -march=i386" { target { { i686-*-* x86_64-*-* } && ilp32 } } } */ + +static inline unsigned +foo (void *x) +{ + unsigned y = *(volatile unsigned *) (x); + return (y >> 24) | ((y >> 8) & 0xff00) | ((y & 0xff00) << 8) | (y << 24); +} + +void +bar (void *x, void *y, int z) +{ + unsigned c; + while (z--) + { + c = foo (y); + *(unsigned *) x = (c & 0xf80000) >> 9 | (c & 0xf800) >> 6 + | (c & 0xf8) >> 3 | (c & 0x80000000) >> 16; + } +}