Skip to content

Missing %EFLAGS<kill> flag on CMOV causes suboptimal code #11504

@stoklund

Description

@stoklund
mannequin
Bugzilla Link 11132
Version trunk
OS All
CC @sunfishcode

Extended Description

The unit test test/CodeGen/X86/uint64-to-float.ll generates this code:

After Instruction Selection:

Machine code for function test:

Function Live Ins: %RDI in %vreg0
Function Live Outs: %XMM0

BB#0: derived from LLVM BB %entry
Live Ins: %RDI
%vreg0 = COPY %RDI; GR64:%vreg0
%vreg1 = SHR64r1 %vreg0, %EFLAGS<imp-def,dead>; GR64:%vreg1,%vreg0
%vreg2 = AND64ri8 %vreg0, 1, %EFLAGS<imp-def,dead>; GR64:%vreg2,%vreg0
%vreg3 = OR64rr %vreg2, %vreg1, %EFLAGS<imp-def,dead>; GR64:%vreg3,%vreg2,%vreg1
%vreg4 = CVTSI2SS64rr %vreg3; FR32:%vreg4 GR64:%vreg3
%vreg5 = ADDSSrr %vreg4, %vreg4; FR32:%vreg5,%vreg4,%vreg4
%vreg6 = CVTSI2SS64rr %vreg0; FR32:%vreg6 GR64:%vreg0
TEST64rr %vreg0, %vreg0, %EFLAGS; GR64:%vreg0
%vreg7 = CMOV_FR32 %vreg6, %vreg5, 15, %EFLAGS; FR32:%vreg7,%vreg6,%vreg5
%XMM0 = COPY %vreg7; FR32:%vreg7
RET

Note the missing %EFLAGS flag on CMOV_FR32. When this instruction is expanded by the custom inserter pass, the new blocks have %EFLAGS live-in because of the missing kill flag:

After Pre-RegAlloc TailDuplicate:

Machine code for function test:

Function Live Ins: %RDI in %vreg0
Function Live Outs: %XMM0

BB#0: derived from LLVM BB %entry
Live Ins: %RDI
%vreg0 = COPY %RDI; GR64:%vreg0
%vreg1 = SHR64r1 %vreg0, %EFLAGS<imp-def,dead>; GR64:%vreg1,%vreg0
%vreg2 = AND64ri8 %vreg0, 1, %EFLAGS<imp-def,dead>; GR64:%vreg2,%vreg0
%vreg3 = OR64rr %vreg2, %vreg1, %EFLAGS<imp-def,dead>; GR64:%vreg3,%vreg2,%vreg1
%vreg4 = CVTSI2SS64rr %vreg3; FR32:%vreg4 GR64:%vreg3
%vreg5 = ADDSSrr %vreg4, %vreg4; FR32:%vreg5,%vreg4,%vreg4
%vreg6 = CVTSI2SS64rr %vreg0; FR32:%vreg6 GR64:%vreg0
TEST64rr %vreg0, %vreg0, %EFLAGS; GR64:%vreg0
JS_4 <BB#2>, %EFLAGS
Successors according to CFG: BB#1 BB#2

BB#1: derived from LLVM BB %entry
Live Ins: %EFLAGS
Predecessors according to CFG: BB#0
Successors according to CFG: BB#2

BB#2: derived from LLVM BB %entry
Live Ins: %EFLAGS
Predecessors according to CFG: BB#0 BB#1
%vreg7 = PHI %vreg6, <BB#1>, %vreg5, <BB#0>; FR32:%vreg7,%vreg6,%vreg5
%XMM0 = COPY %vreg7; FR32:%vreg7
RET

MachineSinking can split the critical edge, but it cannot sink the instructions clobbering %EFLAGS into a block with %EFLAGS live-in.

All of this happens before the proper liveness analysis in LiveVariables, but InstrEmitter could add a kill flag to %EFLAGS.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions