return nullptr;
}
+/// \brief Given operands for an Shl, LShr or AShr, see if we can
+/// fold the result. If not, this returns null.
+static Value *SimplifyRightShift(unsigned Opcode, Value *Op0, Value *Op1,
+ bool isExact, const Query &Q,
+ unsigned MaxRecurse) {
+ if (Value *V = SimplifyShift(Opcode, Op0, Op1, Q, MaxRecurse))
+ return V;
+
+ // X >> X -> 0
+ if (Op0 == Op1)
+ return Constant::getNullValue(Op0->getType());
+
+ // The low bit cannot be shifted out of an exact shift if it is set.
+ if (isExact) {
+ unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
+ APInt Op0KnownZero(BitWidth, 0);
+ APInt Op0KnownOne(BitWidth, 0);
+ computeKnownBits(Op0, Op0KnownZero, Op0KnownOne, Q.DL, /*Depth=*/0, Q.AT, Q.CxtI,
+ Q.DT);
+ if (Op0KnownOne[0])
+ return Op0;
+ }
+
+ return nullptr;
+}
+
/// SimplifyShlInst - Given operands for an Shl, see if we can
/// fold the result. If not, this returns null.
static Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
/// fold the result. If not, this returns null.
static Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
const Query &Q, unsigned MaxRecurse) {
- if (Value *V = SimplifyShift(Instruction::LShr, Op0, Op1, Q, MaxRecurse))
- return V;
-
- // X >> X -> 0
- if (Op0 == Op1)
- return Constant::getNullValue(Op0->getType());
+ if (Value *V = SimplifyRightShift(Instruction::LShr, Op0, Op1, isExact, Q,
+ MaxRecurse))
+ return V;
// undef >>l X -> 0
if (match(Op0, m_Undef()))
/// fold the result. If not, this returns null.
static Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
const Query &Q, unsigned MaxRecurse) {
- if (Value *V = SimplifyShift(Instruction::AShr, Op0, Op1, Q, MaxRecurse))
+ if (Value *V = SimplifyRightShift(Instruction::AShr, Op0, Op1, isExact, Q,
+ MaxRecurse))
return V;
- // X >> X -> 0
- if (Op0 == Op1)
- return Constant::getNullValue(Op0->getType());
-
// all ones >>a X -> all ones
if (match(Op0, m_AllOnes()))
return Op0;