llvm.org GIT mirror llvm / b5a55d9
- Teach SelectionDAG::isKnownNeverZero to return true (op x, c) when c is non-zero. - Teach X86 cmov optimization to eliminate the cmov from ctlz, cttz extension when the source of X86ISD::BSR / X86ISD::BSF is proven to be non-zero. rdar://9490949 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131948 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 8 years ago
3 changed file(s) with 45 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
20492049 break;
20502050
20512051 default:
2052 // Allow the target to implement this method for its nodes.
2053 if (Op.getOpcode() >= ISD::BUILTIN_OP_END) {
2052 if (Op.getOpcode() < ISD::BUILTIN_OP_END)
2053 break;
2054 // Fallthrough
20542055 case ISD::INTRINSIC_WO_CHAIN:
20552056 case ISD::INTRINSIC_W_CHAIN:
20562057 case ISD::INTRINSIC_VOID:
2057 TLI.computeMaskedBitsForTargetNode(Op, Mask, KnownZero, KnownOne, *this,
2058 Depth);
2059 }
2058 // Allow the target to implement this method for its nodes.
2059 TLI.computeMaskedBitsForTargetNode(Op, Mask, KnownZero, KnownOne, *this,
2060 Depth);
20602061 return;
20612062 }
20622063 }
23212322 return !C->isZero();
23222323
23232324 // TODO: Recognize more cases here.
2325 switch (Op.getOpcode()) {
2326 default: break;
2327 case ISD::OR:
2328 if (const ConstantSDNode *C = dyn_cast(Op.getOperand(1)))
2329 return !C->isNullValue();
2330 break;
2331 }
23242332
23252333 return false;
23262334 }
1133111331 if (N->getNumValues() == 2 && !SDValue(N, 1).use_empty())
1133211332 return SDValue();
1133311333
11334 SDValue FalseOp = N->getOperand(0);
11335 SDValue TrueOp = N->getOperand(1);
11336 X86::CondCode CC = (X86::CondCode)N->getConstantOperandVal(2);
11337 SDValue Cond = N->getOperand(3);
11338 if (CC == X86::COND_E || CC == X86::COND_NE) {
11339 switch (Cond.getOpcode()) {
11340 default: break;
11341 case X86ISD::BSR:
11342 case X86ISD::BSF:
11343 // If operand of BSR / BSF are proven never zero, then ZF cannot be set.
11344 if (DAG.isKnownNeverZero(Cond.getOperand(0)))
11345 return (CC == X86::COND_E) ? FalseOp : TrueOp;
11346 }
11347 }
11348
1133411349 // If this is a select between two integer constants, try to do some
1133511350 // optimizations. Note that the operands are ordered the opposite of SELECT
1133611351 // operands.
11337 if (ConstantSDNode *TrueC = dyn_cast(N->getOperand(1))) {
11338 if (ConstantSDNode *FalseC = dyn_cast(N->getOperand(0))) {
11352 if (ConstantSDNode *TrueC = dyn_cast(TrueOp)) {
11353 if (ConstantSDNode *FalseC = dyn_cast(FalseOp)) {
1133911354 // Canonicalize the TrueC/FalseC values so that TrueC (the true value) is
1134011355 // larger than FalseC (the false value).
11341 X86::CondCode CC = (X86::CondCode)N->getConstantOperandVal(2);
11342
1134311356 if (TrueC->getAPIntValue().ult(FalseC->getAPIntValue())) {
1134411357 CC = X86::GetOppositeBranchCondition(CC);
1134511358 std::swap(TrueC, FalseC);
1134911362 // This is efficient for any integer data type (including i8/i16) and
1135011363 // shift amount.
1135111364 if (FalseC->getAPIntValue() == 0 && TrueC->getAPIntValue().isPowerOf2()) {
11352 SDValue Cond = N->getOperand(3);
1135311365 Cond = DAG.getNode(X86ISD::SETCC, DL, MVT::i8,
1135411366 DAG.getConstant(CC, MVT::i8), Cond);
1135511367
1136711379 // Optimize Cond ? cst+1 : cst -> zext(setcc(C)+cst. This is efficient
1136811380 // for any integer data type, including i8/i16.
1136911381 if (FalseC->getAPIntValue()+1 == TrueC->getAPIntValue()) {
11370 SDValue Cond = N->getOperand(3);
1137111382 Cond = DAG.getNode(X86ISD::SETCC, DL, MVT::i8,
1137211383 DAG.getConstant(CC, MVT::i8), Cond);
1137311384
1140611417
1140711418 if (isFastMultiplier) {
1140811419 APInt Diff = TrueC->getAPIntValue()-FalseC->getAPIntValue();
11409 SDValue Cond = N->getOperand(3);
1141011420 Cond = DAG.getNode(X86ISD::SETCC, DL, MVT::i8,
1141111421 DAG.getConstant(CC, MVT::i8), Cond);
1141211422 // Zero extend the condition if needed.
3030 }
3131
3232 declare i16 @llvm.ctlz.i16(i16) nounwind readnone
33
34 ; Don't generate the cmovne when the source is known non-zero (and bsr would
35 ; not set ZF).
36 ; rdar://9490949
37
38 define i32 @t4(i32 %n) nounwind {
39 entry:
40 ; CHECK: t4:
41 ; CHECK: bsrl
42 ; CHECK-NOT: cmov
43 ; CHECK: ret
44 %or = or i32 %n, 1
45 %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %or)
46 ret i32 %tmp1
47 }