allow loopy libcalls to iterate until the end with constants ops
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -64,11 +64,14 @@ struct LoopLikeFunctionApproximator {
// (value, nonpoison, UB)
tuple<expr, expr, expr> _loop(IR::State &s, AndExpr &prefix, unsigned i,
unsigned unroll_cnt) {
- bool is_last = i == unroll_cnt - 1;
+ bool is_last = i >= unroll_cnt - 1;
auto [res_i, np_i, ub_i, continue_i] = ith_exec(i, is_last);
auto ub = ub_i();
prefix.add(ub_i);
+ // Keep going if the function is being applied to a constant input
+ is_last &= !continue_i.isConst();
+
if (is_last)
s.addPre(prefix().implies(!continue_i));

MODIFY
llvm_util/known_fns.cpp
llvm_util/known_fns.cpp
@@ -114,17 +114,6 @@ known_call(llvm::CallInst &i, const llvm::TargetLibraryInfo &TLI,
RETURN_VAL(make_unique<UnaryOp>(*ty, value_name(i), *args[0],
UnaryOp::Copy));
case llvm::LibFunc_strlen:
- if (auto BI = llvm::dyn_cast<llvm::BitCastInst>(i.getArgOperand(0))) {
- auto G = llvm::dyn_cast<llvm::GlobalVariable>(BI->getOperand(0));
- if (G && G->isConstant() && G->hasDefinitiveInitializer()) {
- auto C = llvm::dyn_cast<llvm::ConstantDataArray>(G->getInitializer());
- if (C && C->isCString()) {
- RETURN_VAL(make_unique<UnaryOp>(*ty, value_name(i),
- *make_intconst(C->getAsCString().size(), ty->bits()),
- UnaryOp::Copy));
- }
- }
- }
RETURN_VAL(make_unique<Strlen>(*ty, value_name(i), *args[0]));
case llvm::LibFunc_memcmp:
case llvm::LibFunc_bcmp: {

allow loopy libcalls to iterate until the end with constants ops