mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-02 13:21:43 +00:00
- 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
This commit is contained in:
parent
4992b03cbd
commit
b5a55d979c
@ -2050,14 +2050,15 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, const APInt &Mask,
|
||||
break;
|
||||
|
||||
default:
|
||||
// Allow the target to implement this method for its nodes.
|
||||
if (Op.getOpcode() >= ISD::BUILTIN_OP_END) {
|
||||
if (Op.getOpcode() < ISD::BUILTIN_OP_END)
|
||||
break;
|
||||
// Fallthrough
|
||||
case ISD::INTRINSIC_WO_CHAIN:
|
||||
case ISD::INTRINSIC_W_CHAIN:
|
||||
case ISD::INTRINSIC_VOID:
|
||||
TLI.computeMaskedBitsForTargetNode(Op, Mask, KnownZero, KnownOne, *this,
|
||||
Depth);
|
||||
}
|
||||
// Allow the target to implement this method for its nodes.
|
||||
TLI.computeMaskedBitsForTargetNode(Op, Mask, KnownZero, KnownOne, *this,
|
||||
Depth);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2322,6 +2323,13 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op) const {
|
||||
return !C->isZero();
|
||||
|
||||
// TODO: Recognize more cases here.
|
||||
switch (Op.getOpcode()) {
|
||||
default: break;
|
||||
case ISD::OR:
|
||||
if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
|
||||
return !C->isNullValue();
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -11332,15 +11332,28 @@ static SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG,
|
||||
if (N->getNumValues() == 2 && !SDValue(N, 1).use_empty())
|
||||
return SDValue();
|
||||
|
||||
SDValue FalseOp = N->getOperand(0);
|
||||
SDValue TrueOp = N->getOperand(1);
|
||||
X86::CondCode CC = (X86::CondCode)N->getConstantOperandVal(2);
|
||||
SDValue Cond = N->getOperand(3);
|
||||
if (CC == X86::COND_E || CC == X86::COND_NE) {
|
||||
switch (Cond.getOpcode()) {
|
||||
default: break;
|
||||
case X86ISD::BSR:
|
||||
case X86ISD::BSF:
|
||||
// If operand of BSR / BSF are proven never zero, then ZF cannot be set.
|
||||
if (DAG.isKnownNeverZero(Cond.getOperand(0)))
|
||||
return (CC == X86::COND_E) ? FalseOp : TrueOp;
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a select between two integer constants, try to do some
|
||||
// optimizations. Note that the operands are ordered the opposite of SELECT
|
||||
// operands.
|
||||
if (ConstantSDNode *TrueC = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
|
||||
if (ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
|
||||
if (ConstantSDNode *TrueC = dyn_cast<ConstantSDNode>(TrueOp)) {
|
||||
if (ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(FalseOp)) {
|
||||
// Canonicalize the TrueC/FalseC values so that TrueC (the true value) is
|
||||
// larger than FalseC (the false value).
|
||||
X86::CondCode CC = (X86::CondCode)N->getConstantOperandVal(2);
|
||||
|
||||
if (TrueC->getAPIntValue().ult(FalseC->getAPIntValue())) {
|
||||
CC = X86::GetOppositeBranchCondition(CC);
|
||||
std::swap(TrueC, FalseC);
|
||||
@ -11350,7 +11363,6 @@ static SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG,
|
||||
// This is efficient for any integer data type (including i8/i16) and
|
||||
// shift amount.
|
||||
if (FalseC->getAPIntValue() == 0 && TrueC->getAPIntValue().isPowerOf2()) {
|
||||
SDValue Cond = N->getOperand(3);
|
||||
Cond = DAG.getNode(X86ISD::SETCC, DL, MVT::i8,
|
||||
DAG.getConstant(CC, MVT::i8), Cond);
|
||||
|
||||
@ -11368,7 +11380,6 @@ static SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG,
|
||||
// Optimize Cond ? cst+1 : cst -> zext(setcc(C)+cst. This is efficient
|
||||
// for any integer data type, including i8/i16.
|
||||
if (FalseC->getAPIntValue()+1 == TrueC->getAPIntValue()) {
|
||||
SDValue Cond = N->getOperand(3);
|
||||
Cond = DAG.getNode(X86ISD::SETCC, DL, MVT::i8,
|
||||
DAG.getConstant(CC, MVT::i8), Cond);
|
||||
|
||||
@ -11407,7 +11418,6 @@ static SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG,
|
||||
|
||||
if (isFastMultiplier) {
|
||||
APInt Diff = TrueC->getAPIntValue()-FalseC->getAPIntValue();
|
||||
SDValue Cond = N->getOperand(3);
|
||||
Cond = DAG.getNode(X86ISD::SETCC, DL, MVT::i8,
|
||||
DAG.getConstant(CC, MVT::i8), Cond);
|
||||
// Zero extend the condition if needed.
|
||||
|
@ -31,3 +31,18 @@ entry:
|
||||
}
|
||||
|
||||
declare i16 @llvm.ctlz.i16(i16) nounwind readnone
|
||||
|
||||
; Don't generate the cmovne when the source is known non-zero (and bsr would
|
||||
; not set ZF).
|
||||
; rdar://9490949
|
||||
|
||||
define i32 @t4(i32 %n) nounwind {
|
||||
entry:
|
||||
; CHECK: t4:
|
||||
; CHECK: bsrl
|
||||
; CHECK-NOT: cmov
|
||||
; CHECK: ret
|
||||
%or = or i32 %n, 1
|
||||
%tmp1 = tail call i32 @llvm.ctlz.i32(i32 %or)
|
||||
ret i32 %tmp1
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user