On Thu, Aug 07, 2025 at 03:25:45PM +0000, Thomas de Bock wrote: > "I see what you mean, I think there is probably no way to apply the > optimization to all functions then indeed, since there is no way to > know if the early break on inequality of a field was arbitrary > or because it indicates the following data will be out of range. > My main goal currently though is applying the optimization to > the default comparison operator, and is it not undefined > behaviour to call it on an incomplete struct? > > For -O2: > bool __attribute__((noinline)) > f(std::array<int32_t, 4>* x, std::array<int32_t, 4>* y) { > return *x == *y; > } > > int main() { > > std::array<int32_t, 4>* a; > std::array<int32_t, 4>* b; > a = (std::array<int32_t, 4>*)malloc(sizeof(std::array<int32_t, 3>)); > b = (std::array<int32_t, 4>*)malloc(sizeof(std::array<int32_t, 3>)); > return f(a, b);
This has both arrays uninitialized, so it is obviously invalid. What I'm worried about is when they are initialized and are guaranteed to differ in the first allocated part. One case is when all the members are part of the same struct, another is when you have multiple structs. struct A { char a, b, c, d; }; struct B { struct A e; char f, g, h, i; }; bool foo (struct A *p, struct A *q) { if (p->a != q->a) return false; if (p->b != q->b) return false; if (p->c != q->c) return false; if (p->d != q->d) return false; struct B *r = (struct B *) p; struct B *s = (struct B *) q; if (r->f != s->f) return false; if (r->g != s->g) return false; if (r->h != s->h) return false; if (r->i != s->i) return false; return true; } >From the IL all the loads are still from the same base in ascending order, but I think it must be just fine to call this with only A allocated if they differ in the first 4 elements, so optimizing this say into 64-bit loads is only ok if the pointers are guaranteed to be 64-bit aligned. Jakub