1
0
mirror of https://github.com/c64scene-ar/llvm-6502.git synced 2025-03-05 12:31:46 +00:00

Move optimization of some cases of (A & C1)|(B & C2) from instcombine to instsimplify. Patch by Rahul Jain, plus some last minute changes by me -- you can blame me for any bugs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211252 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky 2014-06-19 03:51:46 +00:00
parent 650b6ea893
commit fe3a219355
3 changed files with 69 additions and 23 deletions
lib
test/Transforms/InstSimplify

@ -1625,6 +1625,38 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const Query &Q,
MaxRecurse))
return V;
// (A & C)|(B & D)
Value *C = nullptr, *D = nullptr;
if (match(Op0, m_And(m_Value(A), m_Value(C))) &&
match(Op1, m_And(m_Value(B), m_Value(D)))) {
ConstantInt *C1 = dyn_cast<ConstantInt>(C);
ConstantInt *C2 = dyn_cast<ConstantInt>(D);
if (C1 && C2 && (C1->getValue() == ~C2->getValue())) {
// (A & C1)|(B & C2)
// If we have: ((V + N) & C1) | (V & C2)
// .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
// replace with V+N.
Value *V1, *V2;
if ((C2->getValue() & (C2->getValue() + 1)) == 0 && // C2 == 0+1+
match(A, m_Add(m_Value(V1), m_Value(V2)))) {
// Add commutes, try both ways.
if (V1 == B && MaskedValueIsZero(V2, C2->getValue()))
return A;
if (V2 == B && MaskedValueIsZero(V1, C2->getValue()))
return A;
}
// Or commutes, try both ways.
if ((C1->getValue() & (C1->getValue() + 1)) == 0 &&
match(B, m_Add(m_Value(V1), m_Value(V2)))) {
// Add commutes, try both ways.
if (V1 == A && MaskedValueIsZero(V2, C1->getValue()))
return B;
if (V2 == A && MaskedValueIsZero(V1, C1->getValue()))
return B;
}
}
}
// If the operation is with the result of a phi instruction, check whether
// operating on all incoming values of the phi always yields the same value.
if (isa<PHINode>(Op0) || isa<PHINode>(Op1))

@ -1996,29 +1996,6 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
C1 = dyn_cast<ConstantInt>(C);
C2 = dyn_cast<ConstantInt>(D);
if (C1 && C2) { // (A & C1)|(B & C2)
// If we have: ((V + N) & C1) | (V & C2)
// .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
// replace with V+N.
if (C1->getValue() == ~C2->getValue()) {
if ((C2->getValue() & (C2->getValue()+1)) == 0 && // C2 == 0+1+
match(A, m_Add(m_Value(V1), m_Value(V2)))) {
// Add commutes, try both ways.
if (V1 == B && MaskedValueIsZero(V2, C2->getValue()))
return ReplaceInstUsesWith(I, A);
if (V2 == B && MaskedValueIsZero(V1, C2->getValue()))
return ReplaceInstUsesWith(I, A);
}
// Or commutes, try both ways.
if ((C1->getValue() & (C1->getValue()+1)) == 0 &&
match(B, m_Add(m_Value(V1), m_Value(V2)))) {
// Add commutes, try both ways.
if (V1 == A && MaskedValueIsZero(V2, C1->getValue()))
return ReplaceInstUsesWith(I, B);
if (V2 == A && MaskedValueIsZero(V1, C1->getValue()))
return ReplaceInstUsesWith(I, B);
}
}
if ((C1->getValue() & C2->getValue()) == 0) {
// ((V | N) & C1) | (V & C2) --> (V|N) & (C1|C2)
// iff (C1&C2) == 0 and (N&~C1) == 0

@ -0,0 +1,37 @@
; RUN: opt < %s -instsimplify -S | not grep or
; Test the case where integer BitWidth <= 64 && BitWidth % 2 != 0.
define i39 @test1(i39 %V, i39 %M) {
;; If we have: ((V + N) & C1) | (V & C2)
;; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
;; replace with V+N.
%C1 = xor i39 274877906943, -1 ;; C2 = 274877906943
%N = and i39 %M, 274877906944
%A = add i39 %V, %N
%B = and i39 %A, %C1
%D = and i39 %V, 274877906943
%R = or i39 %B, %D
ret i39 %R
; CHECK-LABEL @test1
; CHECK-NEXT: and {{.*}}, -274877906944
; CHECK-NEXT: add
; CHECK-NEXT: ret
}
; Test the case where Integer BitWidth > 64 && BitWidth <= 1024.
define i399 @test2(i399 %V, i399 %M) {
;; If we have: ((V + N) & C1) | (V & C2)
;; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
;; replace with V+N.
%C1 = xor i399 274877906943, -1 ;; C2 = 274877906943
%N = and i399 %M, 18446742974197923840
%A = add i399 %V, %N
%B = and i399 %A, %C1
%D = and i399 %V, 274877906943
%R = or i399 %B, %D
ret i399 %R
; CHECK-LABEL @test2
; CHECK-NEXT: and {{.*}}, 18446742974197923840
; CHECK-NEXT: add
; CHECK-NEXT: ret
}