https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69693

            Bug ID: 69693
           Summary: Wrong mode is used to load spilled register
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ienkovich at gcc dot gnu.org
  Target Milestone: ---

The problem appears for code generated by STV pass.  This code uses paradoxical
subregs which may cause spill/fill mismatch.

>cat test.i
extern const unsigned int a[];
extern const unsigned long long b[];

int
fn1 (unsigned int p1, unsigned long long p2)
{
  unsigned int p3;

  p3 = a[p1];
  if (p3 == 0 || p3 > 64)
    return 0;

  p2 &= b[p1];
  return p2 == ((unsigned long long) 1 << (p3 - 1));
}
>gcc test.i -m32 -O2 -march=corei7 -S
>cat test.s
        .file   "test.i"
        .text
        .p2align 4,,15
        .globl  fn1
        .type   fn1, @function
fn1:
.LFB0:
        .cfi_startproc
        pushl   %ebx
        .cfi_def_cfa_offset 8
        .cfi_offset 3, -8
        subl    $24, %esp
        .cfi_def_cfa_offset 32
        movl    32(%esp), %edx
        movl    36(%esp), %ecx
        movl    40(%esp), %ebx
        movl    a(,%edx,4), %eax
        movl    %ecx, (%esp)
        movl    %ebx, 4(%esp)
        leal    -1(%eax), %ecx
        xorl    %eax, %eax
        cmpl    $63, %ecx
        ja      .L2
        movq    b(,%edx,8), %xmm0
        xorl    %eax, %eax
        xorl    %edx, %edx
        testb   $32, %cl
        sete    %al
        movdqa  (%esp), %xmm2
        setne   %dl
        sall    %cl, %eax
        sall    %cl, %edx
        pand    %xmm0, %xmm2
        movd    %eax, %xmm0
        pinsrd  $1, %edx, %xmm0
        pxor    %xmm2, %xmm0
        punpcklqdq      %xmm0, %xmm0
        ptest   %xmm0, %xmm0
        sete    %al
.L2:
        addl    $24, %esp
        .cfi_def_cfa_offset 8
        movzbl  %al, %eax
        popl    %ebx
        .cfi_restore 3
        .cfi_def_cfa_offset 4
        ret
        .cfi_endproc
.LFE0:
        .size   fn1, .-fn1
        .ident  "GCC: (GNU) 6.0.0 20160127 (experimental)"
        .section        .note.GNU-stack,"",@progbits

Here we use movdqa to load a spilled value. But value has DImode and was
spilled using two movl instructions.  Ideally we shouldn't allocate GPR for
DImode register in this test at all and no spill/fill should occur.

Using gcc version 6.0.0 20160127

Reply via email to