mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-22 20:43:44 +02:00
[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
This commit is contained in:
parent
e90363afbd
commit
2d49fb82e9
@ -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;
|
||||
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(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))) &&
|
||||
|
Loading…
Reference in New Issue
Block a user