Consider: int foo (int *array) { if (array[1] != 0) return array[1]; return 0; } Here is the result after the first DCE, which is immediately after FRE. foo (array) { int D.1134; int D.1133; int * D.1132; <bb 0>: D.1132_3 = array_2 + 4B; D.1133_4 = *D.1132_3; if (D.1133_4 != 0) goto <L0>; else goto <L2>; <L0>:; D.1132_7 = D.1132_3; D.1134_8 = *D.1132_7; # D.1134_1 = PHI <D.1134_8(1), 0(0)>; <L2>:; return D.1134_1; } Note that the second load still stays there. If I run copy-prop and FRE one more time immediately after running them for the first time, then the second run of FRE can remove the redundant load. By running the copy prop one more time, the second load becomes: D.1134_8 = *D.1132_3; Then then I guess it's easy for FRE to eliminate this load because RHS looks exactly like the first load.
Confirmed.
Before FRE. (That is, the result of copyprop) foo (array) { int D.1134; int D.1133; int * D.1132; <bb 0>: D.1132_3 = array_2 + 4B; # VUSE <TMT.0_9>; D.1133_4 = *D.1132_3; if (D.1133_4 != 0) goto <L0>; else goto <L1>; <L0>:; D.1132_7 = array_2 + 4B; # VUSE <TMT.0_9>; D.1134_8 = *D.1132_7; goto <bb 3> (<L2>); <L1>:; D.1134_6 = 0; # D.1134_1 = PHI <D.1134_8(1), 0(2)>; <L2>:; return D.1134_1; } After FRE. foo (array) { int D.1134; int D.1133; int * D.1132; <bb 0>: D.1132_3 = array_2 + 4B; # VUSE <TMT.0_9>; D.1133_4 = *D.1132_3; if (D.1133_4 != 0) goto <L0>; else goto <L1>; <L0>:; D.1132_7 = D.1132_3; # VUSE <TMT.0_9>; D.1134_8 = *D.1132_7; goto <bb 3> (<L2>); <L1>:; D.1134_6 = 0; # D.1134_1 = PHI <D.1134_8(1), 0(2)>; <L2>:; return D.1134_1; }
I have a patch for this that solves it. Waiting for TCB merge to post
Subject: Bug 20703 CVSROOT: /cvs/gcc Module name: gcc Changes by: dberlin@gcc.gnu.org 2005-04-04 19:02:18 Modified files: gcc : ChangeLog tree-ssa-pre.c gcc/testsuite/gcc.dg/tree-ssa: ssa-pre-1.c ssa-pre-2.c ssa-pre-3.c ssa-pre-4.c ssa-pre-5.c ssa-pre-6.c Added files: gcc/testsuite/gcc.dg/tree-ssa: ssa-pre-7.c ssa-pre-8.c Log message: 2005-04-02 Daniel Berlin <dberlin@dberlin.org> Diego Novillo <dnovillo@redhat.com> Fix PR tree-optimization/20703 Fix PR tree-optimization/20725 * tree-ssa-pre.c (phi_translate): Handle tcc_comparison. (create_expression_by_pieces): Ditto. (valid_in_set): Ditto. Also handle tcc_declaration. (find_or_generate_expression): Handle comparison class. (insert_into_preds_of_block): Ditto. (insert_aux): Ditto. (create_value_expr_from): Handle comparison class, recursively handle reference nodes. (compute_avail): Handle comparison classes, rewrite a little cleaner. (execute_pre): Fix spacing. (do_fre): Renamed to execute_fre. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.8122&r2=2.8123 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa-pre.c.diff?cvsroot=gcc&r1=2.72&r2=2.73 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-7.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-8.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-1.c.diff?cvsroot=gcc&r1=1.5&r2=1.6 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-2.c.diff?cvsroot=gcc&r1=1.4&r2=1.5 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-3.c.diff?cvsroot=gcc&r1=1.2&r2=1.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-4.c.diff?cvsroot=gcc&r1=1.2&r2=1.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-5.c.diff?cvsroot=gcc&r1=1.2&r2=1.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-6.c.diff?cvsroot=gcc&r1=1.2&r2=1.3
Fixed