return false;
}
-/// Return true if the constant is of the form 1+0+. This is the same as
-/// lowones(~X).
-static bool isHighOnes(const ConstantInt *CI) {
- return (~CI->getValue() + 1).isPowerOf2();
-}
-
/// Given a signed integer type and a set of known zero and one bits, compute
/// the maximum and minimum values that could have the specified known zero and
/// known one bits, returning them in Min/Max.
}
break;
}
- case Instruction::And:
- // FIXME: Vectors are excluded by ConstantInt.
- if (ConstantInt *BOC = dyn_cast<ConstantInt>(BOp1)) {
+ case Instruction::And: {
+ const APInt *BOC;
+ if (match(BOp1, m_APInt(BOC))) {
// If we have ((X & C) == C), turn it into ((X & C) != 0).
- if (RHS == BOC && RHSV->isPowerOf2())
+ if (RHSV == BOC && RHSV->isPowerOf2())
return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE,
BO, Constant::getNullValue(RHS->getType()));
break;
// Replace (and X, (1 << size(X)-1) != 0) with x s< 0
- if (BOC->getValue().isSignBit()) {
+ if (BOC->isSignBit()) {
Constant *Zero = Constant::getNullValue(BOp0->getType());
ICmpInst::Predicate Pred =
isICMP_NE ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE;
}
// ((X & ~7) == 0) --> X < 8
- if (*RHSV == 0 && isHighOnes(BOC)) {
- Constant *NegX = ConstantExpr::getNeg(BOC);
+ if (*RHSV == 0 && (~(*BOC) + 1).isPowerOf2()) {
+ Constant *NegBOC = ConstantExpr::getNeg(cast<Constant>(BOp1));
ICmpInst::Predicate Pred =
isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT;
- return new ICmpInst(Pred, BOp0, NegX);
+ return new ICmpInst(Pred, BOp0, NegBOC);
}
}
break;
+ }
case Instruction::Mul:
if (*RHSV == 0 && BO->hasNoSignedWrap()) {
// FIXME: Vectors are excluded by ConstantInt.
ret i1 %C
}
-; FIXME: Vectors should fold the same way.
define <2 x i1> @test18_vec(<2 x i32> %A) {
; CHECK-LABEL: @test18_vec(
-; CHECK-NEXT: [[B:%.*]] = and <2 x i32> %A, <i32 -128, i32 -128>
-; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[B]], zeroinitializer
+; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i32> %A, <i32 127, i32 127>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%B = and <2 x i32> %A, <i32 -128, i32 -128>
ret i1 %C
}
-; FIXME: Vectors should fold the same way.
define <2 x i1> @test18a_vec(<2 x i8> %A) {
; CHECK-LABEL: @test18a_vec(
-; CHECK-NEXT: [[B:%.*]] = and <2 x i8> %A, <i8 -2, i8 -2>
-; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B]], zeroinitializer
+; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> %A, <i8 2, i8 2>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%B = and <2 x i8> %A, <i8 -2, i8 -2>
}
; FIXME: Vectors should fold the same way.
+
define <2 x i1> @test19vec(<2 x i32> %x) {
; CHECK-LABEL: @test19vec(
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> <i32 1, i32 1>, %x
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[SHL]], <i32 8, i32 8>
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], <i32 8, i32 8>
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%shl = shl <2 x i32> <i32 1, i32 1>, %x
define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) {
; CHECK-LABEL: @cmp_and_signbit_vec(
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i3> %x, <i3 -4, i3 -4>
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i3> [[AND]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i3> %x, zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%and = and <2 x i3> %x, <i3 4, i3 4>