Skip to content

Commit f5d77c9

Browse files
committed
Revert "add preliminary support for the 'initialized' param attr"
This reverts commit 77e9d25.
1 parent 1664188 commit f5d77c9

File tree

8 files changed

+15
-159
lines changed

8 files changed

+15
-159
lines changed

ir/attrs.cpp

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "ir/state_value.h"
1111
#include "ir/type.h"
1212
#include "util/compiler.h"
13-
#include <algorithm>
1413
#include <cassert>
1514

1615
using namespace std;
@@ -57,17 +56,6 @@ ostream& operator<<(ostream &os, const ParamAttrs &attr) {
5756
os << "dead_on_unwind ";
5857
if (attr.has(ParamAttrs::Writable))
5958
os << "writable ";
60-
if (!attr.initializes.empty()) {
61-
os << "initializes(";
62-
bool first = true;
63-
for (auto [low, high] : attr.initializes) {
64-
if (!first)
65-
os << ", ";
66-
first = false;
67-
os << '(' << low << ", " << high << ')';
68-
}
69-
os << ") ";
70-
}
7159
return os;
7260
}
7361

@@ -354,9 +342,6 @@ uint64_t ParamAttrs::maxAccessSize() const {
354342
uint64_t bytes = getDerefBytes();
355343
if (has(ParamAttrs::DereferenceableOrNull))
356344
bytes = max(bytes, derefOrNullBytes);
357-
for (auto [low, high] : initializes) {
358-
bytes = max(bytes, high);
359-
}
360345
return round_up(bytes, align);
361346
}
362347

@@ -366,10 +351,6 @@ void ParamAttrs::merge(const ParamAttrs &other) {
366351
derefOrNullBytes = max(derefOrNullBytes, other.derefOrNullBytes);
367352
blockSize = max(blockSize, other.blockSize);
368353
align = max(align, other.align);
369-
370-
decltype(initializes) tmp;
371-
ranges::set_union(initializes, other.initializes, std::back_inserter(tmp));
372-
initializes = std::move(tmp);
373354
}
374355

375356
static expr
@@ -427,19 +408,12 @@ StateValue ParamAttrs::encode(State &s, StateValue &&val, const Type &ty,
427408
val.non_poison &= !isfpclass(val.value, ty, nofpclass);
428409
}
429410

