[llvm] [LVI] Thread binop over select with constant arms (PR #110212)

Andreas Jonson via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 5 10:03:12 PST 2024


================
@@ -924,18 +924,74 @@ LazyValueInfoImpl::solveBlockValueBinaryOpImpl(
     Instruction *I, BasicBlock *BB,
     std::function<ConstantRange(const ConstantRange &, const ConstantRange &)>
         OpFn) {
+  Value *LHS = I->getOperand(0);
+  Value *RHS = I->getOperand(1);
+
+  auto GetValueFromCondition =
+      [&](Value *V, Value *Cond,
+          bool CondIsTrue) -> std::optional<ConstantRange> {
+    std::optional<ValueLatticeElement> OptVal = getBlockValue(V, BB, I);
+    if (!OptVal)
+      return std::nullopt;
+    return OptVal->asConstantRange(V->getType());
+  };
+
+  auto ThreadBinOpOverSelect =
+      [&](Value *X, const ConstantRange &CRX, SelectInst *Y,
+          bool XIsLHS) -> std::optional<ValueLatticeElement> {
+    Value *Cond = Y->getCondition();
+    // Only handle selects with constant values.
+    Constant *TrueC = dyn_cast<Constant>(Y->getTrueValue());
+    if (!TrueC)
+      return std::nullopt;
+    Constant *FalseC = dyn_cast<Constant>(Y->getFalseValue());
+    if (!FalseC)
+      return std::nullopt;
+    if (!isGuaranteedNotToBeUndef(Cond, AC))
+      return std::nullopt;
+
+    ConstantRange TrueX =
+        CRX.intersectWith(getValueFromCondition(X, Cond, /*CondIsTrue=*/true,
+                                                /*UseBlockValue=*/false)
+                              ->asConstantRange(X->getType()));
----------------
andjo403 wrote:

can the getValueFromCondition not return nullopt?  and then using operator-> will result in UB

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


More information about the llvm-commits mailing list