mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
Implement or.ll:test21. This teaches instcombine to be able to turn this:
struct { unsigned int bit0:1; unsigned int ubyte:31; } sdata; void foo() { sdata.ubyte++; } into this: foo: add DWORD PTR [sdata], 2 ret instead of this: foo: mov %EAX, DWORD PTR [sdata] mov %ECX, %EAX add %ECX, 2 and %ECX, -2 and %EAX, 1 or %EAX, %ECX mov DWORD PTR [sdata], %EAX ret llvm-svn: 23376
This commit is contained in:
parent
c6c62e7864
commit
1466ade38b
@ -1921,10 +1921,31 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
|
||||
}
|
||||
|
||||
// (A & C1)|(A & C2) == A & (C1|C2)
|
||||
// (A & C1)|(B & C2)
|
||||
if (match(Op0, m_And(m_Value(A), m_ConstantInt(C1))) &&
|
||||
match(Op1, m_And(m_Value(B), m_ConstantInt(C2))) && A == B)
|
||||
return BinaryOperator::createAnd(A, ConstantExpr::getOr(C1, C2));
|
||||
match(Op1, m_And(m_Value(B), m_ConstantInt(C2)))) {
|
||||
|
||||
if (A == B) // (A & C1)|(A & C2) == A & (C1|C2)
|
||||
return BinaryOperator::createAnd(A, ConstantExpr::getOr(C1, C2));
|
||||
|
||||
|
||||
// if A == (add B, C3) or B == (add A, C4)
|
||||
ConstantInt *C3 = 0;
|
||||
Value *V = 0;
|
||||
if ((match(A, m_Add(m_Value(V), m_ConstantInt(C3))) && V == B ||
|
||||
match(B, m_Add(m_Value(V), m_ConstantInt(C3))) && V == A)) {
|
||||
if (V == A) std::swap(C1, C2);
|
||||
// We have: ((V + C3) & C1) | (V & C2)
|
||||
// if C2 = ~C1 and (C3 & C2) == 0 and C2 is 0+1+
|
||||
if (C1 == ConstantExpr::getNot(C2) &&
|
||||
ConstantExpr::getAnd(C3, C2)->isNullValue() &&
|
||||
(C2->getRawValue() & (C2->getRawValue()+1)) == 0) {
|
||||
// Return V+C3.
|
||||
std::cerr << "Simpl: " << *A << "Simpl2: " << *B << "Simpl3: " << I;
|
||||
return ReplaceInstUsesWith(I, V == A ? B : A);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1
|
||||
if (A == Op1) // ~A | A == -1
|
||||
@ -2040,6 +2061,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user