[llvm-dev] retpoline mitigation and 6.0

Reid Kleckner via llvm-dev llvm-dev at lists.llvm.org
Fri Feb 9 14:23:35 PST 2018

I think I see what's going on, and I agree it looks like a bug. It was too
much to hope that later passes weren't going to mess with the PUSH
instruction. :(

While I was trying to reproduce your problem, I think I found another one
that looks like this:

$ clang -S -O2 -m32 -mregparm=3 -mretpoline spill_across_rp.cpp -o - |
grep _retpoline_push -B2
        movl    %eax, 8(%esp)           # 4-byte Spill
        pushl   %edi
        movl    8(%esp), %edi           # 4-byte Reload
        calll   __llvm_retpoline_push

That's obviously broken, it doesn't account for the SP adjustment in the

It's weird, because it's basically the opposite of the problem you're
having, which looks like LLVM *is* accounting for the push and is trying to
adjust its offsets accordingly.

Can you send along the full command line used to compile io_apic_b.i?

On Fri, Feb 9, 2018 at 11:38 AM, David Woodhouse <dwmw2 at infradead.org>

> On Fri, 2018-02-09 at 11:24 -0800, Reid Kleckner wrote:
> > I haven't read the all the emails in full detail, but it seems pretty
> > clear that  __x86_indirect_thunk and __llvm_retpoline_push do not do
> > the same things. It sounds like __llvm_retpoline_push is equivalent
> > to __x86_indirect_thunk except first it swaps the two words on the
> > top of the stack.
> >
> > I arranged it this way because the x86 call instruction puts the
> > intended return address on the top of the stack, and there's no easy
> > way to put it anywhere else. We use this thunk when we want to make
> > an indirect call and there are no available scratch registers, i.e.
> > 32-bit -mregparm=3 and the call has three or more arguments, which
> > happens in Linux. One way to avoid this would be to compile with
> > -mregparm=2, but that would pessimize direct calls unnecessarily.
> >
> > It sounds like Linux is already providing its own thunks, so it might
> > be better to for us to go back to the __llvm_retpoline_push external
> > thunk name and then get Linux to provide that thunk ifdef __clang__.
> Yes, the thunks are different in this case. That one should indeed be
> renamed, and I'll provide the correct one in the kernel.
> However, even if I let LLVM emit the thunk for itself, code generation
> seems hosed. It looks like after a call to __llvm_retpoline_push (or
> perhaps more to the point after pushing the target address in
> preparation for the call?) we're losing track of where %esp points, and
> thus everything else that was spilled to the stack.
> Please let me know if you need any more detail on that, than I provided
> in my last email. You should have everything you need there to follow
> along with my analysis and reproduce it for yourself. Except perhaps
> the Grandma-suck-eggs command lines like
> $ qemu-system-i386  -display none -serial stdio -kernel
> arch/x86/boot/bzImage  -append earlyprintk=ttyS0,keep -s -S
> $ gdb vmlinux
> (gdb) tar rem localhost:1234
> (gdb) break mp_register_ioapic
> (gdb) c
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180209/0ffda508/attachment.html>

More information about the llvm-dev mailing list