take arguments' align into account when calculating bits_byte
ADD
tests/alive-tv/attrs/dereferenceable-align-fail2.srctgt.ll
+define void @src(i1 %c, i32* dereferenceable(4) %p) {
+ br i1 %c, label %A, label %B
+A:
+ load i32, i32* %p, align 4
+ ret void
+B:
+ ret void
+}
+
+define void @tgt(i1 %c, i32* dereferenceable(4) %p) {
+ load i32, i32* %p, align 4 ; %p may not be aligned
+ br i1 %c, label %A, label %B
+A:
+ ret void
+B:
+ ret void
+}
+
+; ERROR: Source is more defined than target

ADD
tests/alive-tv/attrs/dereferenceable-align.srctgt.ll
+define void @src(i1 %c, i32* dereferenceable(4) align 4 %p) {
+ br i1 %c, label %A, label %B
+A:
+ load i32, i32* %p, align 4
+ ret void
+B:
+ ret void
+}
+
+define void @tgt(i1 %c, i32* dereferenceable(4) align 4%p) {
+ load i32, i32* %p, align 4
+ br i1 %c, label %A, label %B
+A:
+ ret void
+B:
+ ret void
+}

MODIFY
tools/transform.cpp
tools/transform.cpp
@@ -673,20 +673,25 @@ static void calculateAndInitConstants(Transform &t) {
for (auto &v : fn->getInputs()) {
auto *i = dynamic_cast<const Input *>(&v);
- if (i && i->hasAttribute(ParamAttrs::Dereferenceable)) {
+ if (!i)
+ continue;
+
+ uint64_t align = i->hasAttribute(ParamAttrs::Align) ?
+ 1ull << i->getAttributes().align : 1;
+ if (i->hasAttribute(ParamAttrs::Dereferenceable)) {
does_mem_access = true;
uint64_t deref_bytes = i->getAttributes().derefBytes;
- min_access_size = gcd(min_access_size, deref_bytes);
+ min_access_size = gcd(min_access_size, gcd(deref_bytes, align));
max_access_size = max(max_access_size, deref_bytes);
}
- if (i && i->hasAttribute(ParamAttrs::ByVal)) {
+ if (i->hasAttribute(ParamAttrs::ByVal)) {
does_mem_access = true;
auto sz = i->getAttributes().blockSize;
max_access_size = max(max_access_size, sz);
min_global_size = min_global_size != UINT64_MAX
? gcd(sz, min_global_size)
: sz;
- min_global_size = gcd(min_global_size, i->getAttributes().align);
+ min_global_size = gcd(min_global_size, align);
}
}

take arguments' align into account when calculating bits_byte (#590)