On Fri, Mar 8, 2013 at 2:57 PM, Georg-Johann Lay <a...@gjlay.de> wrote: > While implementing PR56263 (Strict address-space checking for AVR), I > encountered the problem that pointer casts with address spaces are always > expanded as const_int 0. > > The problem occurs if the attached patch that implements PR56263 and the > following code is compiled as > > $ avr-gcc -Os flash-cast.c -S -mstrict-addr-space-subsets > > > #define PROGMEM __attribute__((__progmem__)) > > #define PSTR(s) \ > (__extension__ \ > ({ \ > static const char __c[] PROGMEM = (s); \ > &__c[0]; \ > })) > > extern void print (const __memx char*, ...); > > const __flash char *p; > > void f (const char *c) > { > c = (const char*) p; > > print ((const __flash char*) PSTR ("Hallo flash")); > } > > > > The corresponding .expand dump reads: > > > f (const char * c) > { > static const char __c[12] = "Hallo flash"; > const <address-space-1> char * _2; > const <address-space-7> char * _3; > > ;; basic block 2, loop depth 0 > ;; pred: ENTRY > _2 = (const <address-space-1> char *) (&__c[0]); > _3 = (const <address-space-7> char *) _2; > print (_3); [tail call] > return; > ;; succ: EXIT > > } > > > but the expression is always emit as (const_int 0). > > > Trying to track this issue, I ended up in build1_stat which enters the default > case for "code" (ADDR_SPACE_CONVERT_EXPR at that time) and returns the > following tree: > > > (gdb) p t > $62 = (tree) 0xb7bb4578 > (gdb) pt > <addr_space_convert_expr 0xb7bb4578 > type <pointer_type 0xb7bc3a80 > type <integer_type 0xb7bc3a20 char readonly sizes-gimplified > address-space-1 string-flag QI > size <integer_cst 0xb7b3a1a4 constant 8> > unit size <integer_cst 0xb7b3a1b8 constant 1> > align 8 symtab 0 alias set -1 canonical type 0xb7bc3a20 precision > 8 > min <integer_cst 0xb7b3a1e0 -128> max <integer_cst 0xb7b3a208 127> > pointer_to_this <pointer_type 0xb7bc3a80>> > unsigned HI > size <integer_cst 0xb7b3a08c constant 16> > unit size <integer_cst 0xb7b3a0a0 constant 2> > align 8 symtab 0 alias set -1 canonical type 0xb7bc3a80> > readonly constant > arg 0 <addr_expr 0xb7bb449c > type <pointer_type 0xb7b4f2a0 type <integer_type 0xb7b4f240 char> > public unsigned HI size <integer_cst 0xb7b3a08c 16> unit size > <integer_cst 0xb7b3a0a0 2> > align 8 symtab 0 alias set -1 canonical type 0xb7b4f2a0 > pointer_to_this <pointer_type 0xb7b4f840>> > readonly constant > arg 0 <array_ref 0xb7b465a0 type <integer_type 0xb7b4f240 char> > readonly arg 0 <var_decl 0xb7bcd05c __c> > arg 1 <integer_cst 0xb7b3a460 constant 0> > flash-cast.c:18:128> > flash-cast.c:18:124>> > > Problem is the arg 1 <integer_cst 0xb7b3a460 constant 0> at the end which > leads > to the expansion of 0. > > The call chain is: > > #0 build1_stat (code=ADDR_SPACE_CONVERT_EXPR, type=0xb7bc3a80, > node=0xb7bb449c) at ../../../gcc.gnu.org/trunk/gcc/tree.c:3848 > (gdb) bt > #0 build1_stat (code=ADDR_SPACE_CONVERT_EXPR, type=0xb7bc3a80, > node=0xb7bb449c) at ../../../gcc.gnu.org/trunk/gcc/tree.c:3848 > #1 0x08286be0 in gimple_assign_rhs_to_tree (stmt=0xb7bc2c30) at > ../../../gcc.gnu.org/trunk/gcc/cfgexpand.c:86 > #2 0x0837047f in expand_expr_real_1 (exp=0xb7b972f8, target=0x0, > tmode=VOIDmode, modifier=EXPAND_STACK_PARM, alt_rtl=0x0) at > ../../../gcc.gnu.org/trunk/gcc/expr.c:9274 > #3 0x083762f2 in expand_expr_real (exp=0xb7b972f8, target=0x0, > tmode=VOIDmode, > modifier=EXPAND_STACK_PARM, alt_rtl=0x0) at > ../../../gcc.gnu.org/trunk/gcc/expr.c:7863 > #4 0x08376a7e in expand_expr (exp=0xb7b972f8, target=0x0, mode=VOIDmode, > modifier=EXPAND_STACK_PARM) at ../../../gcc.gnu.org/trunk/gcc/expr.h:444 > #5 0x0836ae96 in expand_expr_real_2 (ops=0xbfffca10, target=0x0, > tmode=VOIDmode, modifier=EXPAND_STACK_PARM) at > ../../../gcc.gnu.org/trunk/gcc/expr.c:8150 > #6 0x08376234 in expand_expr_real_1 (exp=0xb7bb4564, target=0x0, > tmode=VOIDmode, modifier=EXPAND_STACK_PARM, alt_rtl=0x0) at > ../../../gcc.gnu.org/trunk/gcc/expr.c:10491 > #7 0x083762f2 in expand_expr_real (exp=0xb7bb4564, target=0x0, > tmode=VOIDmode, > modifier=EXPAND_STACK_PARM, alt_rtl=0x0) at > ../../../gcc.gnu.org/trunk/gcc/expr.c:7863 > #8 0x083704a6 in expand_expr_real_1 (exp=0xb7b97320, target=0x0, > tmode=VOIDmode, modifier=EXPAND_STACK_PARM, alt_rtl=0x0) at > ../../../gcc.gnu.org/trunk/gcc/expr.c:9274 > #9 0x083762f2 in expand_expr_real (exp=0xb7b97320, target=0x0, > tmode=VOIDmode, > modifier=EXPAND_STACK_PARM, alt_rtl=0x0) at > ../../../gcc.gnu.org/trunk/gcc/expr.c:7863 > #10 0x0826ae1a in expand_expr (exp=0xb7b97320, target=0x0, mode=VOIDmode, > modifier=EXPAND_STACK_PARM) at ../../../gcc.gnu.org/trunk/gcc/expr.h:444 > #11 0x0826c215 in store_one_arg (arg=0xbfffd130, argblock=0x0, flags=0, > variable_size=0, reg_parm_stack_space=0) at > ../../../gcc.gnu.org/trunk/gcc/calls.c:4500 > #12 0x08274d79 in expand_call (exp=0xb7b46640, target=0x0, ignore=1) at > ../../../gcc.gnu.org/trunk/gcc/calls.c:3040 > #13 0x08375088 in expand_expr_real_1 (exp=0xb7b46640, target=0x0, > tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0) at > ../../../gcc.gnu.org/trunk/gcc/expr.c:10209 > #14 0x0828cb86 in expand_call_stmt (stmt=0xb7fde140) at > ../../../gcc.gnu.org/trunk/gcc/cfgexpand.c:2114 > > ... > > > The problem comes apparent in #5 expand_expr_real_2 > > if (targetm.addr_space.subset_p (as_to, as_from) > || targetm.addr_space.subset_p (as_from, as_to)) > { > op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier); > op0 = targetm.addr_space.convert (op0, treeop0_type, type); > gcc_assert (op0); > return op0; > } > > where op0 is const0_rtx and targetm.addr_space.convert cannot recover from > that. > > Maybe someone can help me fixing the root cause?
Doesn't make sense - in the above code treeop0 should be the arg 0 <addr_expr 0xb7bb449c not the zero integer constant. > the incoming "node" in build1_stat has already arg 1 <integer_cst constant 0> > > Thanks. > > Johann >