Skip to content

Commit

Permalink
consider fncall param aligns when calculating access size (#596)
Browse files Browse the repository at this point in the history
  • Loading branch information
aqjune committed Nov 30, 2020
1 parent dbcdd6d commit 1a84981
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
37 changes: 27 additions & 10 deletions ir/instr.cpp
Expand Up @@ -1565,19 +1565,36 @@ uint64_t FnCall::getMaxAccessSize() const {
}

FnCall::ByteAccessInfo FnCall::getByteAccessInfo() const {
bool has_deref = getAttributes().has(FnAttrs::Dereferenceable);
if (!has_deref) {
for (auto &arg : args)
if (arg.second.has(ParamAttrs::Dereferenceable)) {
has_deref = true;
break;
}
auto &retattr = getAttributes();
bool has_deref = retattr.has(FnAttrs::Dereferenceable);
uint64_t bytesize = has_deref ? gcd(retattr.derefBytes, retattr.align) : 0;

for (auto &arg : args) {
if (!arg.first->getType().isPtrType())
continue;

if (arg.second.has(ParamAttrs::Dereferenceable)) {
has_deref = true;
// Without align, nothing is guaranteed about the bytesize
uint64_t b = gcd(arg.second.derefBytes, arg.second.align);
bytesize = bytesize ? gcd(bytesize, b) : b;
}
// Pointer arguments without dereferenceable attr don't contribute to the
// byte size.
// call f(* dereferenceable(n) align m %p, * %q) is equivalent to a dummy
// load followed by a function call:
// load i<8*n> %p, align m
// call f(* %p, * %q)
// f(%p, %q) does not contribute to the bytesize. After bytesize is fixed,
// function calls update a memory with the granularity.
}
if (!has_deref)
if (!has_deref) {
// No dereferenceable attribute
assert(bytesize == 0);
return {};
// dereferenceable(n) does not guarantee that the pointer is n-byte aligned
return ByteAccessInfo::anyType(1);
}

return ByteAccessInfo::anyType(bytesize);
}


Expand Down
16 changes: 16 additions & 0 deletions tests/alive-tv/opt-memory/deref-align-callee.srctgt.ll
@@ -0,0 +1,16 @@
; TEST-ARGS: -dbg

declare void @f(i32*)

define void @src(i32* dereferenceable(4) align 4 %p) {
call void @f(i32* dereferenceable(4) %p)
ret void
}

define void @tgt(i32* dereferenceable(4) align 4 %p) {
call void @f(i32* dereferenceable(4) %p)
ret void
}


; CHECK: min_access_size: 1
17 changes: 17 additions & 0 deletions tests/alive-tv/opt-memory/deref-align-callee2.srctgt.ll
@@ -0,0 +1,17 @@
; TEST-ARGS: -dbg

declare dereferenceable(8) align 4 i32* @f()

define void @src() {
%r = call i32* @f()
store i32 0, i32* %r, align 4
ret void
}

define void @tgt() {
%r = call i32* @f()
store i32 0, i32* %r, align 4
ret void
}

; CHECK: min_access_size: 4

0 comments on commit 1a84981

Please sign in to comment.