summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-01-04 06:03:59 +0000
committerChris Lattner <sabre@nondot.org>2010-01-04 06:03:59 +0000
commit2d91231d82ce9651b3361b371d42b58142592694 (patch)
tree71cb4a13067178bc4182f42b64eb9913120264d9 /llvm/lib/Transforms/Scalar/InstructionCombining.cpp
parent1dae8766b18a9d5757ff76668bbd3fd05213c3d5 (diff)
downloadbcm5719-llvm-2d91231d82ce9651b3361b371d42b58142592694.tar.gz
bcm5719-llvm-2d91231d82ce9651b3361b371d42b58142592694.zip
implement an instcombine xform needed by clang's codegen
on the example in PR4216. This doesn't trigger in the testsuite, so I'd really appreciate someone scrutinizing the logic for correctness. llvm-svn: 92458
Diffstat (limited to 'llvm/lib/Transforms/Scalar/InstructionCombining.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 363d8798f31..03885a5e05a 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -5213,12 +5213,30 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
return ReplaceInstUsesWith(I, B);
}
}
- V1 = 0; V2 = 0; V3 = 0;
+
+ // ((V | N) & C1) | (V & C2) --> (V|N) & (C1|C2)
+ // iff (C1&C2) == 0 and (N&~C1) == 0
+ if ((C1->getValue() & C2->getValue()) == 0) {
+ if (match(A, m_Or(m_Value(V1), m_Value(V2))) &&
+ ((V1 == B && MaskedValueIsZero(V2, ~C1->getValue())) || // (V|N)
+ (V2 == B && MaskedValueIsZero(V1, ~C1->getValue())))) // (N|V)
+ return BinaryOperator::CreateAnd(A,
+ ConstantInt::get(A->getContext(),
+ C1->getValue()|C2->getValue()));
+ // Or commutes, try both ways.
+ if (match(B, m_Or(m_Value(V1), m_Value(V2))) &&
+ ((V1 == A && MaskedValueIsZero(V2, ~C2->getValue())) || // (V|N)
+ (V2 == A && MaskedValueIsZero(V1, ~C2->getValue())))) // (N|V)
+ return BinaryOperator::CreateAnd(B,
+ ConstantInt::get(B->getContext(),
+ C1->getValue()|C2->getValue()));
+ }
}
// Check to see if we have any common things being and'ed. If so, find the
// terms for V1 & (V2|V3).
if (isOnlyUse(Op0) || isOnlyUse(Op1)) {
+ V1 = 0;
if (A == B) // (A & C)|(A & D) == A & (C|D)
V1 = A, V2 = C, V3 = D;
else if (A == D) // (A & C)|(B & A) == A & (B|C)
OpenPOWER on IntegriCloud