[PATCH] D11768: FastISel fails to remove dead code
Wolfgang Pieb
wolfgang_pieb at playstation.sony.com
Wed Aug 5 10:27:24 PDT 2015
wolfgangp created this revision.
wolfgangp added a subscriber: llvm-commits.
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.
http://reviews.llvm.org/D11768
Files:
lib/CodeGen/SelectionDAG/FastISel.cpp
test/CodeGen/X86/fast-isel-deadcode.ll
Index: test/CodeGen/X86/fast-isel-deadcode.ll
===================================================================
--- test/CodeGen/X86/fast-isel-deadcode.ll
+++ test/CodeGen/X86/fast-isel-deadcode.ll
@@ -0,0 +1,39 @@
+; RUN: llc < %s -O0 -march=x86 | FileCheck %s
+;
+; Generated from
+;
+; extern bool bar (long double);
+; bool foo(long double x, long double y)
+; {
+; return (x == y) || (bar(x));
+; }
+;
+; ModuleID = 'test.cpp'
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+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
+}
+
+declare zeroext i1 @_Z3bare(x86_fp80)
+
+; CHECK: movb $1
+; CHECK-NOT: movb $1
Index: lib/CodeGen/SelectionDAG/FastISel.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/FastISel.cpp
+++ lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1327,6 +1327,7 @@
}
bool FastISel::selectInstruction(const Instruction *I) {
+ MachineInstr *SaveLastLocalValue = getLastLocalValue();
// Just before the terminator instruction, insert instructions to
// feed PHI nodes in successor blocks.
if (isa<TerminatorInst>(I))
@@ -1380,8 +1381,21 @@
DbgLoc = DebugLoc();
// Undo phi node updates, because they will be added again by SelectionDAG.
- if (isa<TerminatorInst>(I))
+ if (isa<TerminatorInst>(I)) {
+ // PHI node handling may have generated some local value instructions.
+ // Remove them like other dead code.
+ MachineInstr *CurLastLocalValue = getLastLocalValue();
+ if (CurLastLocalValue != SaveLastLocalValue) {
+ MachineBasicBlock::iterator FirstDeadInst(SaveLastLocalValue);
+ if (SaveLastLocalValue)
+ ++FirstDeadInst;
+ else
+ FirstDeadInst = FuncInfo.MBB->getFirstNonPHI();
+ setLastLocalValue(SaveLastLocalValue);
+ removeDeadCode(FirstDeadInst, FuncInfo.InsertPt);
+ }
FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate);
+ }
return false;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D11768.31363.patch
Type: text/x-patch
Size: 2703 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150805/494274f6/attachment.bin>
More information about the llvm-commits
mailing list