From f8b08f7179bca3cac6ccb32c5f2c05a07ffabd9e Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 24 Jun 2016 18:26:02 +0000 Subject: [InstCombine] consolidate commutation variants of matchSelectFromAndOr() in one place; NFCI By putting all the possible commutations together, we simplify the code. Note that this is NFCI, but I'm adding tests that actually exercise each commutation pattern because we don't have this anywhere else. llvm-svn: 273702 --- .../Transforms/InstCombine/InstCombineAndOrXor.cpp | 45 +++++++++------------- 1 file changed, 18 insertions(+), 27 deletions(-) (limited to 'llvm/lib/Transforms') diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index e518db13a7f..c76cfba4f14 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1628,26 +1628,18 @@ Instruction *InstCombiner::MatchBSwap(BinaryOperator &I) { return LastInst; } -/// We have an expression of the form (A&C)|(B&D). Check if A is (cond?-1:0) -/// and either B or D is ~(cond?-1,0) or (cond?0,-1), then we can simplify this -/// expression to "cond ? C : D or B". -static Instruction *matchSelectFromAndOr(Value *A, Value *B, Value *C, Value *D, +/// 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, 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) | (B & (cond ? 0:-1)) -> cond ? C : B. - if (match(D, m_Not(m_SExt(m_Specific(Cond))))) - return SelectInst::Create(Cond, C, B); - if (match(D, m_SExt(m_Not(m_Specific(Cond))))) - return SelectInst::Create(Cond, C, B); - // ((cond ? -1:0) & C) | ((cond ? 0:-1) & D) -> cond ? C : D. - if (match(B, m_Not(m_SExt(m_Specific(Cond))))) - return SelectInst::Create(Cond, C, D); - if (match(B, m_SExt(m_Not(m_Specific(Cond))))) + 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); } @@ -1662,15 +1654,6 @@ static Instruction *matchSelectFromAndOr(Value *A, Value *B, Value *C, Value *D, Type *SrcType = cast(A)->getSrcTy(); - // ((bc Cond) & C) | (B & (bc ~Cond)) --> bc (select Cond, (bc C), (bc B)) - if (match(D, 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 *BitcastB = Builder.CreateBitCast(B, SrcType); - Value *Select = Builder.CreateSelect(Cond, BitcastC, BitcastB); - return CastInst::Create(Instruction::BitCast, Select, A->getType()); - } - // ((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))))))) { @@ -2276,14 +2259,22 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { } } - // (A & (C0?-1:0)) | (B & ~(C0?-1:0)) -> C0 ? A : B, and commuted variants. - if (Instruction *Match = matchSelectFromAndOr(A, B, C, D, *Builder)) + // (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, A, D, C, *Builder)) + if (Instruction *Match = matchSelectFromAndOr(B, D, C, A, *Builder)) return Match; - if (Instruction *Match = matchSelectFromAndOr(C, B, A, D, *Builder)) + if (Instruction *Match = matchSelectFromAndOr(D, B, A, C, *Builder)) return Match; - if (Instruction *Match = matchSelectFromAndOr(D, A, B, C, *Builder)) + if (Instruction *Match = matchSelectFromAndOr(D, B, C, A, *Builder)) return Match; // ((A&~B)|(~A&B)) -> A^B -- cgit v1.2.3