diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-02-04 13:14:52 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-02-04 13:14:52 +0100 |
commit | be3afd67464ec5430d72971991e9cbbaa7cd4370 (patch) | |
tree | 42139a9e9fb7794f1b0595094fa65ed385e9a0c6 /gcc | |
parent | 81c87471e9ed4952d63477644b1843a42fd1fbb3 (diff) | |
download | gcc-be3afd67464ec5430d72971991e9cbbaa7cd4370.zip gcc-be3afd67464ec5430d72971991e9cbbaa7cd4370.tar.gz gcc-be3afd67464ec5430d72971991e9cbbaa7cd4370.tar.bz2 |
re PR rtl-optimization/57915 (ICE in set_address_disp, at rtlanal.c:5537)
PR rtl-optimization/57915
* recog.c (simplify_while_replacing): If all unary/binary/relational
operation arguments are constant, attempt to simplify those.
* gcc.target/i386/pr57915.c: New test.
From-SVN: r207460
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/recog.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr57915.c | 33 |
4 files changed, 72 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5487d5c..41fc977 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2014-02-04 Jakub Jelinek <jakub@redhat.com> + PR rtl-optimization/57915 + * recog.c (simplify_while_replacing): If all unary/binary/relational + operation arguments are constant, attempt to simplify those. + PR middle-end/59261 * expmed.c (expand_mult): For MODE_VECTOR_INT multiplication if there is no vashl<mode>3 or ashl<mode>3 insn, skip_synth. diff --git a/gcc/recog.c b/gcc/recog.c index e2caf9859..f9040dc 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -565,7 +565,7 @@ simplify_while_replacing (rtx *loc, rtx to, rtx object, { rtx x = *loc; enum rtx_code code = GET_CODE (x); - rtx new_rtx; + rtx new_rtx = NULL_RTX; if (SWAPPABLE_OPERANDS_P (x) && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1))) @@ -579,6 +579,35 @@ simplify_while_replacing (rtx *loc, rtx to, rtx object, code = GET_CODE (x); } + /* Canonicalize arithmetics with all constant operands. */ + switch (GET_RTX_CLASS (code)) + { + case RTX_UNARY: + if (CONSTANT_P (XEXP (x, 0))) + new_rtx = simplify_unary_operation (code, GET_MODE (x), XEXP (x, 0), + op0_mode); + break; + case RTX_COMM_ARITH: + case RTX_BIN_ARITH: + if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1))) + new_rtx = simplify_binary_operation (code, GET_MODE (x), XEXP (x, 0), + XEXP (x, 1)); + break; + case RTX_COMPARE: + case RTX_COMM_COMPARE: + if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1))) + new_rtx = simplify_relational_operation (code, GET_MODE (x), op0_mode, + XEXP (x, 0), XEXP (x, 1)); + break; + default: + break; + } + if (new_rtx) + { + validate_change (object, loc, new_rtx, 1); + return; + } + switch (code) { case PLUS: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5ba47ab..31e271d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-02-04 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/57915 + * gcc.target/i386/pr57915.c: New test. + 2014-02-04 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * g++.dg/init/dso_handle2.C: Compile with -fuse-cxa-atexit. diff --git a/gcc/testsuite/gcc.target/i386/pr57915.c b/gcc/testsuite/gcc.target/i386/pr57915.c new file mode 100644 index 0000000..0b143e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr57915.c @@ -0,0 +1,33 @@ +/* PR rtl-optimization/57915 */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ + +extern struct T { char a[8]; char b[16]; } t; +int c; +void foo (void); + +extern inline char * +baz (char *x, const char *y) +{ + const char *e = y; + unsigned long f, g; + asm ("" : "+c" (f), "+D" (e) : "a" ('\0'), "X" (*e)); + g = e - 1 - y; + __builtin_memcpy (x, y, g); + x[g] = '\0'; + return x; +} + +void +bar (void) +{ + char d[16]; + baz (d, t.b); + + for (;;) + { + foo (); + if (c) + baz (d, t.b); + } +} |