https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77669
--- Comment #1 from wgh at beyondunreal dot com --- The loop in question looks like this, in C++ and aseembly: if (__urngrange > __urange) { // downscaling const __uctype __uerange = __urange + 1; // __urange can be zero const __uctype __scaling = __urngrange / __uerange; const __uctype __past = __uerange * __scaling; do __ret = __uctype(__urng()) - __urngmin; while (__ret >= __past); __ret /= __scaling; } 080001d6 <_ZNSt24uniform_int_distributionIiEclISt26linear_congruential_engineIjLj48271ELj0ELj2147483647EEEEiRT_RKNS0_10param_typeE.constprop.6>: ... ... 80001f4: f7ff ffda bl 80001ac <_ZNSt8__detail4_ModIjLj2147483647ELj48271ELj0ELb0ELb1EE6__calcEj> 80001f8: 1e43 subs r3, r0, #1 80001fa: 429c cmp r4, r3 80001fc: d9fa bls.n 80001f4 <_ZNSt24uniform_int_distributionIiEclISt26linear_congruential_engineIjLj48271ELj0ELj2147483647EEEEiRT_RKNS0_10param_typeE.constprop.6+0x1e> So LCG has been greatly optimized and has become a single __calc call. gdb shows some extra "fake" frames, even though they have been optimized out. #0 __calc (__x=0) at /usr/lib/gcc/armv7m-hardfloat-eabi/5.4.0/include/g++-v5/bits/random.tcc:62 #1 0x080001f8 in std::__detail::__mod<unsigned int, 2147483647u, 48271u, 0u>(unsigned int) () at /usr/lib/gcc/armv7m-hardfloat-eabi/5.4.0/include/g++-v5/bits/random.h:151 #2 operator() (this=0x20000430 <random_engine>) at /usr/lib/gcc/armv7m-hardfloat-eabi/5.4.0/include/g++-v5/bits/random.h:332 #3 operator() (this=this@entry=0x2001ffd0, __param=..., __urng=...) at /usr/lib/gcc/armv7m-hardfloat-eabi/5.4.0/include/g++-v5/bits/uniform_int_dist.h:242 #4 0x080002be in operator() (__urng=..., this=0x2001ffd0) at /usr/lib/gcc/armv7m-hardfloat-eabi/5.4.0/include/g++-v5/bits/uniform_int_dist.h:16 The __calc function looks like this in assembly: 080001ac <_ZNSt8__detail4_ModIjLj2147483647ELj48271ELj0ELb0ELb1EE6__calcEj>: 80001ac: f64a 52c8 movw r2, #44488 ; 0xadc8 80001b0: fbb0 f1f2 udiv r1, r0, r2 80001b4: fb02 0311 mls r3, r2, r1, r0 80001b8: f64b 428f movw r2, #48271 ; 0xbc8f 80001bc: 4353 muls r3, r2 80001be: f640 5247 movw r2, #3399 ; 0xd47 80001c2: fb02 f001 mul.w r0, r2, r1 80001c6: 4283 cmp r3, r0 80001c8: bf3c itt cc 80001ca: f103 4300 addcc.w r3, r3, #2147483648 ; 0x80000000 80001ce: f103 33ff addcc.w r3, r3, #4294967295 ; 0xffffffff 80001d2: 1a18 subs r0, r3, r0 80001d4: 4770 bx lr It should calculate x = (ax + c) mod m, where a = 48271u, c = 0u, m = 2147483647u So in case of x=0, new x will also be zero. Hmm, sounds weird.