Following test case produces incorrect PHI functions in pacc_ch, when compiled with tree-ssa compiler with -O1 on ppc-darwin. This prevents gap of the SPEC benchmark to build correctly with -O1 and higher optimizations. typedef struct TypHeader { unsigned long size; struct TypHeader * * ptr; } * TypHandle; TypHandle gorf (unsigned long h, unsigned long k, TypHandle hdRes, TypHandle hdTmp) { while ( hdTmp < ((hdRes)->ptr)[k-h] ) { ((hdRes)->ptr)[k] = ((hdRes)->ptr)[k-h]; k = k-h; } return hdRes; } gorf (h, k, hdRes, hdTmp) { struct TypHeader * * T.8; struct TypHeader * * T.7; long unsigned int T.6; struct TypHeader * T.5; struct TypHeader * * T.4; struct TypHeader * * T.3; long unsigned int T.2; long unsigned int T.1; struct TypHeader * * T.0; # BLOCK 0 # PRED: ENTRY (fallthru) T.0<D1054>_26 = hdRes<D1048>_3->ptr; T.1<D1055>_27 = k<D1047>_2 - h<D1046>_5; T.2<D1056>_28 = T.1<D1055>_27 * 4; T.3<D1057>_29 = (struct TypHeader * *)T.2<D1056>_28; T.4<D1058>_30 = T.0<D1054>_26 + T.3<D1057>_29; T.5<D1059>_31 = *T.4<D1058>_30; if (T.5<D1059>_31 > hdTmp<D1049>_11) goto <L0>; else goto <L2>; # SUCC: 1 (true) 2 (false) # BLOCK 1 # PRED: 0 (true) 1 (true) # T.3<D1057>_25 = PHI <T.3<D1057>_29(0), T.3<D1057>_40(1)>; # T.1<D1055>_24 = PHI <T.1<D1055>_27(0), T.1<D1055>_38(1)>; # k<D1047>_1 = PHI <k<D1047>_2(0), k<D1047>_36(1)>; <L0>:; T.0<D1054>_32 = hdRes<D1048>_3->ptr; T.6<D1061>_14 = k<D1047>_1 * 4; T.7<D1062>_15 = (struct TypHeader * *)T.6<D1061>_14; T.8<D1063>_16 = T.0<D1054>_32 + T.7<D1062>_15; T.0<D1054>_33 = hdRes<D1048>_3->ptr; T.4<D1058>_34 = T.0<D1054>_33 + T.3<D1057>_25; T.5<D1059>_35 = *T.4<D1058>_34; *T.8<D1063>_16 = T.5<D1059>_35; k<D1047>_36 = T.1<D1055>_24; T.0<D1054>_37 = hdRes<D1048>_3->ptr; T.1<D1055>_38 = k<D1047>_36 - h<D1046>_5; T.2<D1056>_39 = T.1<D1055>_38 * 4; T.3<D1057>_40 = (struct TypHeader * *)T.2<D1056>_39; T.4<D1058>_41 = T.0<D1054>_37 + T.3<D1057>_40; T.5<D1059>_42 = *T.4<D1058>_41; if (T.5<D1059>_42 > hdTmp<D1049>_11) goto <L0>; else goto <L2>; # SUCC: 2 (false) 1 (true) # BLOCK 2 # PRED: 0 (false) 1 (false) <L2>:; return hdRes<D1048>_3; # SUCC: EXIT } 2004-02-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> ... * tree-optimize.c (init_tree_optimization_passes): Add pass_ch. * tree-pass.h (pass_ch): Declare. * tree-ssa-loop.c: Include tree-inline.h. (call_expr_p, should_duplicate_loop_header_p, mark_defs_for_rewrite, duplicate_blocks, copy_loop_headers, gate_ch): New functions. (pass_ch): New. ... - fariborz (fjahanian@apple.com)
Here is an executable test case: typedef struct TypHeader { unsigned long size; struct TypHeader * * ptr; } * TypHandle; void gorf (unsigned long h, unsigned long k, TypHandle hdRes, TypHandle hdTmp) { while ( hdTmp < ((hdRes)->ptr)[k-h] ) { ((hdRes)->ptr)[k] = ((hdRes)->ptr)[k-h]; k = k-h; } } int main() { int i; struct TypHeader* arrTypHeader[6]; TypHandle hdTmp; struct TypHeader hd; hd.ptr = arrTypHeader; for (i=0; i < 6; i++) { arrTypHeader[i] = (struct TypHeader*)malloc(sizeof(struct TypHeader)); arrTypHeader[i]->size = i; } gorf(1, 5, &hd, arrTypHeader[0]); for (i=0; i < 6; i++) { printf(" size = %d\n", arrTypHeader[i]->size); } return 0; } Compiled with -O0 produces following results: size = 0 size = 1 size = 1 size = 2 size = 3 size = 4 Compiled with -O1 produces incorrect results: size = 0 size = 1 size = 2 size = 3 size = 4 size = 5
Actually the PHI functions from tree copy header are fine, the real issue is that copyrename is renaming a variable to one which is set also through the loop. I found this seeing that copyrename2 was messing up the trees.
The problem was caused by PRE not knowing that the two PHI's were in fact different so it was choosing the wrong one. See <http://gcc.gnu.org/ml/gcc-bugs/2004-03/msg01821.html>.
Subject: Bug 14562 CVSROOT: /cvs/gcc Module name: gcc Branch: tree-ssa-20020619-branch Changes by: dberlin@gcc.gnu.org 2004-03-16 15:59:30 Modified files: gcc : ChangeLog.tree-ssa tree-ssa-pre.c Log message: 2004-03-16 Daniel Berlin <dberlin@dberlin.org> PR optimization/14562 * tree-ssa-pre.c (generate_expr_as_of_bb): Don't use names_match_p. (generate_vops_as_of_bb): Ditto. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.tree-ssa.diff?cvsroot=gcc&only_with_tag=tree-ssa-20020619-branch&r1=1.1.2.1272&r2=1.1.2.1273 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa-pre.c.diff?cvsroot=gcc&only_with_tag=tree-ssa-20020619-branch&r1=1.1.4.132&r2=1.1.4.133
Fixed