430-
if (ty.isPtrType()) {
411+
if (ty.isPtrType())
431412
val.non_poison &=
432413
encodePtrAttrs(s, val.value, getDerefBytes(), derefOrNullBytes, align,
433414
has(NonNull), has(NoCapture), has(Writable), {}, nullptr,
434415
isdecl, false);
435416

436-
if (!initializes.empty()) {
437-
Pointer p(s.getMemory(), val.value);
438-
uint64_t high = initializes.back().second;
439-
s.addUB(p.addNoUSOverflow(expr::mkUInt(high, bits_for_offset), false));
440-
}
441-
}
442-
443417
if (poisonImpliesUB()) {
444418
s.addUB(std::move(val.non_poison));
445419
val.non_poison = true;

ir/attrs.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,6 @@ class ParamAttrs final {
8282
uint64_t align = 1;
8383
uint16_t nofpclass = 0;
8484

85-
std::vector<std::pair<uint64_t, uint64_t>> initializes;
86-
8785
bool has(Attribute a) const { return (bits & a) != 0; }
8886
void set(Attribute a) { bits |= (unsigned)a; }
8987
bool refinedBy(const ParamAttrs &other) const;

ir/memory.cpp

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,64 +1321,6 @@ void Memory::storeLambda(const Pointer &ptr, const expr &offset,
13211321
access(ptr, bytes.zextOrTrunc(bits_size_t), align, true, fn);
13221322
}
13231323

1324-
1325-
expr Memory::hasStored(const Pointer &p, const expr &bytes) const {
1326-
unsigned bytes_per_byte = bits_byte / 8;
1327-
expr bid = p.getShortBid();
1328-
expr offset = p.getShortOffset();
1329-
uint64_t bytes_i;
1330-
if (bytes.isUInt(bytes_i) && (bytes_i / bytes_per_byte) <= 8) {
1331-
expr ret = true;
1332-
for (uint64_t off = 0; off < (bytes_i / bytes_per_byte); ++off) {
1333-
expr off_expr = expr::mkUInt(off, offset);
1334-
ret &= has_stored_arg.load(bid.concat(offset + off_expr));
1335-
}
1336-
return ret;
1337-
} else {
1338-
expr var = expr::mkFreshVar("#off", offset);
1339-
state->addQuantVar(var);
1340-
expr bytes_div = bytes.zextOrTrunc(offset.bits())
1341-
.udiv(expr::mkUInt(bytes_per_byte, bytes));
1342-
return (var.uge(offset) && var.ult(offset + bytes_div))
1343-
.implies(has_stored_arg.load(bid.concat(var)));
1344-
}
1345-
}
1346-
1347-
void Memory::record_store(const Pointer &p, const smt::expr &bytes) {
1348-
auto is_local = p.isLocal();
1349-
if (is_local.isTrue())
1350-
return;
1351-
1352-
unsigned bytes_per_byte = bits_byte / 8;
1353-
expr bid = p.getShortBid();
1354-
expr offset = p.getShortOffset();
1355-
uint64_t bytes_i;
1356-
if (bytes.isUInt(bytes_i) && (bytes_i / bytes_per_byte) <= 8) {
1357-
for (uint64_t off = 0; off < (bytes_i / bytes_per_byte); ++off) {
1358-
expr off_expr = expr::mkUInt(off, offset);
1359-
has_stored_arg
1360-
= expr::mkIf(is_local,
1361-
has_stored_arg,
1362-
has_stored_arg.store(bid.concat(offset + off_expr), true));
1363-
}
1364-
} else {
1365-
expr var = expr::mkQVar(0, bid.concat(offset));
1366-
expr var_bid = var.extract(var.bits()-1, offset.bits());
1367-
expr var_off = var.trunc(offset.bits());
1368-
1369-
expr bytes_div = bytes.zextOrTrunc(offset.bits())
1370-
.udiv(expr::mkUInt(bytes_per_byte, bytes));
1371-
has_stored_arg
1372-
= expr::mkIf(is_local,
1373-
has_stored_arg,
1374-
expr::mkLambda(var, "#bid_off",
1375-
(bid == var_bid &&
1376-
var_off.uge(offset) &&
1377-
var_off.ult(offset + bytes_div)) ||
1378-
has_stored_arg.load(var)));
1379-
}
1380-
}
1381-
13821324
static bool memory_unused() {
13831325
return num_locals_src == 0 && num_locals_tgt == 0 && num_nonlocals == 0;
13841326
}
@@ -1532,10 +1474,6 @@ Memory::Memory(State &state)
15321474
local_block_liveness = expr::mkUInt(0, numLocals());
15331475
}
15341476

1535-
// no argument has been written to at entry
1536-
unsigned bits = Pointer::bitsShortBid() + Pointer::bitsShortOffset();
1537-
has_stored_arg = expr::mkConstArray(expr::mkUInt(0, bits), false);
1538-
15391477
// Initialize a memory block for null pointer.
15401478
if (skip_null()) {
15411479
auto zero = expr::mkUInt(0, bits_size_t);
@@ -2806,8 +2744,6 @@ Memory Memory::mkIf(const expr &cond, Memory &&then, Memory &&els) {
28062744
els.non_local_block_liveness);
28072745
ret.local_block_liveness = expr::mkIf(cond, then.local_block_liveness,
28082746
els.local_block_liveness);
2809-
ret.has_stored_arg = expr::mkIf(cond, then.has_stored_arg,
2810-
els.has_stored_arg);
28112747
ret.local_blk_addr.add(els.local_blk_addr);
28122748
ret.local_blk_size.add(els.local_blk_size);
28132749
ret.local_blk_align.add(els.local_blk_align);
@@ -2957,7 +2893,6 @@ ostream& operator<<(ostream &os, const Memory &m) {
29572893
if (!m.local_blk_addr.empty()) {
29582894
os << "\nLOCAL BLOCK ADDR: " << m.local_blk_addr << '\n';
29592895
}
2960-
os << "\nSTORED ADDRS: " << m.has_stored_arg << '\n';
29612896
if (!m.ptr_alias.empty()) {
29622897
os << "\nALIAS SETS:\n";
29632898
for (auto &[bid, alias] : m.ptr_alias) {

ir/memory.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,6 @@ class Memory {
154154
smt::expr non_local_block_liveness; // BV w/ 1 bit per bid (1 if live)
155155
smt::expr local_block_liveness;
156156

157-
// TODO: change from short idx to arg number
158-
smt::expr has_stored_arg; // (short idx, short offset) -> bool
159-
160157
smt::FunctionExpr local_blk_addr; // bid -> (bits_size_t - 1)
161158
smt::FunctionExpr local_blk_size;
162159
smt::FunctionExpr local_blk_align;
@@ -227,10 +224,6 @@ class Memory {
227224
const std::vector<std::pair<unsigned, smt::expr>> &data,
228225
const std::set<smt::expr> &undef, uint64_t align);
229226

230-
// to implement the 'initializes' parameter attribute
231-
smt::expr hasStored(const Pointer &p, const smt::expr &bytes) const;
232-
void record_store(const Pointer &p, const smt::expr &bytes);
233-
234227
smt::expr blockValRefined(const Memory &other, unsigned bid, bool local,
235228
const smt::expr &offset,
236229
std::set<smt::expr> &undef) const;

ir/pointer.cpp

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static expr attr_to_bitvec(const ParamAttrs &attrs) {
6969
namespace IR {
7070

7171
Pointer::Pointer(const Memory &m, const expr &bid, const expr &offset,
72-
const expr &attr) : m(const_cast<Memory&>(m)),
72+
const expr &attr) : m(m),
7373
p(prepend_if(expr::mkUInt(0, 1 + padding_logical()),
7474
bid.concat(offset), hasLogicalBit())) {
7575
if (bits_for_ptrattrs)
@@ -78,7 +78,7 @@ Pointer::Pointer(const Memory &m, const expr &bid, const expr &offset,
7878
}
7979

8080
Pointer::Pointer(const Memory &m, const char *var_name,
81-
const ParamAttrs &attr) : m(const_cast<Memory&>(m)) {
81+
const ParamAttrs &attr) : m(m) {
8282
unsigned bits = bitsShortBid() + bits_for_offset;
8383
p = expr::mkVar(var_name, bits, false)
8484
.zext(hasLocalBit() + (1 + padding_logical()) * hasLogicalBit());
@@ -87,13 +87,12 @@ Pointer::Pointer(const Memory &m, const char *var_name,
8787
assert(p.bits() == totalBits());
8888
}
8989

90-
Pointer::Pointer(const Memory &m, expr repr)
91-
: m(const_cast<Memory&>(m)), p(std::move(repr)) {
90+
Pointer::Pointer(const Memory &m, expr repr) : m(m), p(std::move(repr)) {
9291
assert(!p.isValid() || p.bits() == totalBits());
9392
}
9493

9594
Pointer::Pointer(const Memory &m, unsigned bid, bool local, expr attr)
96-
: m(const_cast<Memory&>(m)), p(
95+
: m(m), p(
9796
prepend_if(expr::mkUInt(0, 1 + padding_logical()),
9897
prepend_if(expr::mkUInt(local, 1),
9998
expr::mkUInt(bid, bitsShortBid())
@@ -531,35 +530,12 @@ Pointer::isDereferenceable(const expr &bytes0, uint64_t align,
531530
bytes = bytes.round_up(expr::mkUInt(align, bytes));
532531
expr bytes_off = bytes.zextOrTrunc(bits_for_offset);
533532

534-
auto block_constraints = [&](const Pointer &p) {
533+
auto block_constraints = [=](const Pointer &p) {
535534
expr ret = p.isBlockAlive();
536535
if (iswrite)
537536
ret &= p.isWritable() && !p.isNoWrite();
538537
else if (!ignore_accessability)
539538
ret &= !p.isNoRead();
540-
541-
// If we are loading from an argument and it has the 'initializes'
542-
// attribute, make sure we have already stored to it before.
543-
if (!ignore_accessability && !iswrite) {
544-
auto &s = m.getState();
545-
for (auto &input0 : s.getFn().getInputs()) {
546-
auto &input = static_cast<const Input&>(input0);
547-
auto &inits = input.getAttributes().initializes;
548-
if (inits.empty())
549-
continue;
550-
551-
Pointer arg(m, s[input].value);
552-
expr offsets = true;
553-
for (auto [l, h] : inits) {
554-
offsets &= (p.getOffset().uge((arg + l).getOffset()) &&
555-
p.getOffset().ult((arg + h).getOffset())
556-
).implies(m.hasStored(p, bytes));
557-
}
558-
// TODO: isBasedOnArg is not sufficient; we have to store the arg number
559-
// in the pointer as we can have 2 args with same initializes attr
560-
ret&= (p.isBasedOnArg() && p.getBid() == arg.getBid()).implies(offsets);
561-
}
562-
}
563539
return ret;
564540
};
565541

@@ -592,7 +568,6 @@ Pointer::isDereferenceable(const expr &bytes0, uint64_t align,
592568
DisjointExpr<expr> addrs(expr::mkUInt(0, bits_ptr_address));
593569
expr ub = false;
594570
bool all_same_size = true;
595-
expr addr = is_phy ? p.getPhysicalAddress() : p.getAddress();
596571

597572
auto add = [&](unsigned start, unsigned limit, bool local) {
598573
for (unsigned i = start; i < limit; ++i) {
@@ -602,24 +577,20 @@ Pointer::isDereferenceable(const expr &bytes0, uint64_t align,
602577

603578
Pointer this_ptr(m, i, local, p.getAttrs());
604579

605-
bool same_size = bytes.eq(this_ptr.blockSizeAligned());
606-
expr this_addr = this_ptr.getLogAddress();
607-
expr offset = same_size ? expr::mkUInt(0, addr) : addr - this_addr;
608-
609580
expr cond = p.isInboundsOf(this_ptr, bytes, is_phy) &&
610-
block_constraints(this_ptr + offset);
581+
block_constraints(this_ptr);
611582
if (cond.isFalse())
612583
continue;
613584

614585
ub |= cond;
615586

616587
cond = p.isOfBlock(this_ptr, bytes, is_phy);
617588

618-
all_same_size &= same_size;
589+
all_same_size &= bytes.eq(this_ptr.blockSizeAligned());
619590

620591
bids.add(
621592
observes_local ? this_ptr.getBid() : this_ptr.getShortBid(), cond);
622-
addrs.add(std::move(this_addr), std::move(cond));
593+
addrs.add(this_ptr.getLogAddress(), std::move(cond));
623594
}
624595
};
625596
add(0, m.numLocals(), true);
@@ -631,6 +602,8 @@ Pointer::isDereferenceable(const expr &bytes0, uint64_t align,
631602
if (!observes_local)
632603
bid = mkLongBid(bid, false);
633604

605+
expr addr = is_phy ? p.getPhysicalAddress() : p.getAddress();
606+
634607
return { std::move(ub),
635608
Pointer(m, std::move(bid),
636609
all_same_size
@@ -711,9 +684,6 @@ Pointer::isDereferenceable(const expr &bytes0, uint64_t align,
711684
auto ptrs = std::move(all_ptrs)();
712685
p = ptrs ? *std::move(ptrs) : expr::mkUInt(0, totalBits());
713686

714-
if (!ignore_accessability && iswrite)
715-
m.record_store(*this, bytes);
716-
717687
return { std::move(exprs), *std::move(is_aligned)() };
718688
}
719689

ir/pointer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace IR {
1515
class Memory;
1616

1717
class Pointer {
18-
Memory &m;
18+
const Memory &m;
1919

2020
// [0, padding, bid, offset, attributes (1 bit for each)] -- logical pointer
2121
// [1, padding, address, attributes] -- physical pointer

llvm_util/llvm2alive.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "llvm/IR/IntrinsicsX86.h"
2020
#include "llvm/IR/Operator.h"
2121
#include "llvm/Support/ModRef.h"
22-
#include <algorithm>
2322
#include <sstream>
2423
#include <unordered_map>
2524
#include <unordered_set>
@@ -1510,7 +1509,7 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
15101509
unique_ptr<Instr>
15111510
handleRangeAttrNoInsert(const llvm::Attribute &attr, Value &val,
15121511
bool is_welldefined = false) {
1513-
auto &CR = attr.getValueAsConstantRange();
1512+
auto CR = attr.getValueAsConstantRange();
15141513
vector<Value*> bounds{ make_intconst(CR.getLower()),
15151514
make_intconst(CR.getUpper()) };
15161515
string name = "%#range_" + to_string(range_idx++) + "_" + val.getName();
@@ -1634,19 +1633,6 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
16341633
attrs.set(ParamAttrs::DeadOnUnwind);
16351634
break;
16361635

1637-
case llvm::Attribute::Initializes:
1638-
for (auto &CR : llvmattr.getInitializes()) {
1639-
auto l = CR.getLower().tryZExtValue();
1640-
auto h = CR.getUpper().tryZExtValue();
1641-
if (!l || !h) {
1642-
errorAttr(llvmattr);
1643-
return false;
1644-
}
1645-
attrs.initializes.emplace_back(*l, *h);
1646-
}
1647-
ranges::sort(attrs.initializes);
1648-
break;
1649-
16501636
default:
16511637
// If it is call site, it should be added at approximation list
16521638
if (!is_callsite)

smt/expr.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ expr expr::sdiv(const expr &rhs) const {
751751
if (rhs.isZero())
752752
return rhs;
753753

754-
if (isZero() || rhs.isOne())
754+
if (isZero())
755755
return *this;
756756

757757
if (isSMin() && rhs.isAllOnes())
@@ -767,7 +767,7 @@ expr expr::udiv(const expr &rhs) const {
767767
if (rhs.isZero())
768768
return rhs;
769769

770-
if (isZero() || rhs.isOne())
770+
if (isZero())
771771
return *this;
772772

773773
return binop_fold(rhs, Z3_mk_bvudiv);

0 commit comments

Comments
 (0)