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