Hello! When expanding __bultin_eh_return, its address pointers can degrade to a modeless constant. Use copy_addr_to_reg to always give temporary register a Pmode.
2015-09-18 Uros Bizjak <ubiz...@gmail.com> PR middle-end/67619 * except.c (expand_builtin_eh_return): Use copy_addr_to_reg to copy the address to a register. testsuite/ChangeLog: 2015-09-18 Uros Bizjak <ubiz...@gmail.com> PR middle-end/67619 * gcc.dg/torture/pr67619.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN as obvious, the patch will be backported to other release branches in a couple of days. Uros.
Index: testsuite/gcc.dg/torture/pr67619.c =================================================================== --- testsuite/gcc.dg/torture/pr67619.c (revision 0) +++ testsuite/gcc.dg/torture/pr67619.c (revision 0) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +void +foo () +{ + unsigned long l; + void *p = 0; + + __builtin_unwind_init (); + l = 0; + __builtin_eh_return (l, p); +} Index: except.c =================================================================== --- except.c (revision 227896) +++ except.c (working copy) @@ -2219,7 +2219,7 @@ expand_builtin_eh_return (tree stackadj_tree ATTRI VOIDmode, EXPAND_NORMAL); tmp = convert_memory_address (Pmode, tmp); if (!crtl->eh.ehr_stackadj) - crtl->eh.ehr_stackadj = copy_to_reg (tmp); + crtl->eh.ehr_stackadj = copy_addr_to_reg (tmp); else if (tmp != crtl->eh.ehr_stackadj) emit_move_insn (crtl->eh.ehr_stackadj, tmp); #endif @@ -2228,7 +2228,7 @@ expand_builtin_eh_return (tree stackadj_tree ATTRI VOIDmode, EXPAND_NORMAL); tmp = convert_memory_address (Pmode, tmp); if (!crtl->eh.ehr_handler) - crtl->eh.ehr_handler = copy_to_reg (tmp); + crtl->eh.ehr_handler = copy_addr_to_reg (tmp); else if (tmp != crtl->eh.ehr_handler) emit_move_insn (crtl->eh.ehr_handler, tmp);