From: Jakub Jelinek Date: Wed, 16 Mar 2016 17:52:20 +0000 (+0100) Subject: re PR middle-end/70245 (Miscompilation of ICU on i386 with atom tuning starting with... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c73d295c48fd246c2fd85827ab798e894f600033;p=gcc.git re PR middle-end/70245 (Miscompilation of ICU on i386 with atom tuning starting with r227382) PR target/70245 * rtlanal.c (replace_rtx): For REG, if from is a REG, return to even if only REGNO is equal, and assert mode is the same. * g++.dg/opt/pr70245.C: New test. * g++.dg/opt/pr70245.h: New file. * g++.dg/opt/pr70245-aux.cc: New file. Co-Authored-By: Richard Biener From-SVN: r234265 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 48941e22bf3..ab80ce4120a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-03-16 Jakub Jelinek + Richard Biener + + PR target/70245 + * rtlanal.c (replace_rtx): For REG, if from is a REG, + return to even if only REGNO is equal, and assert + mode is the same. + 2016-03-11 Jeff Law PR rtl-optimization/70224 diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index bacc5f25f4a..74b593d6935 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -2961,7 +2961,16 @@ replace_rtx (rtx x, rtx from, rtx to) if (x == 0) return 0; - if (GET_CODE (x) == SUBREG) + if (GET_CODE (x) == REG) + { + if (GET_CODE (from) == REG + && REGNO (x) == REGNO (from)) + { + gcc_assert (GET_MODE (x) == GET_MODE (from)); + return to; + } + } + else if (GET_CODE (x) == SUBREG) { rtx new_rtx = replace_rtx (SUBREG_REG (x), from, to); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 76b57ea4880..a215b0ca519 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-03-16 Jakub Jelinek + + PR target/70245 + * g++.dg/opt/pr70245.C: New test. + * g++.dg/opt/pr70245.h: New file. + * g++.dg/opt/pr70245-aux.cc: New file. + 2016-03-16 Martin Sebor * g++.dg/cpp1y/constexpr-instantiate.C: Correct DejaGnu directives. diff --git a/gcc/testsuite/g++.dg/opt/pr70245-aux.cc b/gcc/testsuite/g++.dg/opt/pr70245-aux.cc new file mode 100644 index 00000000000..7f65f20174f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr70245-aux.cc @@ -0,0 +1,56 @@ +// PR target/70245 +// { dg-do compile } +// { dg-options "" } + +#include "pr70245.h" + +D m; +A n, o; +int p, q; + +int * +fn1 (char *x, int *y) +{ + *y = 0; + return &p; +} + +void +fn2 () +{ + __builtin_abort (); +} + +void * +fn3 (int *x) +{ + *x = 0; + return (void *) &m; +} + +void * +fn4 () +{ + a = &o; + o.a1.d = 9; + m.d = sizeof (D); + __builtin_memcpy (o.a2.c, "abcdefghijklmnop", 16); + return (void *) &n; +} + +void +fn5 (A *x, B *y, unsigned char *z, int *w) +{ + if (x != &n || y != &k || z != (unsigned char *) (&m + 1)) + __builtin_abort (); + q++; +} + +int +main () +{ + d = fn5; + baz (0); + if (q != 1) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr70245.C b/gcc/testsuite/g++.dg/opt/pr70245.C new file mode 100644 index 00000000000..21280b7aaf5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr70245.C @@ -0,0 +1,52 @@ +// PR target/70245 +// { dg-do run } +// { dg-additional-sources "pr70245-aux.cc" } +// { dg-options "-O2" } +// { dg-additional-options "-fPIC" { target fpic } } +// { dg-additional-options "-march=i386 -mtune=atom" { target ia32 } } + +#include "pr70245.h" + +struct A *a, *i; +int b, c, e, l; +F d; + +static A * +foo (B *x, int *y, int *z) +{ + unsigned char *f = (unsigned char *) fn3 (y); + D *g = (D *) f; + A *h; + if (e || a || c || b || g->d) + return 0; + h = (A *) fn4 (); + __builtin_memcpy (h, a, sizeof (A)); + h->a1 = *(D *) f; + if (d) + { + d (h, x, f + g->d, z); + if (*z) + fn2 (); + } + return h; +} + +static A * +bar (B *x, int *y) +{ + int *j = fn1 (x->b, y); + if (*y > 0) + return 0; + i = foo (x, j, y); + return i; +} + +B k; + +void +baz (int x) +{ + if (x) + bar (0, 0); + bar (&k, &l); +} diff --git a/gcc/testsuite/g++.dg/opt/pr70245.h b/gcc/testsuite/g++.dg/opt/pr70245.h new file mode 100644 index 00000000000..b0c54064725 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr70245.h @@ -0,0 +1,14 @@ +extern struct A *a, *i; +extern int b, c, e, l; +int *fn1 (char *, int *); +void fn2 (); +void *fn3 (int *); +struct B { char *b; }; +typedef void (*F) (A *, B *, unsigned char *, int *); +struct C { int c[16]; }; +struct D { int d; }; +struct A { D a1; C a2; }; +void *fn4 (); +extern F d; +extern B k; +extern void baz (int);