Register undef variables used by the size argument of malloc
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -1758,7 +1758,7 @@ void Malloc::print(std::ostream &os) const {
}
StateValue Malloc::toSMT(State &s) const {
- auto &[sz, np] = s[*size];
+ auto &[sz, np] = s.getAndAddUndefs(*size);
// TODO: malloc's alignment is implementation defined.
expr nonnull = expr::mkBoolVar("malloc_never_fails");
auto [p, allocated] = s.getMemory().alloc(sz, 8, Memory::HEAP, true, nonnull);
@@ -1797,8 +1797,8 @@ void Calloc::print(std::ostream &os) const {
}
StateValue Calloc::toSMT(State &s) const {
- auto &[nm, np_num] = s[*num];
- auto &[sz, np_sz] = s[*size];
+ auto &[nm, np_num] = s.getAndAddUndefs(*num);
+ auto &[sz, np_sz] = s.getAndAddUndefs(*size);
// TODO: check calloc align.
expr size = nm * sz;

MODIFY
ir/state.cpp
ir/state.cpp
@@ -69,6 +69,13 @@ const StateValue& State::operator[](const Value &val) {
return tmp_values[i_tmp_values++] = move(sval_new);
}
+const StateValue& State::getAndAddUndefs(const Value &val) {
+ auto &v = (*this)[val];
+ for (auto uvar: at(val).second)
+ addQuantVar(move(uvar));
+ return v;
+}
+
const State::ValTy& State::at(const Value &val) const {
return get<1>(values[values_map.at(&val)]);
}

MODIFY
ir/state.h
ir/state.h
@@ -86,6 +86,7 @@ public:
const StateValue& exec(const Value &v);
const StateValue& operator[](const Value &val);
+ const StateValue& getAndAddUndefs(const Value &val);
const ValTy& at(const Value &val) const;
const smt::expr* jumpCondFrom(const BasicBlock &bb) const;

MODIFY
tests/alive-tv/memory/alloca-removal.src.ll
tests/alive-tv/memory/alloca-removal.src.ll
-; TEST-ARGS: -disable-undef-input
+; TEST-ARGS: -smt-to=5000
+
define i8* @f(i64 %size) {
entry:
%items.addr = alloca i32, align 4
@@ -14,4 +15,22 @@ entry:
ret i8* %call
}
-declare dso_local noalias i8* @malloc(i64)
+define i8* @f_observed2(i64 %size) {
+entry:
+ %items.addr = alloca i32, align 8
+ %call = call noalias i8* @calloc(i64 4, i64 %size)
+ %unused = ptrtoint i8* %call to i64
+ ret i8* %call
+}
+
+define i8* @f_observed3(i64 %size) {
+entry:
+ %unused0 = bitcast i64 %size to i64
+ %items.addr = alloca i32, align 8
+ %call = call noalias i8* @calloc(i64 4, i64 %size)
+ %unused = ptrtoint i8* %call to i64
+ ret i8* %call
+}
+
+declare noalias i8* @malloc(i64)
+declare noalias i8* @calloc(i64, i64)

MODIFY
tests/alive-tv/memory/alloca-removal.tgt.ll
tests/alive-tv/memory/alloca-removal.tgt.ll
-; TEST-ARGS: -disable-undef-input
define i8* @f(i64 %size) {
entry:
%call = call noalias i8* @malloc(i64 %size)
@@ -12,4 +11,20 @@ entry:
ret i8* %call
}
-declare dso_local noalias i8* @malloc(i64)
+define i8* @f_observed2(i64 %size) {
+entry:
+ %call = call noalias i8* @calloc(i64 4, i64 %size)
+ %unused = ptrtoint i8* %call to i64
+ ret i8* %call
+}
+
+define i8* @f_observed3(i64 %size) {
+entry:
+ %unused0 = bitcast i64 %size to i64
+ %call = call noalias i8* @calloc(i64 4, i64 %size)
+ %unused = ptrtoint i8* %call to i64
+ ret i8* %call
+}
+
+declare noalias i8* @malloc(i64)
+declare noalias i8* @calloc(i64, i64)

Register undef variables used by the size argument of malloc (#262)