// (A | B) ^ (A & B) -> A ^ B
// (A | B) ^ (B & A) -> A ^ B
if (match(&I, m_c_Xor(m_And(m_Value(A), m_Value(B)),
- m_c_Or(m_Deferred(A), m_Deferred(B))))) {
- I.setOperand(0, A);
- I.setOperand(1, B);
- return &I;
- }
+ m_c_Or(m_Deferred(A), m_Deferred(B)))))
+ return BinaryOperator::CreateXor(A, B);
// (A | ~B) ^ (~A | B) -> A ^ B
// (~B | A) ^ (~A | B) -> A ^ B
// (~A | B) ^ (A | ~B) -> A ^ B
// (B | ~A) ^ (A | ~B) -> A ^ B
if (match(&I, m_Xor(m_c_Or(m_Value(A), m_Not(m_Value(B))),
- m_c_Or(m_Not(m_Deferred(A)), m_Deferred(B))))) {
- I.setOperand(0, A);
- I.setOperand(1, B);
- return &I;
- }
+ m_c_Or(m_Not(m_Deferred(A)), m_Deferred(B)))))
+ return BinaryOperator::CreateXor(A, B);
// (A & ~B) ^ (~A & B) -> A ^ B
// (~B & A) ^ (~A & B) -> A ^ B
// (~A & B) ^ (A & ~B) -> A ^ B
// (B & ~A) ^ (A & ~B) -> A ^ B
if (match(&I, m_Xor(m_c_And(m_Value(A), m_Not(m_Value(B))),
- m_c_And(m_Not(m_Deferred(A)), m_Deferred(B))))) {
- I.setOperand(0, A);
- I.setOperand(1, B);
- return &I;
- }
+ m_c_And(m_Not(m_Deferred(A)), m_Deferred(B)))))
+ return BinaryOperator::CreateXor(A, B);
// For the remaining cases we need to get rid of one of the operands.
if (!Op0->hasOneUse() && !Op1->hasOneUse())
MaskedValueIsZero(X, *C, 0, &I)) {
Constant *NewC = ConstantInt::get(I.getType(), *C ^ *RHSC);
Worklist.push(cast<Instruction>(Op0));
- I.setOperand(0, X);
- I.setOperand(1, NewC);
- return &I;
+ return BinaryOperator::CreateXor(X, NewC);
}
}
}
if (Cmp.getPredicate() == ICmpInst::ICMP_NE)
return replaceInstUsesWith(Cmp, ConstantInt::getTrue(Cmp.getType()));
} else {
- Cmp.setOperand(1, ConstantInt::get(And->getType(), NewCst));
APInt NewAndCst = IsShl ? C2.lshr(*C3) : C2.shl(*C3);
- And->setOperand(1, ConstantInt::get(And->getType(), NewAndCst));
- And->setOperand(0, Shift->getOperand(0));
- Worklist.push(Shift); // Shift is dead.
- return &Cmp;
+ Value *NewAnd = Builder.CreateAnd(
+ Shift->getOperand(0), ConstantInt::get(And->getType(), NewAndCst));
+ return new ICmpInst(Cmp.getPredicate(),
+ NewAnd, ConstantInt::get(And->getType(), NewCst));
}
}
}
if (X) { // Build (X^Y) & Z
Op1 = Builder.CreateXor(X, Y);
Op1 = Builder.CreateAnd(Op1, Z);
- I.setOperand(0, Op1);
- I.setOperand(1, Constant::getNullValue(Op1->getType()));
- return &I;
+ return new ICmpInst(Pred, Op1, Constant::getNullValue(Op1->getType()));
}
}
else
Elts.push_back(ConstantInt::get(Int32Ty, Mask[i] % LHSWidth));
}
- SVI.setOperand(0, SVI.getOperand(1));
- SVI.setOperand(1, UndefValue::get(RHS->getType()));
- SVI.setOperand(2, ConstantVector::get(Elts));
- return &SVI;
+ return new ShuffleVectorInst(LHS, UndefValue::get(RHS->getType()),
+ ConstantVector::get(Elts));
}
// shuffle undef, x, mask --> shuffle x, undef, mask'
; Variation of the above with an ashr
define i1 @icmp_and_ashr_multiuse(i32 %X) {
; CHECK-LABEL: @icmp_and_ashr_multiuse(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240
-; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
-; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
+; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
+; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
; CHECK-NEXT: ret i1 [[AND3]]
;
define i32 @test6(i32 %a, i32 %b) {
; CHECK-LABEL: @test6(
-; CHECK-NEXT: [[E:%.*]] = ashr i32 [[A:%.*]], 31
-; CHECK-NEXT: [[F:%.*]] = and i32 [[E]], [[B:%.*]]
+; CHECK-NEXT: [[A_LOBIT_NEG:%.*]] = ashr i32 [[A:%.*]], 31
+; CHECK-NEXT: [[F:%.*]] = and i32 [[A_LOBIT_NEG]], [[B:%.*]]
; CHECK-NEXT: ret i32 [[F]]
;
%c = icmp sle i32 %a, -1
define i1 @icmp_add_and_shr_ne_0(i32 %X) {
; CHECK-LABEL: @icmp_add_and_shr_ne_0(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
; CHECK-NEXT: ret i1 [[TOBOOL]]
;
%shr = lshr i32 %X, 4
define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec(
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240>
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[AND]], <i32 224, i32 224>
+; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240>
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 224, i32 224>
; CHECK-NEXT: ret <2 x i1> [[TOBOOL]]
;
%shr = lshr <2 x i32> %X, <i32 4, i32 4>
; Variation of the above with an extra use of the shift
define i1 @icmp_and_shr_multiuse(i32 %X) {
; CHECK-LABEL: @icmp_and_shr_multiuse(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240
-; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
-; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
+; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
+; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
; CHECK-NEXT: ret i1 [[AND3]]
;
; Variation of the above with an ashr
define i1 @icmp_and_ashr_multiuse(i32 %X) {
; CHECK-LABEL: @icmp_and_ashr_multiuse(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240
-; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
-; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
+; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
+; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
; CHECK-NEXT: ret i1 [[AND3]]
;