[PATCH] D17288: [CodeGenPrepare] Do select to branch transform when cmp's operand is expensive.
Junmo Park via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 16 02:05:50 PST 2016
flyingforyou created this revision.
flyingforyou added a reviewer: spatel.
flyingforyou added subscribers: llvm-commits, JongwonLee, evandro.
Emit "cmov on compare with a expensive operand" as a branch to avoid stalls on executing expensive instruction likes division.
http://reviews.llvm.org/D17288
Files:
lib/CodeGen/CodeGenPrepare.cpp
test/Transforms/CodeGenPrepare/X86/select.ll
Index: test/Transforms/CodeGenPrepare/X86/select.ll
===================================================================
--- test/Transforms/CodeGenPrepare/X86/select.ll
+++ test/Transforms/CodeGenPrepare/X86/select.ll
@@ -139,3 +139,17 @@
; CHECK: %sel = select i1 %cmp, i32 %div1, i32 %div2
}
+; Nothing to sink here, but this gets converted to a branch to
+; avoid stalling an out-of-order CPU on a predictable branch.
+; Because cmp's operand is expensive instruction likes division.
+
+define float @fdiv_do_transform(float %a, float %b) {
+entry:
+ %div = fdiv float %a, %b
+ %cmp = fcmp ogt float %div, %b
+ %sel = select i1 %cmp, float %div, float 8.0
+ ret float %sel
+
+; CHECK-LABEL: @fdiv_do_transform(
+; CHECK: br i1 %cmp, label %select.end, label %select.false
+}
Index: lib/CodeGen/CodeGenPrepare.cpp
===================================================================
--- lib/CodeGen/CodeGenPrepare.cpp
+++ lib/CodeGen/CodeGenPrepare.cpp
@@ -4468,16 +4468,31 @@
// case currently.
CmpInst *Cmp = dyn_cast<CmpInst>(SI->getCondition());
+ if (!Cmp)
+ return false;
+
+ Value *CmpOp0 = Cmp->getOperand(0);
+ Value *CmpOp1 = Cmp->getOperand(1);
+
+ // Emit "cmov on compare with a expensive operand" as a branch to avoid stalls
+ // on executing expensive instruction likes division.
+ auto IsExpensiveCostInst = [&](Value *V) -> bool {
+ auto *I = dyn_cast<Instruction>(V);
+ if (I && TTI->getUserCost(I) >= TargetTransformInfo::TCC_Expensive)
+ return true;
+
+ return false;
+ };
+
+ if (IsExpensiveCostInst(CmpOp0) || IsExpensiveCostInst(CmpOp1))
+ return true;
// If a branch is predictable, an out-of-order CPU can avoid blocking on its
// comparison condition. If the compare has more than one use, there's
// probably another cmov or setcc around, so it's not worth emitting a branch.
- if (!Cmp || !Cmp->hasOneUse())
+ if (!Cmp->hasOneUse())
return false;
- Value *CmpOp0 = Cmp->getOperand(0);
- Value *CmpOp1 = Cmp->getOperand(1);
-
// Emit "cmov on compare with a memory operand" as a branch to avoid stalls
// on a load from memory. But if the load is used more than once, do not
// change the select to a branch because the load is probably needed
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17288.48055.patch
Type: text/x-patch
Size: 2250 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160216/c06413d5/attachment.bin>
More information about the llvm-commits
mailing list