http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55430



Jakub Jelinek <jakub at gcc dot gnu.org> changed:



           What    |Removed                     |Added

----------------------------------------------------------------------------

             Target|                            |x86_64-linux

           Priority|P3                          |P1

             Status|UNCONFIRMED                 |NEW

   Last reconfirmed|                            |2012-11-21

          Component|other                       |middle-end

                 CC|                            |vmakarov at redhat dot com

     Ever Confirmed|0                           |1

   Target Milestone|---                         |4.8.0



--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-11-21 
17:16:00 UTC ---

This ree.c:61X failure is a LRA caused miscompilation of ree.c apparently.

Reduced self-contained testcase:



struct S

{

  unsigned int s1 : 8;

  unsigned int s2 : 2;

};



int

foo (int x, int y, struct S *z, unsigned int w)

{

  if (z[y].s2 == x && z[y].s1 == w)

    return 1;

  return 0;

}



#ifdef FULL

#include <unistd.h>

#include <sys/mman.h>



int foo (int, int, struct S *, unsigned int) __attribute__((noinline,

noclone));



int

main ()

{

  unsigned long ps = sysconf (_SC_PAGE_SIZE);

  char *p = mmap (NULL, 8 * ps, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

  if (p == MAP_FAILED)

    return 0;

  if (mprotect (p + 4 * ps, 4 * ps, PROT_NONE))

    return 0;

  if ((4 * ps / sizeof (struct S)) * sizeof (struct S) != 4 * ps)

    return 0;

  struct S *s = (struct S *) (p + 4 * ps);

  return foo (0, 0, s - 1, 0) != 1;

}

#endif



compile with -O2 on x86_64-linux, and you can see (or when compiled with -O2

-DFULL watch at runtime) that before LRA merge, code like:

        movzbl  1(%rdx), %eax

        andl    $3, %eax

has been generated to read the s2 bitfield, while with LRA it is

        movl    1(%rdx), %esi

        andl    $3, %esi

instead (note movl instead of movzbl).  But the structure (in ree.c s2 is kind

and struct S is struct ext_modified) is 4 bytes long, thus reading 4 bytes from

the start of the structure + 1 byte is potentially going to trap if the

structure is at the end of some page (as -DFULL shows).

In *.ira we have:

(insn 15 12 16 2 (set (reg:QI 80 [ *_6+1 ])

        (mem:QI (plus:DI (reg/f:DI 62 [ D.1744 ])

                (const_int 1 [0x1])) [2 *_6+1 S1 A8])) reetest.c:10 67

{*movqi_internal}

     (expr_list:REG_EQUIV (mem:QI (plus:DI (reg/f:DI 62 [ D.1744 ])

                (const_int 1 [0x1])) [2 *_6+1 S1 A8])

        (nil)))

(note 16 15 17 2 NOTE_INSN_DELETED)

(insn 17 16 7 2 (parallel [

            (set (reg:SI 81 [ D.1742 ])

                (and:SI (subreg:SI (reg:QI 80 [ *_6+1 ]) 0)

                    (const_int 3 [0x3])))

            (clobber (reg:CC 17 flags))

        ]) reetest.c:10 376 {*andsi_1}

     (expr_list:REG_DEAD (reg:QI 80 [ *_6+1 ])

        (expr_list:REG_UNUSED (reg:CC 17 flags)

            (nil))))

which *.reload turns into:

(insn 43 16 17 2 (set (reg:SI 4 si [orig:81 D.1742 ] [81])

        (mem:SI (plus:DI (reg/f:DI 1 dx [orig:62 D.1744 ] [62])

                (const_int 1 [0x1])) [2 *_6+1 S4 A8])) reetest.c:10 65

{*movsi_internal}

     (nil))

(insn 17 43 44 2 (parallel [

            (set (reg:SI 4 si [orig:81 D.1742 ] [81])

                (and:SI (reg:SI 4 si [orig:81 D.1742 ] [81])

                    (const_int 3 [0x3])))

            (clobber (reg:CC 17 flags))

        ]) reetest.c:10 376 {*andsi_1}

     (nil))

Reply via email to