forked from OSchip/llvm-project
[InstCombine] Support (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) for vector splats.
llvm-svn: 310233
This commit is contained in:
parent
9cbdbefd0f
commit
a1693a2ed3
|
@ -126,14 +126,6 @@ Instruction *InstCombiner::OptAndOp(BinaryOperator *Op,
|
||||||
|
|
||||||
switch (Op->getOpcode()) {
|
switch (Op->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case Instruction::Xor:
|
|
||||||
if (Op->hasOneUse()) {
|
|
||||||
// (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
|
|
||||||
Value *And = Builder.CreateAnd(X, AndRHS);
|
|
||||||
And->takeName(Op);
|
|
||||||
return BinaryOperator::CreateXor(And, Together);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Instruction::Or:
|
case Instruction::Or:
|
||||||
if (Op->hasOneUse()){
|
if (Op->hasOneUse()){
|
||||||
ConstantInt *TogetherCI = dyn_cast<ConstantInt>(Together);
|
ConstantInt *TogetherCI = dyn_cast<ConstantInt>(Together);
|
||||||
|
@ -1280,6 +1272,15 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||||
return new ZExtInst(IsZero, I.getType());
|
return new ZExtInst(IsZero, I.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const APInt *XorC;
|
||||||
|
if (match(Op0, m_OneUse(m_Xor(m_Value(X), m_APInt(XorC))))) {
|
||||||
|
// (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
|
||||||
|
Constant *NewC = ConstantInt::get(I.getType(), *C & *XorC);
|
||||||
|
Value *And = Builder.CreateAnd(X, Op1);
|
||||||
|
And->takeName(Op0);
|
||||||
|
return BinaryOperator::CreateXor(And, NewC);
|
||||||
|
}
|
||||||
|
|
||||||
// If the mask is only needed on one incoming arm, push the 'and' op up.
|
// If the mask is only needed on one incoming arm, push the 'and' op up.
|
||||||
if (match(Op0, m_OneUse(m_Xor(m_Value(X), m_Value(Y)))) ||
|
if (match(Op0, m_OneUse(m_Xor(m_Value(X), m_Value(Y)))) ||
|
||||||
match(Op0, m_OneUse(m_Or(m_Value(X), m_Value(Y))))) {
|
match(Op0, m_OneUse(m_Or(m_Value(X), m_Value(Y))))) {
|
||||||
|
@ -1298,6 +1299,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||||
return BinaryOperator::Create(BinOp, NewLHS, Y);
|
return BinaryOperator::Create(BinOp, NewLHS, Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(Op1)) {
|
if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(Op1)) {
|
||||||
|
|
|
@ -39,8 +39,8 @@ define i32 @flip_and_mask(i32 %x) {
|
||||||
|
|
||||||
define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) {
|
define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) {
|
||||||
; CHECK-LABEL: @flip_and_mask_splat(
|
; CHECK-LABEL: @flip_and_mask_splat(
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> %x, <i8 1, i8 1>
|
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> %x, <i8 1, i8 1>
|
||||||
; CHECK-NEXT: [[INC:%.*]] = and <2 x i8> [[TMP1]], <i8 1, i8 1>
|
; CHECK-NEXT: [[INC:%.*]] = xor <2 x i8> [[TMP1]], <i8 1, i8 1>
|
||||||
; CHECK-NEXT: ret <2 x i8> [[INC]]
|
; CHECK-NEXT: ret <2 x i8> [[INC]]
|
||||||
;
|
;
|
||||||
%shl = shl <2 x i8> %x, <i8 7, i8 7>
|
%shl = shl <2 x i8> %x, <i8 7, i8 7>
|
||||||
|
|
Loading…
Reference in New Issue