[PATCH] D102698: [InstCombine] Relaxed constraints of uses for exp(X) * exp(Y) -> exp(X + Y) and exp2(X) * exp2(Y) -> exp2(X + Y)

Daniil Seredkin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 24 06:51:56 PDT 2021


vdsered added a comment.

As I understand it

  if (match(Op0, m_Intrinsic<Intrinsic::exp2>(m_Value(X))) &&
          match(Op1, m_Intrinsic<Intrinsic::exp2>(m_Value(Y))) &&
          isOnlyUserOfAnyOperand(&I))

will be

  if (match(Op0, m_Intrinsic<Intrinsic::exp2>(m_Value(X))) &&
          match(Op1, m_Intrinsic<Intrinsic::exp2>(m_Value(Y))) &&
          (X->hasOneUser() || Y -> hasOneUser()))

The difference between them is that isOnlyUserOfAnyOperand depends on how many operands an instruction has (a known count, we use it for mul now where it is 2). On the other, hasOneUser depends on the total number of uses of each operand (can be an arbitrary number). I'm not sure, but there can theoretically be situations when a number of uses is more than a number of ops, right?

@lebedev.ri, we could implement isOnlyUserOfAnyOperand like this

  bool llvm::isOnlyUserOfAnyOperand(Instruction *I) {
      return llvm::any_of(I->operands(), [](Value *V) { return V->hasOneUser(); })
  }

This solution would be good too especially because it is easier to understand, but I'd leave it as-is without hasOneUser in case there are no any performance/logical issues with it.


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

https://reviews.llvm.org/D102698



More information about the llvm-commits mailing list