// position where V can be constrained by a select or branch condition.
const Use *CurrU = &U;
// TODO: Increase limit?
- const unsigned MaxUsesToInspect = 2;
+ const unsigned MaxUsesToInspect = 3;
for (unsigned I = 0; I < MaxUsesToInspect; ++I) {
std::optional<ValueLatticeElement> CondVal;
auto *CurrI = cast<Instruction>(CurrU->getUser());
// TODO: Use non-local query?
CondVal =
getEdgeValueLocal(V, PHI->getIncomingBlock(*CurrU), PHI->getParent());
+ } else if (!isSafeToSpeculativelyExecute(CurrI)) {
+ // Stop walking if we hit a non-speculatable instruction. Even if the
+ // result is only used under a specific condition, executing the
+ // instruction itself may cause side effects or UB already.
+ break;
}
if (CondVal && CondVal->isConstantRange())
CR = CR.intersectWith(CondVal->getConstantRange());
ret i16 %sel
}
-; TODO: We could handle this case by raising the limit on the number of
-; instructions we look through.
define i16 @sel_true_cond_chain_speculatable(i16 %x) {
; CHECK-LABEL: @sel_true_cond_chain_speculatable(
-; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[X:%.*]], i16 1)
-; CHECK-NEXT: [[EXTRA:%.*]] = mul i16 [[SUB]], 3
+; CHECK-NEXT: [[SUB1:%.*]] = add nuw i16 [[X:%.*]], 1
+; CHECK-NEXT: [[EXTRA:%.*]] = mul i16 [[SUB1]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[X]], -1
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[EXTRA]], i16 42
; CHECK-NEXT: ret i16 [[SEL]]
ret i16 %sel
}
+; TODO: We could handle this case by raising the limit on the number of
+; instructions we look through.
define i16 @sel_true_cond_longer_chain(i16 %x) {
; CHECK-LABEL: @sel_true_cond_longer_chain(
; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[X:%.*]], i16 1)