add support for VLAs
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -1781,14 +1781,27 @@ void Alloc::rauw(const Value &what, Value &with) {
}
void Alloc::print(std::ostream &os) const {
- os << getName() << " = alloca " << *size << ", align " << align;
+ os << getName() << " = alloca " << *size;
+ if (mul)
+ os << " x " << *mul;
+ os << ", align " << align;
if (initially_dead)
os << ", dead";
}
StateValue Alloc::toSMT(State &s) const {
- auto &[sz, np] = s[*size];
- s.addUB(np);
+ auto [sz, np] = s[*size];
+ s.addUB(move(np));
+
+ if (mul) {
+ auto &[mul_e, mul_np] = s[*mul];
+ s.addUB(mul_np);
+ sz = sz.zextOrTrunc(bits_size_t);
+ auto m = mul_e.zextOrTrunc(bits_size_t);
+ s.addUB(sz.mul_no_uoverflow(m));
+ sz = sz * m;
+ }
+
expr ptr = s.getMemory().alloc(sz, align, Memory::STACK, true, true).first;
if (initially_dead)
s.getMemory().free(ptr, true);
@@ -1802,7 +1815,7 @@ expr Alloc::getTypeConstraints(const Function &f) const {
}
unique_ptr<Instr> Alloc::dup(const string &suffix) const {
- return make_unique<Alloc>(getType(), getName() + suffix, *size, align,
+ return make_unique<Alloc>(getType(), getName() + suffix, *size, mul, align,
initially_dead);
}

MODIFY
ir/instr.h
ir/instr.h
@@ -379,13 +379,13 @@ public:
class Alloc final : public Instr {
- Value *size;
+ Value *size, *mul;
unsigned align;
bool initially_dead;
public:
- Alloc(Type &type, std::string &&name, Value &size, unsigned align,
+ Alloc(Type &type, std::string &&name, Value &size, Value *mul, unsigned align,
bool initially_dead)
- : Instr(type, std::move(name)), size(&size), align(align),
+ : Instr(type, std::move(name)), size(&size), mul(mul), align(align),
initially_dead(initially_dead) {}
Value& getSize() const { return *size; }

MODIFY
llvm_util/llvm2alive.cpp
llvm_util/llvm2alive.cpp
@@ -399,18 +399,20 @@ public:
}
RetTy visitAllocaInst(llvm::AllocaInst &i) {
- // TODO
- if (i.isArrayAllocation() || !i.isStaticAlloca())
- return error(i);
-
auto ty = llvm_type2alive(i.getType());
if (!ty)
return error(i);
+ Value *mul = nullptr;
+ if (i.isArrayAllocation()) {
+ if (!(mul = get_operand(i.getArraySize())))
+ return error(i);
+ }
+
unordered_set<llvm::Value*> visited;
// FIXME: size bits shouldn't be a constant
auto size = make_intconst(DL().getTypeAllocSize(i.getAllocatedType()), 64);
- RETURN_IDENTIFIER(make_unique<Alloc>(*ty, value_name(i), *size,
+ RETURN_IDENTIFIER(make_unique<Alloc>(*ty, value_name(i), *size, mul,
pref_alignment(i, i.getAllocatedType()),
hasLifetimeStart(i, visited)));
}

ADD
tests/alive-tv/memory/alloca-vla-fail.srctgt.ll
+define i32 @src(i32 %a, i32 %n) {
+ %vla = alloca i32, i32 %n, align 16
+ %arrayidx = getelementptr inbounds i32, i32* %vla, i64 2
+ store i32 3, i32* %arrayidx, align 8
+ %arrayidx1 = getelementptr inbounds i32, i32* %vla, i32 %a
+ %r = load i32, i32* %arrayidx1, align 4
+ ret i32 %r
+}
+
+define i32 @tgt(i32 %a, i32 %n) {
+ ret i32 4
+}
+
+; ERROR: Value mismatch

ADD
tests/alive-tv/memory/alloca-vla.srctgt.ll
+define i32 @src(i32 %a, i32 %n) {
+ %vla = alloca i32, i32 %n, align 16
+ %arrayidx = getelementptr inbounds i32, i32* %vla, i64 2
+ store i32 3, i32* %arrayidx, align 8
+ %arrayidx1 = getelementptr inbounds i32, i32* %vla, i32 %a
+ %r = load i32, i32* %arrayidx1, align 4
+ ret i32 %r
+}
+
+define i32 @tgt(i32 %a, i32 %n) {
+ ret i32 3
+}
+

add support for VLAs