diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2480,6 +2480,22 @@ if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse()) { SelOpNo = 1; Sel = BO->getOperand(1); + + // Peek through any trunc/zext to shift amount type. + if ((BinOpcode == ISD::SHL || BinOpcode == ISD::SRA || + BinOpcode == ISD::SRL) && Sel.hasOneUse()) { + // This is valid when the truncated bits of x are already zero. + SDValue Op; + KnownBits Known; + if (isTruncateOf(DAG, Sel, Op, Known)) { + APInt TruncatedBits = + APInt::getBitsSet(Op.getScalarValueSizeInBits(), + Sel.getScalarValueSizeInBits(), + Op.getScalarValueSizeInBits()); + if (TruncatedBits.isSubsetOf(Known.Zero)) + Sel = Op; + } + } } if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse())