[PATCH] D122152: [InstCombine] Fold two select patterns into and-or

chenglin.bi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 21 09:42:22 PDT 2022


bcl5980 added a comment.

In D122152#3396735 <https://reviews.llvm.org/D122152#3396735>, @RKSimon wrote:

> I'm almost afraid to ask - but should we consider supporting this with freeze?
>
>   ----------------------------------------
>   define i1 @src(i1 %a, i1 %b, i1 %c) {
>     %nota = xor i1 %a, 1
>     %cond = or i1 %nota, %c
>     %r = select i1 %cond, i1 %a, i1 %b
>     ret i1 %r
>   }
>   =>
>   define i1 @tgt(i1 %a, i1 %b, i1 %c) {
>     %bf = freeze i1 %b
>     %tmp = or i1 %bf, %c
>     %r = and i1 %tmp, %a
>     ret i1 %r
>   }
>   Transformation seems to be correct!
>   
>   
>   ----------------------------------------
>   define i1 @src(i1 %a, i1 %b, i1 %c) {
>     %notc = xor i1 %c, 1
>     %cond = and i1 %notc, %b
>     %r = select i1 %cond, i1 %a, i1 %b
>     ret i1 %r
>   }
>   =>
>   define i1 @tgt(i1 %a, i1 %b, i1 %c) {
>     %fa = freeze i1 %a
>     %tmp = or i1 %c, %fa
>     %r = and i1 %tmp, %b
>     ret i1 %r
>   }
>   Transformation seems to be correct!

Which way is better do you think?

  Value *C;
  // select (~a | c), a, b -> and a, (or c, b)
  if (match(CondVal, m_Or(m_Not(m_Value(TrueVal)), m_Value(C))))
    return BinaryOperator::CreateAnd(
        TrueVal, Builder.CreateOr(C, Builder.CreateFreeze(FalseVal)));
  // select (~c & b), a, b -> and b, (or a, c)
  if (match(CondVal, m_And(m_Not(m_Value(C)), m_Value(FalseVal))))
    return BinaryOperator::CreateAnd(
        FalseVal, Builder.CreateOr(C, Builder.CreateFreeze(TrueVal)));

Or

  // select (~a | c), a, b -> and a, (or c, b)
  if (match(CondVal, m_Or(m_Not(m_Value(TrueVal)), m_Value(C)))) {
    if (!llvm::isGuaranteedNotToBePoison(FalseVal))
      FalseVal = Builder.CreateFreeze(FalseVal);
    return BinaryOperator::CreateAnd(TrueVal, Builder.CreateOr(C, FalseVal));
  }
  // select (~c & b), a, b -> and b, (or a, c)
  if (match(CondVal, m_And(m_Not(m_Value(C)), m_Value(FalseVal)))) {
    if (!llvm::isGuaranteedNotToBePoison(TrueVal))
      TrueVal = Builder.CreateFreeze(TrueVal);
    return BinaryOperator::CreateAnd(FalseVal, Builder.CreateOr(C, TrueVal));
  }


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122152/new/

https://reviews.llvm.org/D122152



More information about the llvm-commits mailing list