On Fri, Mar 8, 2013 at 3:19 PM, Richard Biener <richard.guent...@gmail.com> wrote: > 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 first conversion expands to (symbol_ref:HI ("__c.1466") [flags 0x202] <var_decl 0x7ffff6dfaa18 __c>) then we try to convert that to another address-space and the target hook returns (insn 6 0 7 (set (reg/f:HI 46) (symbol_ref:HI ("__c.1466") [flags 0x202] <var_decl 0x7ffff6dfaa18 __c>)) t.c:18 -1 (nil)) (insn 7 6 0 (set (reg:PSI 45) (zero_extend:PSI (reg/f:HI 46))) t.c:18 -1 (nil)) (reg:PSI 45) so the issue must be elsewhere (in case the above is correct). -mstrict-addr-space-subsets doesn't exist for me. Richard. >> the incoming "node" in build1_stat has already arg 1 <integer_cst constant 0> >> >> Thanks. >> >> Johann >>