Index: include/llvm/CodeGen/SelectionDAGNodes.h =================================================================== --- include/llvm/CodeGen/SelectionDAGNodes.h +++ include/llvm/CodeGen/SelectionDAGNodes.h @@ -1401,16 +1401,24 @@ /// Returns true if \p V is a constant integer zero. bool isNullConstant(SDValue V); + /// Returns true if \p V is an FP constant with a value of positive zero. bool isNullFPConstant(SDValue V); + /// Returns true if \p V is an integer constant with all bits set. bool isAllOnesConstant(SDValue V); + /// Returns true if \p V is a constant integer one. bool isOneConstant(SDValue V); + /// Returns true if \p V is a bitwise not operation. Assumes that an all ones /// constant is canonicalized to be operand 1. bool isBitwiseNot(SDValue V); +/// Returns the SDNode if it is a constant splat BuildVector or constant int. +ConstantSDNode *isConstOrConstSplat(SDValue N); + + class GlobalAddressSDNode : public SDNode { const GlobalValue *TheGlobal; int64_t Offset; Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -787,27 +787,6 @@ } // \brief Returns the SDNode if it is a constant splat BuildVector or constant -// int. -static ConstantSDNode *isConstOrConstSplat(SDValue N) { - if (ConstantSDNode *CN = dyn_cast(N)) - return CN; - - if (BuildVectorSDNode *BV = dyn_cast(N)) { - BitVector UndefElements; - ConstantSDNode *CN = BV->getConstantSplatNode(&UndefElements); - - // BuildVectors can truncate their operands. Ignore that case here. - // FIXME: We blindly ignore splats which include undef which is overly - // pessimistic. - if (CN && UndefElements.none() && - CN->getValueType(0) == N.getValueType().getScalarType()) - return CN; - } - - return nullptr; -} - -// \brief Returns the SDNode if it is a constant splat BuildVector or constant // float. static ConstantFPSDNode *isConstOrConstSplatFP(SDValue N) { if (ConstantFPSDNode *CN = dyn_cast(N)) Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2697,7 +2697,7 @@ if (Tmp2 == 1) return 1; // Handle NEG. - if (ConstantSDNode *CLHS = dyn_cast(Op.getOperand(0))) + if (ConstantSDNode *CLHS = isConstOrConstSplat(Op.getOperand(0))) if (CLHS->isNullValue()) { APInt KnownZero, KnownOne; computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); @@ -6653,6 +6653,25 @@ return V.getOpcode() == ISD::XOR && isAllOnesConstant(V.getOperand(1)); } +ConstantSDNode *llvm::isConstOrConstSplat(SDValue N) { + if (ConstantSDNode *CN = dyn_cast(N)) + return CN; + + if (BuildVectorSDNode *BV = dyn_cast(N)) { + BitVector UndefElements; + ConstantSDNode *CN = BV->getConstantSplatNode(&UndefElements); + + // BuildVectors can truncate their operands. Ignore that case here. + // FIXME: We blindly ignore splats which include undef which is overly + // pessimistic. + if (CN && UndefElements.none() && + CN->getValueType(0) == N.getValueType().getScalarType()) + return CN; + } + + return nullptr; +} + HandleSDNode::~HandleSDNode() { DropOperands(); } Index: test/CodeGen/X86/sar_fold64.ll =================================================================== --- test/CodeGen/X86/sar_fold64.ll +++ test/CodeGen/X86/sar_fold64.ll @@ -80,16 +80,6 @@ ; CHECK-NEXT: pxor %xmm1, %xmm1 ; CHECK-NEXT: psubd %xmm0, %xmm1 ; CHECK-NEXT: movdqa %xmm1, %xmm0 -; CHECK-NEXT: psrad $31, %xmm0 -; CHECK-NEXT: movdqa %xmm1, %xmm2 -; CHECK-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1] -; CHECK-NEXT: pshufd {{.*#+}} xmm2 = xmm2[1,3,2,3] -; CHECK-NEXT: movdqa %xmm1, %xmm0 -; CHECK-NEXT: psrad $5, %xmm0 -; CHECK-NEXT: psrad $1, %xmm1 -; CHECK-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] -; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] -; CHECK-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1] ; CHECK-NEXT: retq ; %and = and <4 x i32> %x,