diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2016-06-24 18:55:27 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2016-06-24 18:55:27 +0000 |
| commit | 4e8ebce19632c135ec39ff7698079edeea6794af (patch) | |
| tree | f9280c0514480f8755b064ab7d8bc74cf3e13a27 | |
| parent | e77d6e0e4d3989b8cfe6d4be69df4a5c26edde5f (diff) | |
| download | bcm5719-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.cpp | 84 |
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))) && |

