Skip to content

Commit

Permalink
memset doesn't extend the deref check to a multiple of alignment
Browse files Browse the repository at this point in the history
According to LangRef, although this is incompatible with load/store semantics
  • Loading branch information
nunoplopes committed Apr 29, 2024
1 parent a95b207 commit 74bd584
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 9 deletions.
2 changes: 1 addition & 1 deletion ir/instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3992,7 +3992,7 @@ DEFINE_AS_RETZEROALIGN(Memset, getMaxAllocSize);
DEFINE_AS_RETZERO(Memset, getMaxGEPOffset);

uint64_t Memset::getMaxAccessSize() const {
return round_up(getIntOr(*bytes, UINT64_MAX), align);
return getIntOr(*bytes, UINT64_MAX);
}

MemInstr::ByteAccessInfo Memset::getByteAccessInfo() const {
Expand Down
2 changes: 1 addition & 1 deletion ir/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2022,7 +2022,7 @@ void Memory::memset(const expr &p, const StateValue &val, const expr &bytesize,
unsigned bytesz = bits_byte / 8;
Pointer ptr(*this, p);
if (deref_check)
state->addUB(ptr.isDereferenceable(bytesize, align, true));
state->addUB(ptr.isDereferenceable(bytesize, align, true, false, false));

auto wval = val;
for (unsigned i = 1; i < bytesz; ++i) {
Expand Down
13 changes: 8 additions & 5 deletions ir/pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,11 @@ static pair<expr, expr> is_dereferenceable(Pointer &p,
// When bytes is 0, pointer is always dereferenceable
pair<AndExpr, expr>
Pointer::isDereferenceable(const expr &bytes0, uint64_t align,
bool iswrite, bool ignore_accessability) {
expr bytes = bytes0.zextOrTrunc(bits_size_t)
.round_up(expr::mkUInt(align, bits_size_t));
bool iswrite, bool ignore_accessability,
bool round_size_to_align) {
expr bytes = bytes0.zextOrTrunc(bits_size_t);
if (round_size_to_align)
bytes = bytes.round_up(expr::mkUInt(align, bits_size_t));
expr bytes_off = bytes.zextOrTrunc(bits_for_offset);

DisjointExpr<expr> UB(expr(false)), is_aligned(expr(false)), all_ptrs;
Expand Down Expand Up @@ -466,9 +468,10 @@ Pointer::isDereferenceable(const expr &bytes0, uint64_t align,

pair<AndExpr, expr>
Pointer::isDereferenceable(uint64_t bytes, uint64_t align,
bool iswrite, bool ignore_accessability) {
bool iswrite, bool ignore_accessability,
bool round_size_to_align) {
return isDereferenceable(expr::mkUInt(bytes, bits_size_t), align, iswrite,
ignore_accessability);
ignore_accessability, round_size_to_align);
}

// This function assumes that both begin + len don't overflow
Expand Down
6 changes: 4 additions & 2 deletions ir/pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ class Pointer {
smt::expr isAligned(const smt::expr &align);
std::pair<smt::AndExpr, smt::expr>
isDereferenceable(uint64_t bytes, uint64_t align, bool iswrite = false,
bool ignore_accessability = false);
bool ignore_accessability = false,
bool round_size_to_align = true);
std::pair<smt::AndExpr, smt::expr>
isDereferenceable(const smt::expr &bytes, uint64_t align, bool iswrite,
bool ignore_accessability = false);
bool ignore_accessability = false,
bool round_size_to_align = true);

void isDisjointOrEqual(const smt::expr &len1, const Pointer &ptr2,
const smt::expr &len2) const;
Expand Down
15 changes: 15 additions & 0 deletions tests/alive-tv/memory/memset-align2.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
define void @src(ptr %P) {
%arrayidx = getelementptr inbounds i32, ptr %P, i64 1
store i32 0, ptr %arrayidx, align 4
%add.ptr = getelementptr inbounds i32, ptr %P, i64 2
tail call void @llvm.memset.p0.i64(ptr %add.ptr, i8 0, i64 11, i1 false)
ret void
}

define void @tgt(ptr %P) {
%arrayidx = getelementptr inbounds i8, ptr %P, i64 4
tail call void @llvm.memset.p0.i64(ptr align(4) %arrayidx, i8 0, i64 15, i1 false)
ret void
}

declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)

0 comments on commit 74bd584

Please sign in to comment.