diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-02-12 23:07:52 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-02-12 23:07:52 +0000 |
commit | 0557a44287f4796707323e22732ebed9c3f7b905 (patch) | |
tree | e508ae739458af81628c15377caa28ae210f21e3 /llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | |
parent | 31e1b8fe482970e11cb61b432bd24b4840b7e373 (diff) | |
download | bcm5719-llvm-0557a44287f4796707323e22732ebed9c3f7b905.tar.gz bcm5719-llvm-0557a44287f4796707323e22732ebed9c3f7b905.zip |
[TargetLowering] fix SETCC SETLT folding with FP types
The bug was introduced with:
https://reviews.llvm.org/rL294863
...and manifests as a selection failure in x86, but that's actually
another bug. This fix prevents wrong codegen with -0.0, but in the
more common case when we have NSZ and NNAN (-ffast-math), we should
still be able to fold this setcc/compare.
llvm-svn: 294924
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 3db7c8202d6..3785f402c3e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -751,25 +751,29 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, KnownOne &= KnownOne2; KnownZero &= KnownZero2; break; - case ISD::SETCC: + case ISD::SETCC: { + SDValue Op0 = Op.getOperand(0); + SDValue Op1 = Op.getOperand(1); + ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); // If (1) we only need the sign-bit, (2) the setcc operands are the same // width as the setcc result, and (3) the result of a setcc conforms to 0 or // -1, we may be able to bypass the setcc. - if (NewMask.isSignBit() && - Op.getOperand(0).getScalarValueSizeInBits() == BitWidth && + if (NewMask.isSignBit() && Op0.getScalarValueSizeInBits() == BitWidth && getBooleanContents(Op.getValueType()) == BooleanContent::ZeroOrNegativeOneBooleanContent) { - ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); - // If we're testing if X < 0, then this compare isn't needed - just use X! - if (CC == ISD::SETLT && - (isNullConstant(Op.getOperand(1)) || - ISD::isBuildVectorAllZeros(Op.getOperand(1).getNode()))) - return TLO.CombineTo(Op, Op.getOperand(0)); + // If we're testing X < 0, then this compare isn't needed - just use X! + // FIXME: We're limiting to integer types here, but this should also work + // if we don't care about FP signed-zero. The use of SETLT with FP means + // that we don't care about NaNs. + if (CC == ISD::SETLT && Op1.getValueType().isInteger() && + (isNullConstant(Op1) || ISD::isBuildVectorAllZeros(Op1.getNode()))) + return TLO.CombineTo(Op, Op0); // TODO: Should we check for other forms of sign-bit comparisons? // Examples: X <= -1, X >= 0 } break; + } case ISD::SHL: if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { unsigned ShAmt = SA->getZExtValue(); |