C++: Bypassing strict-aliasing through union, then use __restrict extension
Asked Answered
M

0

0

I wonder if it is possible to tailor strict aliasing requirements to specifically designed cases, while still preserving strict aliasing in general or -O2/-O3 optimization respectively.

To be more precise, in cases where it is needed, strict aliasing can be bypassed using an anonymous union (as pointed out here and here):

#define PTR_CAST(type, x) &(((union {typeof(*x) src; type dst;}*) &(x))->dst)

Now I wonder if using __restrict on a pointer obtained by such a cast would re-enable no-alias optimizations in the compiler (or if such a pointer and all copies of it would be considered potentially aliasing for all times). Like this:

void bar(float* __restrict a, float* __restrict b) {
   // Do something with a and b assuming they don't overlap.
}

void baz(float* c) { /* Do something with c... */ }

void foo() {
   int32_t* buffer = new int32_t[1000];
   // Do something with buffer...

   float* bufCast1 = PTR_CAST(float, buffer);
   float* bufCast2 = PTR_CAST(float, buffer + 500);

   // Can the arguments be successfully __restrict-ed in this case?
   bar(bufCast1, bufCast2);

   // Also, would bufCast1 be treated as potentially aliasing inside of baz()?
   baz(bufCast1);
}
Misdate answered 6/9, 2013 at 21:46 Comment(5)
Almost everything you mention is not C++, but some compiler extension or other. So consult your compiler's documentation and study the generated machine code. That said, __restrict is a promise by you that the pointers don't point to overlapping data.Carroty
Aliasing through unions is widely supported, to the point where it's technically an extension but portable in the big majority of cases. The __restrict is clearly an extension but also one that's widely supported. The question was if __restrict usually overrides any other aliasing information in the compilation or if it is rendered useless once the compiler's own alias analysis pulls the red flag when encountering a union-based cast.Misdate
How would the compiler know? If bar is in a separate TU, the compiler has to trust you that you're not lying to it. But as I said, easiest to just check how the machine code comes out.Carroty
Well, yea, right, makes sense. I guess clang can do link-time optimizations where it probably would be able to figure this out across TUs.Misdate
@RafaelSpring: Given that __restrict would entitle a compiler to assume that two pointers won't have an aliasing conflict even if they are the same type, why should a compiler not apply the same assumption in other cases where the types would not rule out aliasing but the __restrict qualifier would?Michaud

© 2022 - 2024 — McMap. All rights reserved.