On 2017-02-13 21:47 -0800, Evan Nemerson wrote: > I'm trying to put together a macro to abstract away some compiler > differences, but I'm having trouble with __builtin_assume_aligned, > and > I'm not sure how to generate a reliable test case. You can adapt source code in GCC testsuite. It's in gcc/testsuite/gcc.dg/builtin-assume-aligned-1.c On modern system it would be optimized to use SIMD instructions. SIMD instructions require strict alignment. So, if assume_aligned _doesn't_ work, the (assembly or object) code would bloat up since the compiler have to deal with several leading elements not aligned. > For ICC there is __assume_aligned. This is what I'm looking to > emulate; you just pass it a pointer and the desired alignment: > > __assume_aligned(arg, 16) > /* Compiler knows arg is 16-byte aligned */ > > For MSVC there is __assume, which is a bit of a pain to use, but > basically you pass an expression (which evaluates to true if the > variable is aligned as expected). Something like > > __assume((((char*) arg) - ((char*) 0)) % (16) == 0) > /* Compiler knows arg is 16-byte aligned */ I am not sure weather it work. > GCC 4.7+, OTOH, does things a bit different. It returns a value, and > you're supposed to use the returned value: > > void* x = __builtin_assume_aligned(arg, 16); > /* Compiler knows x is 16-byte aligned */ > > My question is, with __builtin_assume_aligned, does GCC know that > *arg* > (not x) is 16-byte aligned? Basically, can I use it like > __assume_aligned? According to my test (on GCC 6.3.0), no. But following code works well: #define assume_aligned(_ptr, _align) \ ((void) ((_ptr) = __builtin_aligned((_ptr), (_align)))) > Also, for 4.5+ (when __builtin_unreachable was added), if I do > something like > > #define assume_aligned(arg, align) \ > ((((char*) ptr) - ((char*) 0)) % (align) == 0) ? \ > (0) : __builtin_unreachable() > > Would GCC know that arg is aligned? No. It's no use. -- Xi Ruoyao <ryxi@xxxxxxxxxxxxxxxxx> School of Aerospace Science and Technology, Xidian University