Fill padding with poison when loading an aggregate value
MODIFY
ir/memory.cpp
ir/memory.cpp
@@ -1947,13 +1947,19 @@ StateValue Memory::load(const Pointer &ptr, const Type &type, set<expr> &undef,
vector<StateValue> member_vals;
unsigned byteofs = 0;
for (unsigned i = 0, e = aty->numElementsConst(); i < e; ++i) {
+ // Padding is filled with poison.
+ if (aty->isPadding(i)) {
+ byteofs += getStoreByteSize(aty->getChild(i));
+ continue;
+ }
+
auto ptr_i = ptr + byteofs;
auto align_i = gcd(align, byteofs % align);
member_vals.emplace_back(load(ptr_i, aty->getChild(i), undef, align_i));
byteofs += getStoreByteSize(aty->getChild(i));
}
assert(byteofs == bytecount);
- return aty->aggregateVals(member_vals);
+ return aty->aggregateVals(member_vals, true);
}
bool is_ptr = type.isPtrType();

ADD
tests/alive-tv/memory/aggregate-padding.srctgt.ll
+@glb = global {i8, i32} undef, align 4
+
+define i8 @src() {
+ %p = bitcast {i8, i32}* @glb to i32*
+ store i32 0, i32* %p, align 4 ; fill padding with 0
+
+ %v = load {i8, i32}, {i8, i32}* @glb ;padding should be poison
+ store {i8, i32} %v, {i8, i32}* @glb, align 4
+
+ %p2 = bitcast {i8, i32}* @glb to i8*
+ %p3 = getelementptr i8, i8* %p2, i64 1
+ %padding = load i8, i8* %p3
+ ret i8 %padding
+}
+
+define i8 @tgt() {
+ %p = bitcast {i8, i32}* @glb to i32*
+ store i32 0, i32* %p, align 4
+
+ ret i8 undef
+}

Fill padding with poison when loading an aggregate value (#464)