Marina Polyakova <m.polyak...@postgrespro.ru> writes: > On 13-01-2018 21:10, Tom Lane wrote: >> I'm not sure there's much we can do about this. Dropping the use >> of the alignment spec isn't a workable option. If there were a >> simple way for configure to detect that the compiler generates bad >> code for that, we could have it do so and reject use of __int128, >> but it'd be up to you to come up with a workable test.
> I'll think about it.. Attached is a possible test program. I can confirm it passes on a machine with working __int128, but I have no idea whether it will detect the problem on yours. If not, maybe you can tweak it? regards, tom lane
#include <stddef.h> #include <stdio.h> /* GCC, Sunpro and XLC support aligned */ #if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__) #define pg_attribute_aligned(a) __attribute__((aligned(a))) #endif typedef __int128 int128a #if defined(pg_attribute_aligned) pg_attribute_aligned(8) #endif ; /* * These are globals to discourage the compiler from folding all the * arithmetic tests down to compile-time constants. We do not have * convenient support for 128bit literals at this point... */ struct glob128 { __int128 start; char pad; int128a a; int128a b; int128a c; int128a d; } g = {0, 'p', 48828125, 97656255, 0, 0}; int main() { if (offsetof(struct glob128, a) < 17 || offsetof(struct glob128, a) > 24) { printf("wrong alignment, %d\n", (int) offsetof(struct glob128, a)); return 1; } g.a = (g.a << 12) + 1; /* 200000000001 */ g.b = (g.b << 12) + 5; /* 400000000005 */ /* use the most relevant arithmetic ops */ g.c = g.a * g.b; g.d = (g.c + g.b) / g.b; /* return different values, to prevent optimizations */ if (g.d != g.a + 1) { printf("wrong arithmetic result\n"); return 1; } printf("A-OK!\n"); return 0; }