This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug lto/77669] Incorrect LTO code on embedded ARM


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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]