mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +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);
|
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))) &&
|
if (match(Op0, m_And(m_Value(A), m_ConstantInt(C1))) &&
|
||||||
match(Op1, m_And(m_Value(B), m_ConstantInt(C2))) && A == B)
|
match(Op1, m_And(m_Value(B), m_ConstantInt(C2)))) {
|
||||||
return BinaryOperator::createAnd(A, ConstantExpr::getOr(C1, 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 (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1
|
||||||
if (A == Op1) // ~A | A == -1
|
if (A == Op1) // ~A | A == -1
|
||||||
@ -2040,6 +2061,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Changed ? &I : 0;
|
return Changed ? &I : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user