diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-05-17 17:32:50 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-05-17 17:32:50 +0200 |
commit | 07b5d54c9074c902e47f7f3b7f92d3ca540d8fdc (patch) | |
tree | 2fb4ea4adfb26ac3284ac3d647b485a077682d1d | |
parent | 1acc4169f868d25fcec45925a36b4931ec61efc0 (diff) | |
download | gcc-07b5d54c9074c902e47f7f3b7f92d3ca540d8fdc.zip gcc-07b5d54c9074c902e47f7f3b7f92d3ca540d8fdc.tar.gz gcc-07b5d54c9074c902e47f7f3b7f92d3ca540d8fdc.tar.bz2 |
re PR rtl-optimization/57281 (x86_64-linux loop fails to terminate at -O3 -m32)
PR rtl-optimization/57281
PR rtl-optimization/57300
* config/i386/i386.md (extendsidi2_1 dead reg splitter): Remove.
(extendsidi2_1 peephole2s): Add instead 2 new peephole2s, that undo
what the other splitter did if the registers are dead.
* gcc.dg/pr57300.c: New test.
* gcc.c-torture/execute/pr57281.c: New test.
From-SVN: r199021
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 56 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr57281.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr57300.c | 21 |
5 files changed, 101 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8dfc0ce..98ce704 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-05-17 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/57281 + PR rtl-optimization/57300 + * config/i386/i386.md (extendsidi2_1 dead reg splitter): Remove. + (extendsidi2_1 peephole2s): Add instead 2 new peephole2s, that undo + what the other splitter did if the registers are dead. + 2013-05-17 Uros Bizjak <ubizjak@gmail.com> Backport from mainline diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2e450e3..455fb63 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3647,22 +3647,8 @@ "!TARGET_64BIT" "#") -;; Extend to memory case when source register does die. -(define_split - [(set (match_operand:DI 0 "memory_operand") - (sign_extend:DI (match_operand:SI 1 "register_operand"))) - (clobber (reg:CC FLAGS_REG)) - (clobber (match_operand:SI 2 "register_operand"))] - "(reload_completed - && dead_or_set_p (insn, operands[1]) - && !reg_mentioned_p (operands[1], operands[0]))" - [(set (match_dup 3) (match_dup 1)) - (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) - (clobber (reg:CC FLAGS_REG))]) - (set (match_dup 4) (match_dup 1))] - "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") - -;; Extend to memory case when source register does not die. +;; Split the memory case. If the source register doesn't die, it will stay +;; this way, if it does die, following peephole2s take care of it. (define_split [(set (match_operand:DI 0 "memory_operand") (sign_extend:DI (match_operand:SI 1 "register_operand"))) @@ -3691,6 +3677,44 @@ DONE; }) +;; Peepholes for the case where the source register does die, after +;; being split with the above splitter. +(define_peephole2 + [(set (match_operand:SI 0 "memory_operand") + (match_operand:SI 1 "register_operand")) + (set (match_operand:SI 2 "register_operand") (match_dup 1)) + (parallel [(set (match_dup 2) + (ashiftrt:SI (match_dup 2) (const_int 31))) + (clobber (reg:CC FLAGS_REG))]) + (set (match_operand:SI 3 "memory_operand") (match_dup 2))] + "REGNO (operands[1]) != REGNO (operands[2]) + && peep2_reg_dead_p (2, operands[1]) + && peep2_reg_dead_p (4, operands[2]) + && !reg_mentioned_p (operands[2], operands[3])" + [(set (match_dup 0) (match_dup 1)) + (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) + (clobber (reg:CC FLAGS_REG))]) + (set (match_dup 3) (match_dup 1))]) + +(define_peephole2 + [(set (match_operand:SI 0 "memory_operand") + (match_operand:SI 1 "register_operand")) + (parallel [(set (match_operand:SI 2 "register_operand") + (ashiftrt:SI (match_dup 1) (const_int 31))) + (clobber (reg:CC FLAGS_REG))]) + (set (match_operand:SI 3 "memory_operand") (match_dup 2))] + "/* cltd is shorter than sarl $31, %eax */ + !optimize_function_for_size_p (cfun) + && true_regnum (operands[1]) == AX_REG + && true_regnum (operands[2]) == DX_REG + && peep2_reg_dead_p (2, operands[1]) + && peep2_reg_dead_p (3, operands[2]) + && !reg_mentioned_p (operands[2], operands[3])" + [(set (match_dup 0) (match_dup 1)) + (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) + (clobber (reg:CC FLAGS_REG))]) + (set (match_dup 3) (match_dup 1))]) + ;; Extend to register case. Optimize case where source and destination ;; registers match and cases where we can use cltd. (define_split diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7f55104..21f4b5d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2013-05-17 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/57281 + PR rtl-optimization/57300 + * gcc.dg/pr57300.c: New test. + * gcc.c-torture/execute/pr57281.c: New test. + 2013-05-16 Dodji Seketeli <dodji@redhat.com> PR c++/56782 - Regression with empty pack expansions diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57281.c b/gcc/testsuite/gcc.c-torture/execute/pr57281.c new file mode 100644 index 0000000..db3db10 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr57281.c @@ -0,0 +1,25 @@ +/* PR rtl-optimization/57281 */ + +int a = 1, b, d, *e = &d; +long long c, *g = &c; +volatile long long f; + +int +foo (int h) +{ + int j = *g = b; + return h == 0 ? j : 0; +} + +int +main () +{ + int h = a; + for (; b != -20; b--) + { + (int) f; + *e = 0; + *e = foo (h); + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr57300.c b/gcc/testsuite/gcc.dg/pr57300.c new file mode 100644 index 0000000..13a272d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr57300.c @@ -0,0 +1,21 @@ +/* PR rtl-optimization/57300 */ +/* { dg-do run } */ +/* { dg-options "-O3" } */ +/* { dg-additional-options "-msse2" { target sse2_runtime } } */ + +extern void abort (void); +int a, b, d[10]; +long long c; + +int +main () +{ + int e; + for (e = 0; e < 10; e++) + d[e] = 1; + if (d[0]) + c = a = (b == 0 || 1 % b); + if (a != 1) + abort (); + return 0; +} |