https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79593
--- Comment #12 from Uroš Bizjak <ubizjak at gmail dot com> --- (In reply to Katsunori Kumatani from comment #10) > (In reply to Uroš Bizjak from comment #7) > > > > This patch allows conversion from (reg->reg) move to (const->reg) when > > appropriate constant can be determined from REG_EQUIV/REG_EQUAL note. It > > also handles float_extend cases. Patched gcc now generates: > > > > Hi, thank you for patch, patch looks better indeed, but there is still this > I am speaking about at the beginning: > > fld %st(0) > flds global_data+4 > fxch %st(3) > fcomip %st(2), %st > fstp %st(1) > > Shouldn't this instead be: > > flds global_data+4 > fxch %st(2) > fcomip %st(1), %st > > GCC 5 does generate the latter case so GCC 5 generates better code (optimal > in this small case). In fact, this seems to have to do with "floating point > type conversions". The conversions are implicit there, so there's no point > in doing it like this. (one of the few good things about x87 apart from > automatic high precision) > > For example, if you change my code to instead use 'float' instead of 'long > double' and change the constants to float literals, it will generate code > like GCC 5 in this respect. Can you look into it? I'm really sorry I'm not > familiar with GCC internals at all. > > That's why I thought it was a regression in some way when "converting" > floating point types. It only happens after GCC 6. > > If I change floating point types to 'float', GCC 6 generates this portion at > beginning: > > flds global_data+4 > fxch %st(2) > fcomip %st(1), %st > > Which is exactly the same as GCC 5 -- but GCC 5 does it even on 'long > double' and when loading floats. It's obviously worse code for some reason. > > > Yes using floats is a workaround for this small code, because none of the > registers get spilled to the stack. However, in real code, I want to use > 'long double' because it's likely it will have to get spilled on the stack. > And one of the main reasons I'm using x87 is for that extra precision in > this particular code. > > It's not that "long double" generates bad code. It's simply the conversion > from "float" to "long double" that does it, I believe. It's as if GCC 6 > doesn't know float and long double are the same thing in a x87 register. Please see Comment #8. The target-independent middle-end part keeps float and long float version of the value from global_data live, so it can optimize the compare later in the insn stream. This is not optimal for x87, but I doubt it is a runtime regression.