https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30484
--- Comment #23 from Richard Biener <rguenth at gcc dot gnu.org> --- RTL documents no specific behavior for 'div' but says 'ss_div' "ensures that an out-of-bounds result saturates to the maximum or minimum signed value". I'm not sure we want target specific semantics for the RTL IL, but since x86 at least has a valid 'div' for the case overflow is undefined we probably have to assume div by minus one might trap. Practically we already assume that give we simplify division by -1 to negate and have to assume that division by a non-constant amount traps since it could be a division by zero. That means practically speaking the -fwrapv issue remains. Since RTL doesn't document any specific behavior we have to generally expand signed division differently. Using b == -1 ? -a : a / b will for example generate cmpl $-1, %esi je .L5 cltd idivl %esi ... .L5: negl %eax ... We'd expect the following to pass. I wonder how many targets FAIL it, thus whether we can require that RTL sdiv has the desired overflow behavior for -fwrapv (it always appeared to me that RTL behaves as if -fwrapv). It works fine with the libgcc implementation for int128. /* { dg-additional-options "-fwrapv" } */ #define TYPE int #define UTYPE unsigned //#define TYPE __int128_t //#define UTYPE __uint128_t TYPE __attribute__((noipa)) div (TYPE a, TYPE b) { return a / b; } TYPE __attribute__((noipa)) neg (TYPE a) { return -a; } int main() { TYPE min = (TYPE)((UTYPE)1 << (sizeof(TYPE)*8-1)); if (div (min, -1) != min || neg (min) != min) __builtin_abort (); return 0; }