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:
parent
650b6ea893
commit
fe3a219355
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
|
||||
|
37
test/Transforms/InstSimplify/apint-or.ll
Normal file
37
test/Transforms/InstSimplify/apint-or.ll
Normal file
@ -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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user