summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-06-24 18:55:27 +0000
committerSanjay Patel <spatel@rotateright.com>2016-06-24 18:55:27 +0000
commit4e8ebce19632c135ec39ff7698079edeea6794af (patch)
treef9280c0514480f8755b064ab7d8bc74cf3e13a27
parente77d6e0e4d3989b8cfe6d4be69df4a5c26edde5f (diff)
downloadbcm5719-llvm-4e8ebce19632c135ec39ff7698079edeea6794af.tar.gz
bcm5719-llvm-4e8ebce19632c135ec39ff7698079edeea6794af.zip
[InstCombine] refactor optional bitcasting in matchSelectFromAndOr() into one code path (NFCI)
Tests to verify that the commuted variants are all exercised were added with: http://reviews.llvm.org/rL273702 llvm-svn: 273706
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp84
1 files changed, 39 insertions, 45 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index c76cfba4f14..d25eec1a947 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1630,38 +1630,32 @@ Instruction *InstCombiner::MatchBSwap(BinaryOperator &I) {
/// We have an expression of the form (A & C) | (B & D). If A is (Cond?-1:0)
/// and B is ~(Cond?-1,0), then simplify this expression to "Cond ? C : D".
-static Instruction *matchSelectFromAndOr(Value *A, Value *C, Value *B, Value *D,
+static Value *matchSelectFromAndOr(Value *A, Value *C, Value *B, Value *D,
InstCombiner::BuilderTy &Builder) {
- // If A is not a select of -1/0, this cannot match.
- Value *Cond = nullptr;
+ // The potential condition of the select may be bitcasted. In that case, look
+ // through its bitcast and the corresponding bitcast of the 'not' condition.
+ Type *OrigType = A->getType();
+ Value *SrcA, *SrcB;
+ if (match(A, m_BitCast(m_Value(SrcA))) &&
+ match(B, m_BitCast(m_Value(SrcB)))) {
+ A = SrcA;
+ B = SrcB;
+ }
+
+ // The condition must be a value of -1/0, and B must be the 'not' of that
+ // condition.
+ Value *Cond;
if (match(A, m_SExt(m_Value(Cond))) &&
- Cond->getType()->getScalarType()->isIntegerTy(1)) {
-
- // ((cond ? -1:0) & C) | ((cond ? 0:-1) & D) -> cond ? C : D.
- if (match(B, m_CombineOr(m_Not(m_SExt(m_Specific(Cond))),
- m_SExt(m_Not(m_Specific(Cond))))))
- return SelectInst::Create(Cond, C, D);
- }
-
- // TODO: Refactor the pattern matching above and below so there's less code.
-
- // The sign-extended boolean condition may be hiding behind a bitcast. In that
- // case, look for the same patterns as above. However, we need to bitcast the
- // input operands to the select and bitcast the output of the select to match
- // the expected types.
- if (match(A, m_BitCast(m_SExt(m_Value(Cond)))) &&
- Cond->getType()->getScalarType()->isIntegerTy(1)) {
-
- Type *SrcType = cast<BitCastInst>(A)->getSrcTy();
-
+ Cond->getType()->getScalarType()->isIntegerTy(1) &&
+ match(B, m_CombineOr(m_Not(m_SExt(m_Specific(Cond))),
+ m_SExt(m_Not(m_Specific(Cond)))))) {
// ((bc Cond) & C) | ((bc ~Cond) & D) --> bc (select Cond, (bc C), (bc D))
- if (match(B, m_CombineOr(m_BitCast(m_Not(m_SExt(m_Specific(Cond)))),
- m_BitCast(m_SExt(m_Not(m_Specific(Cond))))))) {
- Value *BitcastC = Builder.CreateBitCast(C, SrcType);
- Value *BitcastD = Builder.CreateBitCast(D, SrcType);
- Value *Select = Builder.CreateSelect(Cond, BitcastC, BitcastD);
- return CastInst::Create(Instruction::BitCast, Select, A->getType());
- }
+ // The bitcasts will either all exist or all not exist. The builder will
+ // not create unnecessary casts if the types already match.
+ Value *BitcastC = Builder.CreateBitCast(C, A->getType());
+ Value *BitcastD = Builder.CreateBitCast(D, A->getType());
+ Value *Select = Builder.CreateSelect(Cond, BitcastC, BitcastD);
+ return Builder.CreateBitCast(Select, OrigType);
}
return nullptr;
@@ -2260,22 +2254,22 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
}
// (Cond & C) | (~Cond & D) -> Cond ? C : D, and commuted variants.
- if (Instruction *Match = matchSelectFromAndOr(A, C, B, D, *Builder))
- return Match;
- if (Instruction *Match = matchSelectFromAndOr(A, C, D, B, *Builder))
- return Match;
- if (Instruction *Match = matchSelectFromAndOr(C, A, B, D, *Builder))
- return Match;
- if (Instruction *Match = matchSelectFromAndOr(C, A, D, B, *Builder))
- return Match;
- if (Instruction *Match = matchSelectFromAndOr(B, D, A, C, *Builder))
- return Match;
- if (Instruction *Match = matchSelectFromAndOr(B, D, C, A, *Builder))
- return Match;
- if (Instruction *Match = matchSelectFromAndOr(D, B, A, C, *Builder))
- return Match;
- if (Instruction *Match = matchSelectFromAndOr(D, B, C, A, *Builder))
- return Match;
+ if (Value *V = matchSelectFromAndOr(A, C, B, D, *Builder))
+ return replaceInstUsesWith(I, V);
+ if (Value *V = matchSelectFromAndOr(A, C, D, B, *Builder))
+ return replaceInstUsesWith(I, V);
+ if (Value *V = matchSelectFromAndOr(C, A, B, D, *Builder))
+ return replaceInstUsesWith(I, V);
+ if (Value *V = matchSelectFromAndOr(C, A, D, B, *Builder))
+ return replaceInstUsesWith(I, V);
+ if (Value *V = matchSelectFromAndOr(B, D, A, C, *Builder))
+ return replaceInstUsesWith(I, V);
+ if (Value *V = matchSelectFromAndOr(B, D, C, A, *Builder))
+ return replaceInstUsesWith(I, V);
+ if (Value *V = matchSelectFromAndOr(D, B, A, C, *Builder))
+ return replaceInstUsesWith(I, V);
+ if (Value *V = matchSelectFromAndOr(D, B, C, A, *Builder))
+ return replaceInstUsesWith(I, V);
// ((A&~B)|(~A&B)) -> A^B
if ((match(C, m_Not(m_Specific(D))) &&
OpenPOWER on IntegriCloud