[llvm] [ValueTracking] Try to infer range of select from true and false values. (PR #68256)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 4 14:55:54 PDT 2023


================
@@ -8854,11 +8854,16 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
   } else if (auto *II = dyn_cast<IntrinsicInst>(V))
     CR = getRangeForIntrinsic(*II);
   else if (auto *SI = dyn_cast<SelectInst>(V)) {
+    ConstantRange CRTrue = computeConstantRange(
+        SI->getTrueValue(), ForSigned, UseInstrInfo, AC, CtxI, DT, Depth + 1);
+    ConstantRange CRFalse = computeConstantRange(
+        SI->getFalseValue(), ForSigned, UseInstrInfo, AC, CtxI, DT, Depth + 1);
+    CR = CRTrue.unionWith(CRFalse);
----------------
goldsteinn wrote:

code wise looks fine.
Maybe add a todo for (or just implement) trying to use select condition. I.e we have something like:
`select (icmp ule x, 10), x, 10`
we can bound to [0, 10].
Something like:
```
const APInt * C;
if(match(SelectCond, m_ICmp(Pred, m_Specific(SelectTrue), m_APInt(C))) {
    CRTrue = CRTrue.intersectWith(ConstantRange::makeExactICmpRegion(Pred), *C);
}
if(match(SelectCond, m_ICmp(Pred, m_Specific(SelectFalse), m_APInt(C))) {
   CRFalse = CRFalse.intersectWith(ConstantRange::makeExactICmpRegion(getInverse(Pred), *C));
}
```
You could get a bit more sophisticated and do non-constants of just `m_APInt(C)` and build a CR for the other operand.

https://github.com/llvm/llvm-project/pull/68256


More information about the llvm-commits mailing list