Hello! "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387" is never matched by combine. The order of operands in x87 ficom compare is forced by combine in simplify_comparison () function. Float operator is treated as RTX_OBJ with a precedence over other operators and is always put in the first place.
Patch defines TARGET_CANONICALIZE_COMPARISON target hook to swap condition and operands to match ficom instruction. 2017-10-11 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.c (ix86_canonicalize_comparison): New function. (TARGET_CANONICALIZE_COMPARISON): Define. testsuite/ChangeLog: 2017-10-11 Uros Bizjak <ubiz...@gmail.com> * gcc.target/i386/387-ficom-2.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 253653) +++ config/i386/i386.c (working copy) @@ -4792,6 +4792,30 @@ ix86_conditional_register_usage (void) fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; } +/* Canonicalize a comparison from one we don't have to one we do have. */ + +static void +ix86_canonicalize_comparison (int *code, rtx *op0, rtx *op1, + bool op0_preserve_value) +{ + /* The order of operands in x87 ficom compare is forced by combine in + simplify_comparison () function. Float operator is treated as RTX_OBJ + with a precedence over other operators and is always put in the first + place. Swap condition and operands to match ficom instruction. */ + if (!op0_preserve_value + && GET_CODE (*op0) == FLOAT && MEM_P (XEXP (*op0, 0)) && REG_P (*op1)) + { + enum rtx_code scode = swap_condition ((enum rtx_code) *code); + + /* We are called only for compares that are split to SAHF instruction. + Ensure that we have setcc/jcc insn for the swapped condition. */ + if (ix86_fp_compare_code_to_integer (scode) != UNKNOWN) + { + std::swap (*op0, *op1); + *code = (int) scode; + } + } +} /* Save the current options */ @@ -49649,6 +49673,9 @@ ix86_run_selftests (void) #undef TARGET_CONDITIONAL_REGISTER_USAGE #define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage +#undef TARGET_CANONICALIZE_COMPARISON +#define TARGET_CANONICALIZE_COMPARISON ix86_canonicalize_comparison + #undef TARGET_LOOP_UNROLL_ADJUST #define TARGET_LOOP_UNROLL_ADJUST ix86_loop_unroll_adjust Index: testsuite/gcc.target/i386/387-ficom-2.c =================================================================== --- testsuite/gcc.target/i386/387-ficom-2.c (nonexistent) +++ testsuite/gcc.target/i386/387-ficom-2.c (working copy) @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=i386" } } */ +/* { dg-options "-Os -march=i386 -ffast-math -masm=att" } */ + +#include "387-ficom-1.c" + +/* { dg-final { scan-assembler-times "ficomps" 3 } } */ +/* { dg-final { scan-assembler-times "ficompl" 3 } } */