forked from OSchip/llvm-project
[InstCombine] Support ~(c-X) --> X+(-c-1) and ~(X-c) --> (-c-1)-X for splat vectors.
llvm-svn: 310195
This commit is contained in:
parent
5b307cdb8a
commit
b5bf016015
|
@ -2419,17 +2419,33 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
|||
return replaceInstUsesWith(I, Op0);
|
||||
}
|
||||
|
||||
{
|
||||
const APInt *RHSC;
|
||||
if (match(Op1, m_APInt(RHSC))) {
|
||||
Value *V;
|
||||
const APInt *C;
|
||||
if (match(Op0, m_Sub(m_APInt(C), m_Value(V)))) {
|
||||
// ~(c-X) == X-c-1 == X+(-c-1)
|
||||
if (RHSC->isAllOnesValue()) {
|
||||
Constant *NewC = ConstantInt::get(I.getType(), -(*C) - 1);
|
||||
return BinaryOperator::CreateAdd(V, NewC);
|
||||
}
|
||||
} else if (match(Op0, m_Add(m_Value(V), m_APInt(C)))) {
|
||||
// ~(X-c) --> (-c-1)-X
|
||||
if (RHSC->isAllOnesValue()) {
|
||||
Constant *NewC = ConstantInt::get(I.getType(), -(*C) - 1);
|
||||
return BinaryOperator::CreateSub(NewC, V);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ConstantInt *RHSC = dyn_cast<ConstantInt>(Op1)) {
|
||||
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
|
||||
// ~(c-X) == X-c-1 == X+(-c-1)
|
||||
if (Op0I->getOpcode() == Instruction::Sub)
|
||||
if (ConstantInt *Op0I0C = dyn_cast<ConstantInt>(Op0I->getOperand(0))) {
|
||||
if (RHSC->isMinusOne()) {
|
||||
Constant *NegOp0I0C = ConstantExpr::getNeg(Op0I0C);
|
||||
return BinaryOperator::CreateAdd(Op0I->getOperand(1),
|
||||
SubOne(NegOp0I0C));
|
||||
} else if (RHSC->getValue().isSignMask()) {
|
||||
// (C - X) ^ signmask -> (C + signmask - X)
|
||||
// (C - X) ^ signmask -> (C + signmask - X)
|
||||
if (RHSC->getValue().isSignMask()) {
|
||||
Constant *C = Builder.getInt(RHSC->getValue() + Op0I0C->getValue());
|
||||
return BinaryOperator::CreateSub(C, Op0I->getOperand(1));
|
||||
}
|
||||
|
@ -2437,13 +2453,8 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
|||
|
||||
if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
|
||||
if (Op0I->getOpcode() == Instruction::Add) {
|
||||
// ~(X-c) --> (-c-1)-X
|
||||
if (RHSC->isMinusOne()) {
|
||||
Constant *NegOp0CI = ConstantExpr::getNeg(Op0CI);
|
||||
return BinaryOperator::CreateSub(SubOne(NegOp0CI),
|
||||
Op0I->getOperand(0));
|
||||
} else if (RHSC->getValue().isSignMask()) {
|
||||
// (X + C) ^ signmask -> (X + C + signmask)
|
||||
// (X + C) ^ signmask -> (X + C + signmask)
|
||||
if (RHSC->getValue().isSignMask()) {
|
||||
Constant *C = Builder.getInt(RHSC->getValue() + Op0CI->getValue());
|
||||
return BinaryOperator::CreateAdd(Op0I->getOperand(0), C);
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ for.cond:
|
|||
%input_1.addr.1 = phi <3 x i32> [ undef, %entry ], [ %dec43, %for.body ]
|
||||
br i1 undef, label %for.end, label %for.body
|
||||
|
||||
; CHECK: extractelement <3 x i32> %{{.*}}, i32 0
|
||||
; CHECK-NOT: extractelement <3 x i32> %{{.*}}, i32 0
|
||||
for.body:
|
||||
%dec43 = add <3 x i32> %input_1.addr.1, <i32 -1, i32 -1, i32 -1>
|
||||
%sub44 = sub <3 x i32> <i32 -1, i32 -1, i32 -1>, %dec43
|
||||
|
|
|
@ -188,6 +188,16 @@ define i32 @test15(i32 %A) {
|
|||
ret i32 %C
|
||||
}
|
||||
|
||||
define <2 x i32> @test15vec(<2 x i32> %A) {
|
||||
; CHECK-LABEL: @test15vec(
|
||||
; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> zeroinitializer, [[A:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[C]]
|
||||
;
|
||||
%B = add <2 x i32> %A, <i32 -1, i32 -1>
|
||||
%C = xor <2 x i32> %B, <i32 -1, i32 -1>
|
||||
ret <2 x i32> %C
|
||||
}
|
||||
|
||||
define i32 @test16(i32 %A) {
|
||||
; CHECK-LABEL: @test16(
|
||||
; CHECK-NEXT: [[C:%.*]] = sub i32 -124, %A
|
||||
|
@ -198,6 +208,16 @@ define i32 @test16(i32 %A) {
|
|||
ret i32 %C
|
||||
}
|
||||
|
||||
define <2 x i32> @test16vec(<2 x i32> %A) {
|
||||
; CHECK-LABEL: @test16vec(
|
||||
; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> <i32 -124, i32 -124>, [[A:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[C]]
|
||||
;
|
||||
%B = add <2 x i32> %A, <i32 123, i32 123>
|
||||
%C = xor <2 x i32> %B, <i32 -1, i32 -1>
|
||||
ret <2 x i32> %C
|
||||
}
|
||||
|
||||
define i32 @test17(i32 %A) {
|
||||
; CHECK-LABEL: @test17(
|
||||
; CHECK-NEXT: [[C:%.*]] = add i32 %A, -124
|
||||
|
@ -208,6 +228,16 @@ define i32 @test17(i32 %A) {
|
|||
ret i32 %C
|
||||
}
|
||||
|
||||
define <2 x i32> @test17vec(<2 x i32> %A) {
|
||||
; CHECK-LABEL: @test17vec(
|
||||
; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[A:%.*]], <i32 -124, i32 -124>
|
||||
; CHECK-NEXT: ret <2 x i32> [[C]]
|
||||
;
|
||||
%B = sub <2 x i32> <i32 123, i32 123>, %A
|
||||
%C = xor <2 x i32> %B, <i32 -1, i32 -1>
|
||||
ret <2 x i32> %C
|
||||
}
|
||||
|
||||
define i32 @test18(i32 %A) {
|
||||
; CHECK-LABEL: @test18(
|
||||
; CHECK-NEXT: [[C:%.*]] = add i32 %A, 124
|
||||
|
|
Loading…
Reference in New Issue