/* { dg-do run { target aarch64*-*-* } } */ /* { dg-options "-O" } */ typedef signed long long int S; typedef unsigned long long int U; typedef __int128 W; __attribute__ ((noinline, noclone)) U upseu (U x, S y, int *ovf) { U res; *ovf = __builtin_add_overflow (x, y, &res); return res; } U usueu (U x, U y, int *ovf) { U res; *ovf = __builtin_sub_overflow (x, y, &res); return res; } U usseu (U x, S y, int *ovf) { U res; *ovf = __builtin_sub_overflow (x, y, &res); return res; } int main () { int i, j; for (i = 0; i < ((unsigned char) ~0); i++) for (j = 0; j < ((unsigned char) ~0); j++) { U u1 = ((W) i << ((8 - 1) * 8)); S s2 = ((W) j << ((8 - 1) * 8)) + (-0x7fffffffffffffffLL - 1); U u2 = ((W) j << ((8 - 1) * 8)); W w; int ovf; w = ((W) u1) + ((W) s2); if (upseu (u1, s2, &ovf) != (U) w || ovf != (w != (U) w)) __builtin_abort (); w = ((W) u1) - ((W) u2); if (usueu (u1, u2, &ovf) != (U) w || ovf != (w != (U) w)) __builtin_abort (); w = ((W) u1) - ((W) s2); if (usseu (u1, s2, &ovf) != (U) w || ovf != (w != (U) w)) __builtin_abort (); } }