[llvm] r273706 - [InstCombine] refactor optional bitcasting in matchSelectFromAndOr() into one code path (NFCI)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 24 11:55:28 PDT 2016
Author: spatel
Date: Fri Jun 24 13:55:27 2016
New Revision: 273706
URL: http://llvm.org/viewvc/llvm-project?rev=273706&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=273706&r1=273705&r2=273706&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Fri Jun 24 13:55:27 2016
@@ -1630,38 +1630,32 @@ Instruction *InstCombiner::MatchBSwap(Bi
/// 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;
- 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);
+ // 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;
}
- // 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();
-
+ // 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) &&
+ 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(Binar
}
// (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))) &&
More information about the llvm-commits
mailing list