This is an archive of the discontinued LLVM Phabricator instance.

FastISel fails to remove dead code
ClosedPublic

Authored by wolfgangp on Aug 5 2015, 10:27 AM.

Details

Summary

When FastISel fails to translate an instruction it hands off code generation to SelectionDAG. Before it does so, it may have generated local value instructions to feed phi nodes in successor blocks. These instructions will then be generated again by SelectionDAG, causing duplication and less efficient code, including extra spill instructions.
Consider the following example:

define zeroext i1 @_Z3fooee(x86_fp80 %x, x86_fp80 %y) {
entry:

%x.addr = alloca x86_fp80, align 16
%y.addr = alloca x86_fp80, align 16
store x86_fp80 %x, x86_fp80* %x.addr, align 16
store x86_fp80 %y, x86_fp80* %y.addr, align 16
%0 = load x86_fp80, x86_fp80* %x.addr, align 16
%1 = load x86_fp80, x86_fp80* %y.addr, align 16
%cmp = fcmp oeq x86_fp80 %0, %1
br i1 %cmp, label %lor.end, label %lor.rhs

lor.rhs: ; preds = %entry

%2 = load x86_fp80, x86_fp80* %x.addr, align 16
%call = call zeroext i1 @_Z3bare(x86_fp80 %2)
br label %lor.end

lor.end: ; preds = %lor.rhs, %entry

%3 = phi i1 [ true, %entry ], [ %call, %lor.rhs ]
ret i1 %3

}

FastISel fails to translate one of the instructions in the entry block and leaves the rest of code generation to SelectionDAG. However, it fails to remove the instructions it generated to supply the phi node in the lor.end block:

...
subq    $64, %rsp
fldt    32(%rbp)
fldt    16(%rbp)
movb    $1, %al         <=======
fstpt   -16(%rbp)
fld     %st(0)
fstpt   -32(%rbp)
fldt    -16(%rbp)
movb    $1, %cl         <=======
fucompi %st(1)
fstp    %st(0)
movb    %al, -33(%rbp)          # 1-byte Spill <======== not used later
movb    %cl, -34(%rbp)          # 1-byte Spill <======== used
jne     .LBB0_1
jp      .LBB0_1
jmp     .LBB0_2

.LBB0_1:

...

The patch proposes to remove all phi-node handling instructions as dead code when FastISel quits.

Diff Detail

Event Timeline

wolfgangp updated this revision to Diff 31363.Aug 5 2015, 10:27 AM
wolfgangp retitled this revision from to FastISel fails to remove dead code.
wolfgangp updated this object.
wolfgangp added a subscriber: llvm-commits.
hans edited edge metadata.Sep 18 2015, 1:08 PM

This seems reasonable, but I don't know this code well enough to feel comfortable signing off here.

I'm afraid you'll have to get Eric or someone else to take a look.

lib/CodeGen/SelectionDAG/FastISel.cpp
1330

How about SavedLastLocalValue, to make the name a noun?

test/CodeGen/X86/fast-isel-deadcode.ll
16

Let's pretend the code above was C code and just call this "foo". Same thing for "_Z3bare" below: I'd just call it "bar".

39

I would probably have a CHECK-LABEL, and move these lines closer to the IR that they're generated from.

As it is now, the reader only sees "check that movb $1 isn't followed by another movb $1", and that really doesn't provide much of a clue to what's going on.

echristo edited edge metadata.Sep 18 2015, 1:13 PM

Sorry, it's on my list, but there are a few patches ahead of it. Know that it isn't forgotten though.

wolfgangp updated this revision to Diff 36039.Sep 29 2015, 2:45 PM
wolfgangp edited edge metadata.

Incorporated feedback by Hans. Sorry for the delay.

echristo accepted this revision.Nov 19 2015, 6:13 PM
echristo edited edge metadata.

One inline comment requesting more commenting :)

Otherwise LGTM.

Thanks!

-eric

lib/CodeGen/SelectionDAG/FastISel.cpp
1392–1396

This feels a little weird, can you comment it a bit?

This revision is now accepted and ready to land.Nov 19 2015, 6:13 PM
wolfgangp updated this revision to Diff 40850.Nov 20 2015, 5:20 PM
wolfgangp edited edge metadata.

Sorry, Eric, I had to revise the patch because we found another instance of this issue, in that handlePHINodesInSuccessorBlocks() can return false AND leave dead code behind, so I ended up breaking out the removing code and calling it from two different places. The test case has 2 subcases covering both code paths.

I beefed up the commentary a bit.

Still LGTM.

Thanks!

-eric

This revision was automatically updated to reflect the committed changes.