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

--- Comment #27 from Bernd Edlinger <bernd.edlinger at hotmail dot de> ---
(In reply to Martin Jambor from comment #22)
> Created attachment 30732 [details]
> Another attempt at a fix
> 
> I simply moved the decision whether to go the misalignp path or not a
> bit down in the function, below the address adjustments done for
> non-NULL offset, strict volatile bit fields etc. and ran the
> testsuite, expecting some fallout.  But there was none the patch even
> survives a bootstrap on x86_64-linux.  I'm hesitant to call it the
> fix, I'd like to have a second look at it after the weekend but if
> someone wants to test meanwhile, such input would be highly welcome.

Martin, this patch is wrong:
consider this test example:

/* PR middle-end/57748 */
/* { dg-do run } */

#include <stdlib.h>

extern void abort (void);

typedef long long V
  __attribute__ ((vector_size (2 * sizeof (long long)), may_alias));

typedef double V1
  __attribute__ ((vector_size (1 * sizeof (double)), may_alias));

typedef struct S { V a; V1 b[0]; } P __attribute__((aligned (1)));

struct __attribute__((packed)) T { char c; P s; };

void __attribute__((noinline, noclone))
check (struct T *t)
{
  if (t->s.b[0][0] != 3)
    abort ();
}

int __attribute__((noinline, noclone))
get_i (void)
{
  return 0;
}

void __attribute__((noinline, noclone))
foo (P *p)
{
  V1 a = { 3 };
  int i = get_i();
  p->b[i] = a;
}

int
main ()
{
  struct T *t = (struct T *) malloc (128);

  foo (&t->s);
  check (t);

  return 0;
}

this example is designed to go thru the
if (bitsize != GET_MODE_BITSIZE (mode)) path.
Because the struct mode is derived from V but the bitsize
is from V1, only half of V.

the resulting code from this patch accesses out of bounds:

foo:
.LFB9:
        .cfi_startproc
        pushq   %rbx
        .cfi_def_cfa_offset 16
        .cfi_offset 3, -16
        movq    %rdi, %rbx
        subq    $16, %rsp
        .cfi_def_cfa_offset 32
        call    get_i
        cltq
        movq    .LC1(%rip), %xmm1
        addq    $2, %rax
        movdqu  (%rbx,%rax,8), %xmm0
        psrldq  $8, %xmm0
        punpcklqdq      %xmm0, %xmm1
        movdqu  %xmm1, (%rbx,%rax,8)
        addq    $16, %rsp
        .cfi_def_cfa_offset 16
        popq    %rbx
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc

while my latest patch (which meanwhile was boot-straped without regressions)
generates this:

foo:
.LFB9:
        .cfi_startproc
        pushq   %rbx
        .cfi_def_cfa_offset 16
        .cfi_offset 3, -16
        movq    %rdi, %rbx
        call    get_i
        movsd   .LC0(%rip), %xmm0
        cltq
        movsd   %xmm0, 16(%rbx,%rax,8)
        popq    %rbx
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc

Reply via email to