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