https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91323
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target| |x86_64-*-*, i?86-*-* --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Uroš Bizjak from comment #2) > (In reply to Ilya Leoshkevich from comment #0) > > I'm implementing signaling comparisons on S/390 and I'm trying to figure out > > whether or not LTGT is supposed to be signaling. > > I've decided to check what Intel does, and ran into what appears to be a > > bug. > > > > Consider the following functions: > > > > int f1(float a, float b) { return a < b || a > b; } > > int f2(float a, float b) { return __builtin_isless(a, b) || > > __builtin_isgreater(a, b); } > > int f3(float a, float b) { return __builtin_islessgreater(a, b); } > > > > gcc creates LTGT rtx for f1 and UNEQ for f2 and f3. > > However, for all 3 variants it then emits UCOMISS instruction. > > I would expect f1 to be compiled to COMISS, since I believe that comparison > > operators in C are supposed to be signaling. > > Based on the above observation, LTGT should trap, since either LT or GT > traps. > > It also means that __builtin_islessgreater is confusingly named. LTGT is the opposite of UNEQ. f1 produces LTGT since a long time (checked 4.8.5). It's combine_comparisons that does this transformation. We have (gdb) p (enum comparison_code)compcode $8 = COMPCODE_LTGT and then bool trap = (compcode & COMPCODE_UNORD) == 0 && (compcode != COMPCODE_EQ) && (compcode != COMPCODE_ORD); computes trap == true and thus we conclude we do not change trapping behavior. And indeed for example operation_could_trap_helper_p says LTGT_EXPR traps (makes sense if it is the opposite of UNEQ). And thus using UNEQ for the other two functions is correct as well. That means this is a target issue, LTGT isn't an unordered compare.