The included program coredumps during execution when compiled with -O2 but not when compiled with -O0. The problem appears to be with combine and the use of the ptr_extend_plus_2 instruction. GCC is losing track of what is and isn't a pointer. I am not entirely sure if the program is legal given all the casts. struct magic_state { void *mgs_sv; }; typedef struct magic_state MGS; MGS *PL_savestack; void restore_magic(void *p) { MGS* mgs = ((MGS*) ((char*)PL_savestack + (long)(p))); if (!mgs->mgs_sv) return; mgs->mgs_sv = ((void *)0); } MGS s; main() { PL_savestack = &s; restore_magic((void *) 0); }
The program is correct, because you are still accessing a MGS object through a MGS pointer, so GCC should not segfault here.
Confirmed with mainline and 3.4.3.
Created attachment 10216 [details] Testcase that fails at -O on every branch.
That's a pretty serious issue (the testcase comes from Perl).
I think basereg_operand should not look inside SUBREGs. Here's an excerpt from PA's deprecated basereg_operand: return (GET_CODE (op) == REG && REG_POINTER (op) && register_operand (op, mode)); I'm going to attach the proposed fix.
Created attachment 10217 [details] Proposed fix.
Patch posted: http://gcc.gnu.org/ml/gcc-patches/2006-02/msg01489.html
Subject: Bug 19061 Author: sje Date: Fri Mar 3 16:43:43 2006 New Revision: 111678 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=111678 Log: PR rtl-optimization/26345 PR target/19061 * config/ia64/predicates.md (basereg_operand): Don't look in subregs. Modified: trunk/gcc/ChangeLog trunk/gcc/config/ia64/predicates.md
Subject: Bug 19061 Author: sje Date: Fri Mar 3 16:45:47 2006 New Revision: 111679 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=111679 Log: PR rtl-optimization/26345 PR target/19061 * config/ia64/predicates.md (basereg_operand): Don't look in subregs. Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/config/ia64/predicates.md
Fixed in 4.1.1.