[i386] : Re-enable FICOM instruction with IX86_FPCMP_SAHF FP comparison strategy

Message ID CAFULd4ZEGeYYDP2v+q2TvgNWQL1JJvo3Wfz2uCsxxrbqTW3+xA@mail.gmail.com
State New
Headers show
Series
  • [i386] : Re-enable FICOM instruction with IX86_FPCMP_SAHF FP comparison strategy
Related show

Commit Message

Uros Bizjak Oct. 11, 2017, 9:22 p.m.
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  <ubizjak@gmail.com>

    * config/i386/i386.c (ix86_canonicalize_comparison): New function.
    (TARGET_CANONICALIZE_COMPARISON): Define.

testsuite/ChangeLog:

2017-10-11  Uros Bizjak  <ubizjak@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.

Patch

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 } } */