diff options
author | Chris Lattner <sabre@nondot.org> | 2010-01-04 06:03:59 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-01-04 06:03:59 +0000 |
commit | 2d91231d82ce9651b3361b371d42b58142592694 (patch) | |
tree | 71cb4a13067178bc4182f42b64eb9913120264d9 /llvm/lib/Transforms/Scalar/InstructionCombining.cpp | |
parent | 1dae8766b18a9d5757ff76668bbd3fd05213c3d5 (diff) | |
download | bcm5719-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.cpp | 20 |
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) |