X86 Backend - How to push and pop eflags?

Hello llvm-dev list,

i am implementing an X86 Machine Pass that at some point needs to push/pop eflags on the stack. This pass is hooked at preRegAlloc and LLVM is 3.7.0.
I got two big problems:

  1. I didn’t found a way to emit a pushfq instruction in a clean way, i.e. with BuildMI(*MBB, MI, DL, TII.get(X86::PUSHF64)). Even if both EFLAGS and RSP are added to the MBB liveins, the Machine Verifier complains saying:

*** Bad machine code: Using an undefined physical register ***

  • function: main
  • basic block: BB#238 for.inc.121.4 (0x43133b0)
  • instruction: PUSHF64- operand 2: %EFLAGS<imp-use,kill>

Anyway right now i’m able to push it via some “dirty” INLINE_ASM.

  1. INLINE_ASM works pretty well, except in one randomly generated test case where the register allocator spills a register in between the pushfq/popfq, resulting in a crash of the compiled application.

So the question is: is there a recommended way to save and restore the value of eflags?

Any help is really appreciated!

I think our PUSHF representation or the verifier needs to be changed here. You are lowering it exactly the way that llvm.x86.flags.read.u64 is lowered. Compiling this IR with llc gives the same verifier failure:

define i64 @f() {
entry:
%0 = call i64 @llvm.x86.flags.read.u64()
ret i64 %0
}

Hello llvm-dev list,

i am implementing an X86 Machine Pass that at some point needs to push/pop
eflags on the stack. This pass is hooked at preRegAlloc and LLVM is 3.7.0.
I got two big problems:
1) I didn't found a way to emit a pushfq instruction in a clean way, i.e.
with BuildMI(*MBB, MI, DL, TII.get(X86::PUSHF64)). Even if both EFLAGS
and RSP are added to the MBB liveins, the Machine Verifier complains saying:
*** Bad machine code: Using an undefined physical register ***

- function: main

- basic block: BB#238 for.inc.121.4 (0x43133b0)
- instruction: PUSHF64- operand 2: %EFLAGS<imp-use,kill>

We had a similar issue with the machine verifier for our blessed intrinsic.
The fixe was to mark the EFLAGS MachineOperand as Undef:
https://github.com/llvm-mirror/llvm/commit/60cefca131b1e4847f7206f99f334baac95772e9