Hello!

Attached patch works around PR 63620. Patched gcc will allow only a
subset of CONST_DOUBLEs in FP push patterns. This subset will result
in direct immediates that can always be encoded directly in the insn
stream. These won't be reloaded through memory, and will avoid PIC
register re-materialization issues. OTOH, the patch will generate
non-optimal push sequences when general registers are available.

2014-10-31  Uros Bizjak  <ubiz...@gmail.com>

    PR target/63620
    * config/i386/i386.md (*pushtf): Allow only CONST_DOUBLES that won't
    be reloaded through memory.
    (*pushxf): Ditto.
    (*pushdf): Ditto.

The patch was bootstrapped and regression tested on x86_64-linux-gnu
{-m32}. The patch was also checked with Darwin crosscompiler on the
testcases in the PR.

Committed to mainline.

Uros
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 216983)
+++ config/i386/i386.md (working copy)
@@ -2733,10 +2733,14 @@
 
 ;; Floating point push instructions.
 
+;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
 (define_insn "*pushtf"
   [(set (match_operand:TF 0 "push_operand" "=<,<")
        (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
-  "TARGET_64BIT || TARGET_SSE"
+  "(TARGET_64BIT || TARGET_SSE)
+   && (!can_create_pseudo_p ()
+       || GET_CODE (operands[1]) != CONST_DOUBLE
+       || standard_sse_constant_p (operands[1]))"
 {
   /* This insn should be already split before reg-stack.  */
   gcc_unreachable ();
@@ -2758,10 +2762,13 @@
   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
 })
 
+;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
 (define_insn "*pushxf"
   [(set (match_operand:XF 0 "push_operand" "=<,<")
        (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
-  ""
+  "!can_create_pseudo_p ()
+   || GET_CODE (operands[1]) != CONST_DOUBLE
+   || standard_80387_constant_p (operands[1]) > 0"
 {
   /* This insn should be already split before reg-stack.  */
   gcc_unreachable ();
@@ -2789,10 +2796,16 @@
   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
 })
 
+;; %%% Remove CONST_DOUBLE workaround after PR63620 is fixed!
 (define_insn "*pushdf"
   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
        (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
-  ""
+  "!can_create_pseudo_p ()
+   || GET_CODE (operands[1]) != CONST_DOUBLE
+   || (!(TARGET_SSE2 && TARGET_SSE_MATH)
+       && standard_80387_constant_p (operands[1]) > 0)
+   || (TARGET_SSE2 && TARGET_SSE_MATH
+       && standard_sse_constant_p (operands[1]))"
 {
   /* This insn should be already split before reg-stack.  */
   gcc_unreachable ();

Reply via email to