IR: add bitcast/int2ptr/ptr2int
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -468,6 +468,9 @@ void ConversionOp::print(ostream &os) const {
case SExt: str = "sext "; break;
case ZExt: str = "zext "; break;
case Trunc: str = "trunc "; break;
+ case BitCast: str = "bitcast "; break;
+ case Ptr2Int: str = "ptrtoint "; break;
+ case Int2Ptr: str = "int2ptr "; break;
}
os << getName() << " = " << str << val;
@@ -492,25 +495,48 @@ StateValue ConversionOp::toSMT(State &s) const {
case Trunc:
newval = v.trunc(to_bw);
break;
+ case BitCast:
+ newval = v;
+ break;
+ case Ptr2Int:
+ newval = s.getMemory().ptr2int(v);
+ break;
+ case Int2Ptr:
+ newval = s.getMemory().int2ptr(v);
+ break;
}
return { move(newval), expr(vp) };
}
expr ConversionOp::getTypeConstraints(const Function &f) const {
- expr sizeconstr;
+ expr c;
switch (op) {
case SExt:
case ZExt:
- sizeconstr = val.getType().sizeVar().ult(getType().sizeVar());
+ c = getType().enforceIntOrVectorType() &&
+ getType().sameType(val.getType()) &&
+ val.getType().sizeVar().ult(getType().sizeVar());
break;
case Trunc:
- sizeconstr = getType().sizeVar().ult(val.getType().sizeVar());
+ c = getType().enforceIntOrVectorType() &&
+ getType().sameType(val.getType()) &&
+ getType().sizeVar().ult(val.getType().sizeVar());
+ break;
+ case BitCast:
+ // FIXME: input can only be ptr if result is a ptr as well
+ c = getType().enforceIntOrPtrOrVectorType() &&
+ getType().sizeVar() == val.getType().sizeVar();
+ break;
+ case Ptr2Int:
+ c = getType().enforceIntType() &&
+ val.getType().enforcePtrType();
+ break;
+ case Int2Ptr:
+ c = getType().enforcePtrType() &&
+ val.getType().enforceIntType();
break;
}
- return Value::getTypeConstraints() &&
- getType().enforceIntOrVectorType() &&
- getType().sameType(val.getType()) &&
- move(sizeconstr);
+ return Value::getTypeConstraints() && move(c);
}
unique_ptr<Instr> ConversionOp::dup(const string &suffix) const {

MODIFY
ir/instr.h
ir/instr.h
@@ -68,6 +68,7 @@ public:
std::unique_ptr<Instr> dup(const std::string &suffix) const override;
};
+
class TernaryOp final : public Instr {
public:
enum Op { FShl, FShr };
@@ -87,9 +88,10 @@ public:
std::unique_ptr<Instr> dup(const std::string &suffix) const override;
};
+
class ConversionOp final : public Instr {
public:
- enum Op { SExt, ZExt, Trunc };
+ enum Op { SExt, ZExt, Trunc, BitCast, Ptr2Int, Int2Ptr };
private:
Value &val;

MODIFY
ir/memory.cpp
ir/memory.cpp
@@ -215,6 +215,15 @@ void Memory::memcpy(const expr &d, const expr &s, const expr &bytes,
// TODO
}
+expr Memory::ptr2int(const expr &ptr) {
+ return Pointer(*this, ptr).get_address();
+}
+
+expr Memory::int2ptr(const expr &val) {
+ // TODO
+ return {};
+}
+
Memory Memory::mkIf(const expr &cond, const Memory &then, const Memory &els) {
assert(then.state == els.state);
Memory ret(then);

MODIFY
ir/memory.h
ir/memory.h
@@ -81,6 +81,9 @@ public:
void memcpy(const smt::expr &dst, const smt::expr &src,
const smt::expr &bytes, unsigned align_dst, unsigned align_src);
+ smt::expr ptr2int(const smt::expr &ptr);
+ smt::expr int2ptr(const smt::expr &val);
+
static Memory mkIf(const smt::expr &cond, const Memory &then,
const Memory &els);

IR: add bitcast/int2ptr/ptr2int