https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66768
--- Comment #5 from amker at gcc dot gnu.org --- I can reproduce the problem on avr using its namespace with GCC trunk. The example code is as below: typedef __memx struct foo_s { int a[20]; } foo_t; int sum1(const foo_t *p) { int i, total=0; for (i=0; i<20; i++) total += p->a[i]; return total; } int sum2(void) { const foo_t *p = (const foo_t *)0x1234; int i, total=0; for (i=0; i<20; i++) total += p->a[i]; return total; } The issue arises because of below facts. 1) To avoid undefined overflow behavior, IV candidates are all of unsigned type. As a result, rewrite_use_address can't tell IV pointing to memory objects from IV that represents simply an offset. 2) To address 1), IVO records base_object information for every IV that actually points to memory object. And base_object is computed in alloc_iv with a call to determine_base_object. 3) In this case, the address of memory object is of form like "&MEM[(ptr_type)4660B].a[0]". 4) Now the address is firstly lowered into "4660B", and determine_base_object can't identify any base_object from const_int, it just returns NULL. 5) With NULL base_object, rewrite_use_address_1 won't pass base_hint to create_mem_ref. As a result, memory reference is rewritten into form of "MEM[base: 0B, index: ivtmp.20_8, offset: 0B]". 6) Though correct memory access can be generated from that reference, address_space attribute is lost because of "ZERO base". I suspect this issue exists all the time. Even we pass "&MEM[(ptr)4660B].a[0]" directly to determine_base_object, it won't consider *((ptr_type)const_int) as the memory object and just return NULL. I can see one possible fix to it. 1) call determine_base_object before lowering the address expression in alloc_iv. 2) change determine_base_object to take memory objects at constant int address into consideration. 3) for subsequent alloc_iv calls in add_candidate_1, we need to add new parameter base_object and pass the original iv->base_object to it. Otherwise, it's impossible to determine base_object because "base" has already been lowered... So what's your opinion? Thanks.