------- Additional Comments From rakdver at atrey dot karlin dot mff dot cuni dot cz 2005-03-29 21:09 ------- Subject: Re: [4.0/4.1 regression] ivopts produces code that generates "unaligned access exception"
> > This most likely can be reproduced on ia64 too and other targets where > > alignment is needed for some > > loads. > > > > The tree which we produce looks like: > > <bb 0>: > > if (p->c[0] != 0) goto <L0>; else goto <L2>; > > > > <L0>:; > > D.1133 = *((unsigned char *) p + 5B); > > p = p + 1B; > > if (D.1133 != 0) goto <L0>; else goto <L2>; > > The problem seems to be that the expansion assumes that p must be > aligned. Which seems to be reasonable. I will try making ivopts > produce all pointer ivs in (void *) type, that should hopefully > help. This patch should fix the problem (I have looked on crosscompiler output only, so I am not entirely sure yet). Index: tree-ssa-loop-ivopts.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v retrieving revision 2.54 diff -c -3 -p -r2.54 tree-ssa-loop-ivopts.c *** tree-ssa-loop-ivopts.c 22 Mar 2005 22:08:53 -0000 2.54 --- tree-ssa-loop-ivopts.c 29 Mar 2005 21:07:33 -0000 *************** strip_offset (tree expr, bool inside_add *** 1840,1845 **** --- 1840,1861 ---- return fold_convert (orig_type, expr); } + /* Returns variant of TYPE that can be used as base for different uses. + For integer types, we return unsigned variant of the type, which + avoids problems with overflows. For pointer types, we return void *. */ + + static tree + generic_type_for (tree type) + { + if (POINTER_TYPE_P (type)) + return ptr_type_node; + + if (TYPE_UNSIGNED (type)) + return type; + + return unsigned_type_for (type); + } + /* Adds a candidate BASE + STEP * i. Important field is set to IMPORTANT and position to POS. If USE is not NULL, the candidate is set as related to it. If both BASE and STEP are NULL, we add a pseudocandidate for the *************** add_candidate_1 (struct ivopts_data *dat *** 1852,1865 **** { unsigned i; struct iv_cand *cand = NULL; ! tree type; if (base) { ! type = TREE_TYPE (base); ! if (!TYPE_UNSIGNED (type)) { - type = unsigned_type_for (type); base = fold_convert (type, base); if (step) step = fold_convert (type, step); --- 1868,1881 ---- { unsigned i; struct iv_cand *cand = NULL; ! tree type, orig_type; if (base) { ! orig_type = TREE_TYPE (base); ! type = generic_type_for (orig_type); ! if (type != orig_type) { base = fold_convert (type, base); if (step) step = fold_convert (type, step); -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20625