From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jim Wilson To: rth@cygnus.com (Richard Henderson) Cc: hjl@lucon.org (H.J. Lu), egcs@cygnus.com Subject: Re: glibc 2.0.5 is miscompiled by egcs 970904 Date: Sun, 07 Sep 1997 17:36:00 -0000 Message-id: <199709080036.RAA22284@cygnus.com> References: <199709072243.PAA04342@rtl.cygnus.com> X-SW-Source: 1997-09/msg00264.html > asm volatile > ("cmoveq %1, 1, %0\n\t" > "ret $31, (%2), 1" > : "=r" (retval) > : "0" (val), "r" (retpc)); I would call this a bug in the asm. It is assuming that $0 (retval) will be used for operand 0. If this is not done, then the pattern fails because it contains a return instruction. However, it is not safe to make this assumption because the use of a matching contraint for operand 1 means that a reload is necessary. When a reload is required, reload makes no guarantees about where the reload instruction will be emitted. It may emit an input reload before the asm, or it may emit an output reload after the asm. In this case, it is emitting an output reload after the asm. This instruction then gets optimized away because reload is smart enough to know that there aren't any following instructions that use its value. This is the right thing to do in general, because it means that we emit one less instruction, and gcc is after all an optimizing compiler. A much better way to write this is: retval = val; asm volatile ("cmoveq %1, 1, %0\n\t" "ret $31, (%2), 1" : "=r" (retval) : "0" (retval), "r" (retpc)); Now, no reloads are necessary, and the pattern will always do what you expect. We even get better code this way, because now the move instruction is explicit, we get the benefit of instruction scheduling. An even better way to write this is: retval = val ? val : 1; asm volatile ("ret $31, (%0), 1" : : "r" (retpc), "r" (retval)); This just uses the asm for stuff that can't be written in C. Jim