Hello! Attached patch disparages riF->o alternative of *movti_internal_rex64 insn, as described by Vlad in comment #2 [1]
The core of the problem however is, that gcc is unable to detect zero-extended address as offsetable. H.J. will propose a patch for this [2]. 2012-11-10 Vladimir Makarov <vmaka...@redhat.com> Uros Bizjak <ubiz...@gmail.com> PR target/55247 * config/i386/i386.md (*movti_internal_rex64): Add "!" to riF->o alternative. testsuite/ChangeLog: 2012-11-10 Uros Bizjak <ubiz...@gmail.com> PR target/55247 * gcc.target/i386/pr55247.c: New test. Tested on x86_64-linux-gnu {,m32} and committed to mainline SVN. [1] gcc.gnu.org/bugzilla/show_bug.cgi?id=55247#c2 [2] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55247#c6 Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 193387) +++ config/i386/i386.md (working copy) @@ -1874,7 +1874,7 @@ (const_string "OI")))]) (define_insn "*movti_internal_rex64" - [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m") + [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,!o ,x,x ,m") (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" { Index: testsuite/gcc.target/i386/pr55247.c =================================================================== --- testsuite/gcc.target/i386/pr55247.c (revision 0) +++ testsuite/gcc.target/i386/pr55247.c (working copy) @@ -0,0 +1,38 @@ +/* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-options "-O2 -mx32 -maddress-mode=long -mno-sse" } */ + +typedef unsigned int uint32_t; +typedef unsigned int uintptr_t; +typedef uint32_t Elf32_Word; +typedef uint32_t Elf32_Addr; +typedef struct { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_other; +} Elf32_Sym; +typedef struct { + Elf32_Word r_info; +} +Elf32_Rela; +typedef struct { + union { + Elf32_Addr d_ptr; + } + d_un; +} Elf32_Dyn; +struct link_map { + Elf32_Dyn *l_info[34]; +}; +typedef struct link_map *lookup_t; +extern void symbind32 (Elf32_Sym *); +void +_dl_profile_fixup (struct link_map *l, Elf32_Word reloc_arg) +{ + const Elf32_Sym *const symtab = (const void *) (l)->l_info[6]->d_un.d_ptr; + const Elf32_Rela *const reloc = (const void *) ((l)->l_info[23]->d_un.d_ptr + reloc_arg * sizeof (Elf32_Rela)); + const Elf32_Sym *refsym = &symtab[((reloc->r_info) >> 8)]; + const Elf32_Sym *defsym = refsym; + Elf32_Sym sym = *defsym; + symbind32 (&sym); +}