[PATCH] D45539: [InstCombine][NFC]: foldSelectICmpAndAnd(): and is commutative

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 12 11:47:26 PDT 2018


spatel added a comment.

I think the patch is correct, but it's hard to keep all of the values straight (because there are a lot!). What do you think about rearranging it a bit like this and using m_c_And():

  /// We want to turn:
  ///   (select (icmp eq (and X, Y), 0), (and (lshr X, Z), 1), 1)
  /// into:
  ///   zext (icmp ne i32 (and X, (or Y, (shl 1, Z))), 0)
  /// Note:
  ///   Z may be 0 if lshr is missing.
  /// Worst-case scenario is that we will replace 5 instructions with 5 different
  /// instructions, but we got rid of select.
  static Instruction *foldSelectICmpAndAnd(Type *SelType, const ICmpInst *Cmp,
                                           Value *TVal, Value *FVal,
                                           InstCombiner::BuilderTy &Builder) {
    if (!Cmp->hasOneUse() || !Cmp->getOperand(0)->hasOneUse() ||
        Cmp->getPredicate() != ICmpInst::ICMP_EQ ||
        !match(Cmp->getOperand(1), m_Zero()) || !match(FVal, m_One()))
      return nullptr;
  
    // The TrueVal has general form of:
    //   and %B, 1
    // where %B may be optionally shifted: lshr %X, %Z.
    Value *B;
    if (!match(TVal, m_OneUse(m_And(m_Value(B), m_One()))))
      return nullptr;
  
    Value *X, *Y, *Z;
    bool HasShift = match(B, m_OneUse(m_LShr(m_Value(X), m_Value(Z))));
    if (!HasShift)
      X = B;
  
    if (!match(Cmp->getOperand(0), m_c_And(m_Specific(X), m_Value(Y))))
      return nullptr;
  
    // ((X & Y) == 0) ? ((X >> Z) & 1) : 1 --> (X & (Y | (1 << Z))) != 0
    // ((X & Y) == 0) ? (X & 1) : 1 --> (X & (Y | 1)) != 0
    Constant *One = ConstantInt::get(SelType, 1);
    Value *MaskB = HasShift ? Builder.CreateShl(One, Z) : One;
    Value *FullMask = Builder.CreateOr(Y, MaskB);
    Value *MaskedX = Builder.CreateAnd(X, FullMask);
    Value *ICmpNeZero = Builder.CreateIsNotNull(MaskedX);
    return new ZExtInst(ICmpNeZero, SelType);
  }


Repository:
  rL LLVM

https://reviews.llvm.org/D45539





More information about the llvm-commits mailing list