llvm.org GIT mirror llvm / 87255a4
Patch by Shuxin Yang <shuxin.llvm@gmail.com>. Original message: The attached is the fix to radar://11663049. The optimization can be outlined by following rules: (select (x != c), e, c) -> select (x != c), e, x), (select (x == c), c, e) -> select (x == c), x, e) where the <c> is an integer constant. The reason for this change is that : on x86, conditional-move-from-constant needs two instructions; however, conditional-move-from-register need only one instruction. While the LowerSELECT() sounds to be the most convenient place for this optimization, it turns out to be a bad place. The reason is that by replacing the constant <c> with a symbolic value, it obscure some instruction-combining opportunities which would otherwise be very easy to spot. For that reason, I have to postpone the change to last instruction-combining phase. The change passes the test of "make check-all -C <build-root/test" and "make -C project/test-suite/SingleSource". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165661 91177308-0d34-0410-b5e6-96231b3b80d8 Nadav Rotem 7 years ago
2 changed file(s) with 56 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
1441714417 if (TrueC->getAPIntValue().ult(FalseC->getAPIntValue())) {
1441814418 CC = X86::GetOppositeBranchCondition(CC);
1441914419 std::swap(TrueC, FalseC);
14420 std::swap(TrueOp, FalseOp);
1442014421 }
1442114422
1442214423 // Optimize C ? 8 : 0 -> zext(setcc(C)) << 3. Likewise for any pow2/0.
1449914500 }
1450014501 }
1450114502 }
14503
14504 // Handle these cases:
14505 // (select (x != c), e, c) -> select (x != c), e, x),
14506 // (select (x == c), c, e) -> select (x == c), x, e)
14507 // where the c is an integer constant, and the "select" is the combination
14508 // of CMOV and CMP.
14509 //
14510 // The rationale for this change is that the conditional-move from a constant
14511 // needs two instructions, however, conditional-move from a register needs
14512 // only one instruction.
14513 //
14514 // CAVEAT: By replacing a constant with a symbolic value, it may obscure
14515 // some instruction-combining opportunities. This opt needs to be
14516 // postponed as late as possible.
14517 //
14518 if (!DCI.isBeforeLegalize() && !DCI.isBeforeLegalizeOps()) {
14519 // the DCI.xxxx conditions are provided to postpone the optimization as
14520 // late as possible.
14521
14522 ConstantSDNode *CmpAgainst = 0;
14523 if ((Cond.getOpcode() == X86ISD::CMP || Cond.getOpcode() == X86ISD::SUB) &&
14524 (CmpAgainst = dyn_cast(Cond.getOperand(1))) &&
14525 dyn_cast(Cond.getOperand(0)) == 0) {
14526
14527 if (CC == X86::COND_NE &&
14528 CmpAgainst == dyn_cast(FalseOp)) {
14529 CC = X86::GetOppositeBranchCondition(CC);
14530 std::swap(TrueOp, FalseOp);
14531 }
14532
14533 if (CC == X86::COND_E &&
14534 CmpAgainst == dyn_cast(TrueOp)) {
14535 SDValue Ops[] = { FalseOp, Cond.getOperand(0), N->getOperand(2), Cond };
14536 return DAG.getNode(X86ISD::CMOV, DL, N->getVTList (), Ops,
14537 array_lengthof(Ops));
14538 }
14539 }
14540 }
14541
1450214542 return SDValue();
1450314543 }
1450414544
0 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -mcpu=corei7 | FileCheck %s
1
2 define i64 @test1(i64 %x) nounwind {
3 entry:
4 %cmp = icmp eq i64 %x, 2
5 %add = add i64 %x, 1
6 %retval.0 = select i1 %cmp, i64 2, i64 %add
7 ret i64 %retval.0
8
9 ; CHECK: test1:
10 ; CHECK: leaq 1(%rdi), %rax
11 ; CHECK: cmpq $2, %rdi
12 ; CHECK: cmoveq %rdi, %rax
13 ; CHECK: ret
14
15 }