http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60452
--- Comment #11 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #3) > If I modify the shorter testcase such that int e[2]; is a static array, then > we don't generate cmove for it, because on: > (mem:SI (const:DI (plus:DI (symbol_ref:DI ("e") <var_decl 0x7ffff19d6098 e>) > (const_int 524288 [0x80000]))) [2 e+524288 S4 A32]) > may_trap_or_fault_p returns true (correctly). But in the case of automatic > out-of-bound access we get instead: > (mem/c:SI (plus:DI (reg/f:DI 20 frame) > (const_int 524272 [0x7fff0])) [2 S4 A128]) > and there may_trap_or_fault_p really can't (easily) know if it is valid or > not, there is no MEM_EXPR even. This is because in the #c2 testcase as well > as the original one DECL_RTL of e variable is a register, not MEM. > But even if I try: > int a; > __attribute__((noinline, noclone)) void > foo (int *e) > { > asm volatile ("" : : "r" (e) : "memory"); > } > > int > main () > { > int e[2] = { 0, 0 }, f = 0; > if (a == 131072) > f = e[a]; > foo (e); > return f; > } > where we have: > (mem:SI (plus:DI (reg/f:DI 20 frame) > (const_int 524272 [0x7fff0])) [2 e+524288 S4 A128]) > instead and thus from MEM_EXPR we perhaps could find out that it is an out > of bound access, we still always treat all frame based accesses (whatever > the offset is) as non-trapping. > So perhaps we need to handle known out of bound MEMs specially when we find > that fact out (if we want to emit them into the RTL IL at all), one thing is > expansion, another thing if say initially non-constant offset is later > CSEd/forwprop etc. into constant out of bound offset. > > Thoughts? Well, may_trap_or_fault_p has to be conservative. See how tree_could_trap_p handles bound violations. If you can't prove it isn't out-of-bounds then you have to assume it may be.