forked from OSchip/llvm-project
[InstCombine] Use commutable matchers and m_OneUse in visitSub to shorten code. Add missing test cases.
In one case I removed commute handling for a multiply with a constant since we'll eventually get the constant on the right hand side. llvm-svn: 299863
This commit is contained in:
parent
59d309c7b5
commit
0d830ff7bf
|
@ -1633,18 +1633,16 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
|||
|
||||
// (sub (or A, B) (xor A, B)) --> (and A, B)
|
||||
{
|
||||
Value *A = nullptr, *B = nullptr;
|
||||
Value *A, *B;
|
||||
if (match(Op1, m_Xor(m_Value(A), m_Value(B))) &&
|
||||
(match(Op0, m_Or(m_Specific(A), m_Specific(B))) ||
|
||||
match(Op0, m_Or(m_Specific(B), m_Specific(A)))))
|
||||
match(Op0, m_c_Or(m_Specific(A), m_Specific(B))))
|
||||
return BinaryOperator::CreateAnd(A, B);
|
||||
}
|
||||
|
||||
if (Op0->hasOneUse()) {
|
||||
Value *Y = nullptr;
|
||||
{
|
||||
Value *Y;
|
||||
// ((X | Y) - X) --> (~X & Y)
|
||||
if (match(Op0, m_Or(m_Value(Y), m_Specific(Op1))) ||
|
||||
match(Op0, m_Or(m_Specific(Op1), m_Value(Y))))
|
||||
if (match(Op0, m_OneUse(m_c_Or(m_Value(Y), m_Specific(Op1)))))
|
||||
return BinaryOperator::CreateAnd(
|
||||
Y, Builder->CreateNot(Op1, Op1->getName() + ".not"));
|
||||
}
|
||||
|
@ -1652,7 +1650,6 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
|||
if (Op1->hasOneUse()) {
|
||||
Value *X = nullptr, *Y = nullptr, *Z = nullptr;
|
||||
Constant *C = nullptr;
|
||||
Constant *CI = nullptr;
|
||||
|
||||
// (X - (Y - Z)) --> (X + (Z - Y)).
|
||||
if (match(Op1, m_Sub(m_Value(Y), m_Value(Z))))
|
||||
|
@ -1661,8 +1658,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
|||
|
||||
// (X - (X & Y)) --> (X & ~Y)
|
||||
//
|
||||
if (match(Op1, m_And(m_Value(Y), m_Specific(Op0))) ||
|
||||
match(Op1, m_And(m_Specific(Op0), m_Value(Y))))
|
||||
if (match(Op1, m_c_And(m_Value(Y), m_Specific(Op0))))
|
||||
return BinaryOperator::CreateAnd(Op0,
|
||||
Builder->CreateNot(Y, Y->getName() + ".not"));
|
||||
|
||||
|
@ -1690,14 +1686,14 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
|||
// X - A*-B -> X + A*B
|
||||
// X - -A*B -> X + A*B
|
||||
Value *A, *B;
|
||||
if (match(Op1, m_Mul(m_Value(A), m_Neg(m_Value(B)))) ||
|
||||
match(Op1, m_Mul(m_Neg(m_Value(A)), m_Value(B))))
|
||||
Constant *CI;
|
||||
if (match(Op1, m_c_Mul(m_Value(A), m_Neg(m_Value(B)))))
|
||||
return BinaryOperator::CreateAdd(Op0, Builder->CreateMul(A, B));
|
||||
|
||||
// X - A*CI -> X + A*-CI
|
||||
// X - CI*A -> X + A*-CI
|
||||
if (match(Op1, m_Mul(m_Value(A), m_Constant(CI))) ||
|
||||
match(Op1, m_Mul(m_Constant(CI), m_Value(A)))) {
|
||||
// No need to handle commuted multiply because multiply handling will
|
||||
// ensure constant will be move to the right hand side.
|
||||
if (match(Op1, m_Mul(m_Value(A), m_Constant(CI)))) {
|
||||
Value *NewMul = Builder->CreateMul(A, ConstantExpr::getNeg(CI));
|
||||
return BinaryOperator::CreateAdd(Op0, NewMul);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,17 @@ define i32 @test6(i32 %A, i32 %B) {
|
|||
ret i32 %D
|
||||
}
|
||||
|
||||
define i32 @test6commuted(i32 %A, i32 %B) {
|
||||
; CHECK-LABEL: @test6commuted(
|
||||
; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1
|
||||
; CHECK-NEXT: [[D:%.*]] = and i32 [[B_NOT]], [[A:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[D]]
|
||||
;
|
||||
%C = and i32 %B, %A
|
||||
%D = sub i32 %A, %C
|
||||
ret i32 %D
|
||||
}
|
||||
|
||||
define i32 @test7(i32 %A) {
|
||||
; CHECK-LABEL: @test7(
|
||||
; CHECK-NEXT: [[B:%.*]] = xor i32 [[A:%.*]], -1
|
||||
|
@ -395,6 +406,83 @@ define i32 @test27(i32 %x, i32 %y) {
|
|||
ret i32 %sub
|
||||
}
|
||||
|
||||
define <2 x i32> @test27vec(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @test27vec(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 6>
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[SUB]]
|
||||
;
|
||||
%mul = mul <2 x i32> %y, <i32 -8, i32 -6>
|
||||
%sub = sub <2 x i32> %x, %mul
|
||||
ret <2 x i32> %sub
|
||||
}
|
||||
|
||||
define <2 x i32> @test27vecsplat(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @test27vecsplat(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 3, i32 3>
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[SUB]]
|
||||
;
|
||||
%mul = mul <2 x i32> %y, <i32 -8, i32 -8>
|
||||
%sub = sub <2 x i32> %x, %mul
|
||||
ret <2 x i32> %sub
|
||||
}
|
||||
|
||||
define <2 x i32> @test27vecmixed(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @test27vecmixed(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 -8>
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[SUB]]
|
||||
;
|
||||
%mul = mul <2 x i32> %y, <i32 -8, i32 8>
|
||||
%sub = sub <2 x i32> %x, %mul
|
||||
ret <2 x i32> %sub
|
||||
}
|
||||
|
||||
define i32 @test27commuted(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @test27commuted(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[Y:%.*]], 3
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[SUB]]
|
||||
;
|
||||
%mul = mul i32 -8, %y
|
||||
%sub = sub i32 %x, %mul
|
||||
ret i32 %sub
|
||||
}
|
||||
|
||||
define <2 x i32> @test27commutedvec(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @test27commutedvec(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 6>
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[SUB]]
|
||||
;
|
||||
%mul = mul <2 x i32> <i32 -8, i32 -6>, %y
|
||||
%sub = sub <2 x i32> %x, %mul
|
||||
ret <2 x i32> %sub
|
||||
}
|
||||
|
||||
define <2 x i32> @test27commutedvecsplat(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @test27commutedvecsplat(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 3, i32 3>
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[SUB]]
|
||||
;
|
||||
%mul = mul <2 x i32> <i32 -8, i32 -8>, %y
|
||||
%sub = sub <2 x i32> %x, %mul
|
||||
ret <2 x i32> %sub
|
||||
}
|
||||
|
||||
define <2 x i32> @test27commutedvecmixed(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @test27commutedvecmixed(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 -8>
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[SUB]]
|
||||
;
|
||||
%mul = mul <2 x i32> <i32 -8, i32 8>, %y
|
||||
%sub = sub <2 x i32> %x, %mul
|
||||
ret <2 x i32> %sub
|
||||
}
|
||||
|
||||
define i32 @test28(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK-LABEL: @test28(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[Z:%.*]], [[Y:%.*]]
|
||||
|
@ -407,6 +495,18 @@ define i32 @test28(i32 %x, i32 %y, i32 %z) {
|
|||
ret i32 %sub
|
||||
}
|
||||
|
||||
define i32 @test28commuted(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK-LABEL: @test28commuted(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[Y:%.*]], [[Z:%.*]]
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[SUB]]
|
||||
;
|
||||
%neg = sub i32 0, %z
|
||||
%mul = mul i32 %y, %neg
|
||||
%sub = sub i32 %x, %mul
|
||||
ret i32 %sub
|
||||
}
|
||||
|
||||
define i64 @test29(i8* %foo, i64 %i, i64 %j) {
|
||||
; CHECK-LABEL: @test29(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
|
||||
|
@ -614,6 +714,17 @@ define i32 @test45(i32 %x, i32 %y) {
|
|||
ret i32 %sub
|
||||
}
|
||||
|
||||
define i32 @test45commuted(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @test45commuted(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[SUB]]
|
||||
;
|
||||
%or = or i32 %x, %y
|
||||
%xor = xor i32 %y, %x
|
||||
%sub = sub i32 %or, %xor
|
||||
ret i32 %sub
|
||||
}
|
||||
|
||||
define i32 @test46(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @test46(
|
||||
; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
|
||||
|
@ -625,6 +736,17 @@ define i32 @test46(i32 %x, i32 %y) {
|
|||
ret i32 %sub
|
||||
}
|
||||
|
||||
define i32 @test46commuted(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @test46commuted(
|
||||
; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
|
||||
; CHECK-NEXT: [[SUB:%.*]] = and i32 [[X_NOT]], [[Y:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[SUB]]
|
||||
;
|
||||
%or = or i32 %y, %x
|
||||
%sub = sub i32 %or, %x
|
||||
ret i32 %sub
|
||||
}
|
||||
|
||||
define i32 @test47(i1 %A, i32 %B, i32 %C, i32 %D) {
|
||||
; CHECK-LABEL: @test47(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[D:%.*]], [[C:%.*]]
|
||||
|
|
Loading…
Reference in New Issue