TV: wire up load/store instructions
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -915,7 +915,7 @@ unique_ptr<Instr> Load::dup(const string &suffix) const {
void Store::print(std::ostream &os) const {
- os << "store " << getType() << ", " << ptr << ", " << val;
+ os << "store " << val << ", " << ptr;
}
StateValue Store::toSMT(State &s) const {
@@ -930,7 +930,7 @@ expr Store::getTypeConstraints(const Function &f) const {
}
unique_ptr<Instr> Store::dup(const string &suffix) const {
- return make_unique<Store>(getType(), getName() + suffix, ptr, val);
+ return make_unique<Store>(getName() + suffix, ptr, val);
}
}

MODIFY
ir/instr.h
ir/instr.h
@@ -290,8 +290,8 @@ public:
class Store final : public Instr {
Value &ptr, &val;
public:
- Store(Type &type, std::string &&name, Value &ptr, Value &val)
- : Instr(type, std::move(name)), ptr(ptr), val(val) {}
+ Store(std::string &&name, Value &ptr, Value &val)
+ : Instr(Type::voidTy, std::move(name)), ptr(ptr), val(val) {}
void print(std::ostream &os) const override;
StateValue toSMT(State &s) const override;

MODIFY
llvm_util/utils.cpp
llvm_util/utils.cpp
@@ -21,6 +21,7 @@ unordered_map<const llvm::Value*, string> value_names;
unsigned value_id_counter; // for %0, %1, etc..
vector<unique_ptr<IntType>> int_types;
+vector<unique_ptr<PtrType>> ptr_types;
// cache complex types
unordered_map<const llvm::Type*, unique_ptr<Type>> type_cache;
@@ -78,6 +79,15 @@ Type* llvm_type2alive(const llvm::Type *ty) {
int_types[bits] = make_unique<IntType>("i" + to_string(bits), bits);
return int_types[bits].get();
}
+ case llvm::Type::PointerTyID: {
+ // TODO: support for non-64 bits pointers
+ unsigned as = cast<llvm::PointerType>(ty)->getAddressSpace();
+ if (as < ptr_types.size())
+ ptr_types.resize(as + 1);
+ if (!ptr_types[as])
+ ptr_types[as] = make_unique<PtrType>(as);
+ return ptr_types[as].get();
+ }
case llvm::Type::StructTyID: {
auto &cache = type_cache[ty];
if (!cache) {
@@ -272,6 +282,21 @@ public:
BinOp::ExtractValue));
}
+ RetTy visitLoadInst(llvm::LoadInst &i) {
+ // TODO: Add support for isVolatile(), getAlignment(), getOrdering()
+ PARSE_UNOP();
+ RETURN_IDENTIFIER(make_unique<Load>(*ty, value_name(i), *val));
+ }
+
+ RetTy visitStoreInst(llvm::StoreInst &i) {
+ // TODO: Add support for isVolatile(), getAlignment(), getOrdering()
+ auto val = get_operand(i.getValueOperand());
+ auto ptr = get_operand(i.getPointerOperand());
+ if (!val || !ptr)
+ return error(i);
+ RETURN_IDENTIFIER(make_unique<Store>(value_name(i), *ptr, *val));
+ }
+
RetTy visitPHINode(llvm::PHINode &i) {
auto ty = llvm_type2alive(i.getType());
if (!ty)
@@ -524,10 +549,12 @@ initializer::initializer(ostream &os) {
type_id_counter = 0;
int_types.resize(65);
int_types[1] = make_unique<IntType>("i1", 1);
+ ptr_types.emplace_back(make_unique<PtrType>(0));
}
initializer::~initializer() {
int_types.clear();
+ ptr_types.clear();
type_cache.clear();
}

TV: wire up load/store instructions