Hello!

Attached patch adds new insn_and_split pattern to handle pre_modify
XFmode push variant. -m96bit-long-double option sets XFmode size to 12
bytes that is not divisible with push size (8 bytes), resulting in
pre_modify push variant.

2017-03-02  Uros Bizjak  <ubiz...@gmail.com>

    PR target/79514
    * config/i386/i386.md (*pushxf_rounded): New insn_and_split pattern.

testsuite/ChangeLog:

2017-03-02  Uros Bizjak  <ubiz...@gmail.com>

    PR target/79514
    * gcc.target/i386/pr79514.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline, will be backported to release branches.

Uros.
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 245842)
+++ config/i386/i386.md (working copy)
@@ -3015,6 +3015,36 @@
   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
 })
 
+(define_insn_and_split "*pushxf_rounded"
+  [(set (mem:XF
+         (pre_modify:DI
+           (reg:DI SP_REG)
+           (plus:DI (reg:DI SP_REG) (const_int -16))))
+       (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
+  "TARGET_64BIT"
+  "#"
+  "&& 1"
+  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
+   (set (match_dup 1) (match_dup 0))]
+{
+  rtx pat = PATTERN (curr_insn);
+  operands[1] = SET_DEST (pat);
+
+  /* Preserve memory attributes. */
+  operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
+}
+  [(set_attr "type" "multi")
+   (set_attr "unit" "i387,*,*,*")
+   (set (attr "mode")
+       (cond [(eq_attr "alternative" "1,2,3")
+                (const_string "DI")
+             ]
+             (const_string "XF")))
+   (set (attr "preferred_for_size")
+     (cond [(eq_attr "alternative" "1")
+              (symbol_ref "false")]
+           (symbol_ref "true")))])
+
 (define_insn "*pushxf"
   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
        (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
Index: testsuite/gcc.target/i386/pr79514.c
===================================================================
--- testsuite/gcc.target/i386/pr79514.c (nonexistent)
+++ testsuite/gcc.target/i386/pr79514.c (working copy)
@@ -0,0 +1,12 @@
+/* PR target/79514 */
+/* { dg-do compile } */
+/* { dg-options "-m96bit-long-double" } */
+
+extern void bar (long double);
+
+extern long double x;
+
+void foo (void)
+{
+  bar (x);
+}

Reply via email to