[PATCH] D142234: [ConstantRange] Handle Intrinsic::ctlz

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 1 02:50:27 PST 2023


nikic requested changes to this revision.
nikic added a comment.
This revision now requires changes to proceed.

This looks on the right track now.



================
Comment at: llvm/lib/IR/ConstantRange.cpp:1737
+  }
+}
+
----------------
This looks basically fine, but a bit overly complicated. This should be sufficient:
```
ConstantRange ConstantRange::ctlz(bool ZeroIsPoison) const {
  if (isEmptySet())
    return getEmpty();

  APInt Zero = APInt::getZero(getBitWidth());
  if (ZeroIsPoison && contains(Zero)) {
    // ZeroIsPoison is set, and zero is contained. We discern three cases, in
    // which a zero can appear:
    // 1) Lower is zero, handling cases of kind [0, 1), [0, 2), etc.
    // 2) Upper is zero, wrapped set, handling cases of kind [3, 0], etc.
    // 3) Zero contained in a wrapped set, e.g., [3, 2), [3, 1), etc.
    
    if (getLower().isZero()) {
      if ((getUpper() - 1).isZero()) {
        // We have in input interval of kind [0, 1). In this case we cannot
        // really help but return empty-set.
        return getEmpty();
      }

      // Compute the resulting range by excluding zero from Lower.
      return ConstantRange(
          APInt(getBitWidth(), (getUpper() - 1).countLeadingZeros()), 
          APInt(getBitWidth(), (getLower() + 1).countLeadingZeros() + 1));
    } else if ((getUpper() - 1).isZero()) {
      // Compute the resulting range by excluding zero from Upper.
      return ConstantRange(
          Zero, APInt(getBitWidth(), getLower().countLeadingZeros() + 1));
    } else { 
      return ConstantRange(Zero, APInt(getBitWidth(), getBitWidth()));
    }   
  } 
  
  // Zero is either safe or not in the range. The output range is composed by
  // the result of countLeadingZero of the two extremes.
  return getNonEmpty(
      APInt(getBitWidth(), getUnsignedMax().countLeadingZeros()), 
      APInt(getBitWidth(), getUnsignedMin().countLeadingZeros() + 1));
}     
```


================
Comment at: llvm/test/Analysis/LazyValueAnalysis/lvi-for-ctlz.ll:1
+; RUN: opt < %s -passes=jump-threading -print-lvi-after-jump-threading -disable-output 2>&1 | FileCheck %s
+
----------------
nikic wrote:
> Having an IR test is fine, but please do not test LVI debug output. Just check the resulting IR change using update_test_checks.py.
I don't think that as written, these tests really test anything. There needs to be a comparison involving the ctlz that can be folded away, or similar.


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

https://reviews.llvm.org/D142234



More information about the llvm-commits mailing list