diff options
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 26 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/shift-i128.ll | 18 |
2 files changed, 33 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d1727a15ea0..c449c7d4070 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4518,18 +4518,22 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { N0.getOperand(0).getOpcode() == ISD::SHL) { SDValue N0Op0 = N0.getOperand(0); if (ConstantSDNode *N0Op0C1 = isConstOrConstSplat(N0Op0.getOperand(1))) { - uint64_t c1 = N0Op0C1->getZExtValue(); - uint64_t c2 = N1C->getZExtValue(); + APInt c1 = N0Op0C1->getAPIntValue(); + APInt c2 = N1C->getAPIntValue(); + zeroExtendToMatch(c1, c2, 1 /* Overflow Bit */); + EVT InnerShiftVT = N0Op0.getValueType(); uint64_t InnerShiftSize = InnerShiftVT.getScalarSizeInBits(); - if (c2 >= OpSizeInBits - InnerShiftSize) { + if (c2.uge(OpSizeInBits - InnerShiftSize)) { SDLoc DL(N0); - if (c1 + c2 >= OpSizeInBits) + APInt Sum = c1 + c2; + if (Sum.uge(OpSizeInBits)) return DAG.getConstant(0, DL, VT); - return DAG.getNode(ISD::SHL, DL, VT, - DAG.getNode(N0.getOpcode(), DL, VT, - N0Op0->getOperand(0)), - DAG.getConstant(c1 + c2, DL, N1.getValueType())); + + return DAG.getNode( + ISD::SHL, DL, VT, + DAG.getNode(N0.getOpcode(), DL, VT, N0Op0->getOperand(0)), + DAG.getConstant(Sum.getZExtValue(), DL, N1.getValueType())); } } } @@ -5264,11 +5268,11 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { if (N0->getOpcode() == ISD::XOR) { if (auto *C = dyn_cast<ConstantSDNode>(N0->getOperand(1))) { SDValue Cond0 = N0->getOperand(0); - if (C->isOne()) - return DAG.getNode(ISD::SELECT, SDLoc(N), N1.getValueType(), + if (C->isOne()) + return DAG.getNode(ISD::SELECT, SDLoc(N), N1.getValueType(), Cond0, N2, N1); else - return DAG.getNode(ISD::SELECT, SDLoc(N), N1.getValueType(), + return DAG.getNode(ISD::SELECT, SDLoc(N), N1.getValueType(), Cond0, N1, N2); } } diff --git a/llvm/test/CodeGen/X86/shift-i128.ll b/llvm/test/CodeGen/X86/shift-i128.ll index aef923f8d10..1de99b15e42 100644 --- a/llvm/test/CodeGen/X86/shift-i128.ll +++ b/llvm/test/CodeGen/X86/shift-i128.ll @@ -116,3 +116,21 @@ entry: store <2 x i128> %1, <2 x i128>* %r, align 16 ret void } + +; +; Combines +; + +define <2 x i256> @shl_sext_shl_outofrange(<2 x i128> %a0) { + %1 = shl <2 x i128> %a0, <i128 -1, i128 -1> + %2 = sext <2 x i128> %1 to <2 x i256> + %3 = shl <2 x i256> %2, <i256 128, i256 128> + ret <2 x i256> %3 +} + +define <2 x i256> @shl_zext_shl_outofrange(<2 x i128> %a0) { + %1 = shl <2 x i128> %a0, <i128 -1, i128 -1> + %2 = zext <2 x i128> %1 to <2 x i256> + %3 = shl <2 x i256> %2, <i256 128, i256 128> + ret <2 x i256> %3 +} |