}
// (X & C) == 0 & X > -1 -> (X & (C | SignBit)) == 0
- if (LHS->hasOneUse() && RHS->hasOneUse() &&
- ((LHSCC == ICmpInst::ICMP_EQ && LHSCst->isZero() &&
- RHSCC == ICmpInst::ICMP_SGT && RHSCst->isAllOnesValue()) ||
- (RHSCC == ICmpInst::ICMP_EQ && RHSCst->isZero() &&
- LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue()))) {
- BinaryOperator *BO =
- dyn_cast<BinaryOperator>(LHSCC == ICmpInst::ICMP_EQ ? Val : Val2);
- ConstantInt *AndCst;
- if (BO && match(BO, m_OneUse(m_And(m_Value(), m_ConstantInt(AndCst))))) {
- APInt New = AndCst->getValue() | APInt::getSignBit(AndCst->getBitWidth());
- BO->setOperand(1, ConstantInt::get(AndCst->getContext(), New));
- return BO == Val ? LHS : RHS;
+ if ((LHSCC == ICmpInst::ICMP_EQ && LHSCst->isZero() &&
+ RHSCC == ICmpInst::ICMP_SGT && RHSCst->isAllOnesValue()) ||
+ (RHSCC == ICmpInst::ICMP_EQ && RHSCst->isZero() &&
+ LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue())) {
+ ICmpInst *I = LHSCC == ICmpInst::ICMP_EQ ? LHS : RHS;
+ Value *X; ConstantInt *C;
+ if (I->hasOneUse() &&
+ match(I->getOperand(0), m_OneUse(m_And(m_Value(X), m_ConstantInt(C))))){
+ APInt New = C->getValue() | APInt::getSignBit(C->getBitWidth());
+ return Builder->CreateICmpEQ(Builder->CreateAnd(X, Builder->getInt(New)),
+ I->getOperand(1));
}
}
}
}
- // (X & C) != 0 & X < 0 -> (X & (C | SignBit)) != 0
- if (LHS->hasOneUse() && RHS->hasOneUse() &&
- ((LHSCC == ICmpInst::ICMP_NE && LHSCst->isZero() &&
- RHSCC == ICmpInst::ICMP_SLT && RHSCst->isZero()) ||
- (RHSCC == ICmpInst::ICMP_NE && RHSCst->isZero() &&
- LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero()))) {
- BinaryOperator *BO =
- dyn_cast<BinaryOperator>(LHSCC == ICmpInst::ICMP_NE ? Val : Val2);
- ConstantInt *AndCst;
- if (BO && match(BO, m_OneUse(m_And(m_Value(), m_ConstantInt(AndCst))))) {
- APInt New = AndCst->getValue() | APInt::getSignBit(AndCst->getBitWidth());
- BO->setOperand(1, ConstantInt::get(AndCst->getContext(), New));
- return BO == Val ? LHS : RHS;
+ // (X & C) != 0 | X < 0 -> (X & (C | SignBit)) != 0
+ if ((LHSCC == ICmpInst::ICMP_NE && LHSCst->isZero() &&
+ RHSCC == ICmpInst::ICMP_SLT && RHSCst->isZero()) ||
+ (RHSCC == ICmpInst::ICMP_NE && RHSCst->isZero() &&
+ LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero())) {
+ ICmpInst *I = LHSCC == ICmpInst::ICMP_NE ? LHS : RHS;
+ Value *X; ConstantInt *C;
+ if (I->hasOneUse() &&
+ match(I->getOperand(0), m_OneUse(m_And(m_Value(X), m_ConstantInt(C))))){
+ APInt New = C->getValue() | APInt::getSignBit(C->getBitWidth());
+ return Builder->CreateICmpNE(Builder->CreateAnd(X, Builder->getInt(New)),
+ I->getOperand(1));
}
}
br i1 %or.cond, label %if.then, label %if.end
; CHECK: @test5
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
if.then:
tail call void @foo() nounwind
br i1 %or.cond, label %if.then, label %if.end
; CHECK: @test6
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
if.then:
tail call void @foo() nounwind
br i1 %or.cond, label %if.then, label %if.end
; CHECK: @test7
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.end, label %if.the
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
if.then:
tail call void @foo() nounwind
br i1 %or.cond, label %if.then, label %if.end
; CHECK: @test8
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.end, label %if.the
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
if.then:
tail call void @foo() nounwind