On Fri, Apr 15, 2011 at 12:33 AM, Camo Johnson <da_cr...@yahoo.de> wrote: > > Hello, > > I'm currently writing a gcc 4.4.5 backend for an 18 bit architecture. > I have a c-project with some thousand lines of code. Without optimizations it > compiles. But with -O1 and -O2 I encounter a problem in the induction > variables > optimization pass. > The main issue is, that a temporary variable is created which works as a > memory > reference but is a 36 bit value (SImode). This results in an error at explow.c > line 326, because pointers have to be 18 bit wide (HImode). > The code at this position is: > > rtx > convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED, rtx x) > { > #ifndef POINTERS_EXTEND_UNSIGNED > gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode); > > This asserts because x has mode SI and to_mode is Pmode/HImode. > > I used the -fdump-tree-all option and in the source.c.126t.final_cleanup file > I > found the following: > > isr00 () > { > unsigned int ivtmp.112; > unsigned int D.3690; > long unsigned int D.3683; > unsigned int ivtmp.105; > unsigned int ivtmp.104; > unsigned int prephitmp.91; > unsigned int length; > unsigned int D.1415; > struct usb * usb0.0; > > … > > <bb 5>: > D.3683 = (long unsigned int) ivtmp.105 + (long unsigned int) ((unsigned int *) > (long unsigned int) usb0.0 + 320); > spi_temporary_data[ivtmp.112] = [bit_and_expr] (unsigned char) (MEM[base: > D.3683] >> 8) & 255; > spi_temporary_data[ivtmp.112 + 1] = [bit_and_expr] (unsigned char) MEM[base: > D.3683] & 255 > > The problem is the D.3683 variable. The casts in the assignment for this > variable are kind of senseless, because ivtmp.105 is unsigned int (18 bit), > usb0.0 is a pointer which is also only 18 bit. > > I checked the source files and I think the main problem is the use of sizetype > in several locations working with addresses. sizetype is defined as long > unsigned int and results in SImode when used. I found 3 code positions with an > input tree mode of HImode where the use of sizetype or size_type_node results > in > a tree node with SImode: > > tree-ssa-address.c line 414 > here parts->index becomes a SImode tree node > > static void > add_to_parts (struct mem_address *parts, tree elt) > { > tree type; > > if (!parts->index) > { > parts->index = fold_convert (sizetype, elt); > return; > } > > tree-ssa-address.c line 547 > here part becomes a SImode tree node > > static void > addr_to_parts (aff_tree *addr, struct mem_address *parts, bool speed) > { > ... > /* Then try to process the remaining elements. */ > for (i = 0; i < addr->n; i++) > { > part = fold_convert (sizetype, addr->elts[i].val); > ... > } > > tree.cline 8332 > here t becomes a SImode tree node > > signed_or_unsigned_type_for (int unsignedp, tree type) > { > tree t = type; > if (POINTER_TYPE_P (type)) > t = size_type_node; > > if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp) > return t; > > return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp); > } > > > > As a solution, I tried to replace those 3 sizetype uses with > global_trees[TI_UINTHI_TYPE]. So the relevant lines look like this: > > parts->index = fold_convert (global_trees[TI_UINTHI_TYPE] /*sizetype*/, elt); > part = fold_convert (global_trees[TI_UINTHI_TYPE] /*sizetype*/, > addr->elts[i].val); > t = global_trees[TI_UINTHI_TYPE] /*size_type_node*/; > > With those changes, the compilation comes farther but crashes on the following > gcc_assert: > tree.cline 3312function build2_stat > > if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt) > gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0)) > && INTEGRAL_TYPE_P (TREE_TYPE (arg1)) > && useless_type_conversion_p (sizetype, TREE_TYPE (arg1))); > > If I comment out the "&& useless_type_conversion_p (sizetype, TREE_TYPE > (arg1))" > part the compilation works. I know its bad, but I don't know how to replace > the > sizetype in this case so that the assert doesn't happen. > > > I'm aware of the fact that those fixes would result in errors with other > architectures. But just for my "strange 18 bit" architecture, is this ok? > Might > there be problems in some cases? Why is sizetype used in this positions > anyways? > Wouldn't it be better to somehow use the input tree type instead of sizetype?
It was a design decision to use sizetype for offsets in pointer arithmetic as this is also how offsets and sizes in types are computed. It is also a known fact that there are various issues with architectures that have a sizetype that is wider or narrower than a pointer. Why can't you make sizetype HImode? > I hope the description of the problem is understandable. > > Regards, > Eric Neumann >