This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/20020] x86_64 - 128 bit structs not targeted to TImode


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20020

--- Comment #36 from H.J. Lu <hjl.tools at gmail dot com> 2012-08-15 01:23:54 UTC ---
(In reply to comment #35)
> Note that for the test case in comment #34 (and comment #9) to fail that the
> MAX_FIXED_MODE_SIZE patch has to be applied, and likely GCC internal checking
> has to be enabled.

This patch seems to work:

diff --git a/gcc/calls.c b/gcc/calls.c
index 5bc1b1e..8b95baf 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3345,7 +3345,13 @@ expand_call (tree exp, rtx target, int ignore)
       sibcall_failure = 1;
     }
       else
-    target = copy_to_reg (avoid_likely_spilled_reg (valreg));
+    {
+      rtx val = avoid_likely_spilled_reg (valreg);
+      if (target && GET_MODE (val) != GET_MODE (target))
+        target = copy_from_reg (target, val, rettype);
+      else
+        target = copy_to_reg (val);
+    }

       /* If we promoted this return value, make the proper SUBREG.
          TARGET might be const0_rtx here, so be careful.  */
diff --git a/gcc/expr.c b/gcc/expr.c
index 4e7eb5f..8bd57eb 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2084,32 +2084,20 @@ emit_group_store (rtx orig_dst, rtx src, tree type
ATTRIBUTE_UNUSED, int ssize)
     emit_move_insn (orig_dst, dst);
 }

-/* Generate code to copy a BLKmode object of TYPE out of a
-   set of registers starting with SRCREG into TGTBLK.  If TGTBLK
-   is null, a stack temporary is created.  TGTBLK is returned.
+/* Generate code to copy an object of TYPE out of a set of registers
+   starting with SRCREG into TGTBLK.  TGTBLK is returned.

    The purpose of this routine is to handle functions that return
-   BLKmode structures in registers.  Some machines (the PA for example)
-   want to return all small structures in registers regardless of the
-   structure's alignment.  */
+   structures in registers.  */

 rtx
-copy_blkmode_from_reg (rtx tgtblk, rtx srcreg, tree type)
+copy_from_reg (rtx tgtblk, rtx srcreg, tree type)
 {
   unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
   rtx src = NULL, dst = NULL;
   unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
   unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
-  enum machine_mode copy_mode;
-
-  if (tgtblk == 0)
-    {
-      tgtblk = assign_temp (build_qualified_type (type,
-                          (TYPE_QUALS (type)
-                           | TYPE_QUAL_CONST)),
-                1, 1);
-      preserve_temp_slots (tgtblk);
-    }
+  enum machine_mode copy_mode, mode = TYPE_MODE (type);

   /* This code assumes srcreg is at least a full word.  If it isn't, copy it
      into a new pseudo which is a full word.  */
@@ -2166,7 +2154,7 @@ copy_blkmode_from_reg (rtx tgtblk, rtx srcreg, tree type)
       /* We need a new destination operand each time bitpos is on
      a word boundary.  */
       if (bitpos % BITS_PER_WORD == 0)
-    dst = operand_subword (tgtblk, bitpos / BITS_PER_WORD, 1, BLKmode);
+    dst = operand_subword (tgtblk, bitpos / BITS_PER_WORD, 1, mode);

       /* Use xbitpos for the source extraction (right justified) and
      bitpos for the destination store (left justified).  */
@@ -2179,6 +2167,29 @@ copy_blkmode_from_reg (rtx tgtblk, rtx srcreg, tree
type)
   return tgtblk;
 }

+/* Generate code to copy a BLKmode object of TYPE out of a
+   set of registers starting with SRCREG into TGTBLK.  If TGTBLK
+   is null, a stack temporary is created.  TGTBLK is returned.
+
+   The purpose of this routine is to handle functions that return
+   BLKmode structures in registers.  Some machines (the PA for example)
+   want to return all small structures in registers regardless of the
+   structure's alignment.  */
+
+rtx
+copy_blkmode_from_reg (rtx tgtblk, rtx srcreg, tree type)
+{
+  if (tgtblk == 0)
+    {
+      tgtblk = assign_temp (build_qualified_type (type,
+                          (TYPE_QUALS (type)
+                           | TYPE_QUAL_CONST)),
+                1, 1);
+      preserve_temp_slots (tgtblk);
+    }
+  return copy_from_reg (tgtblk, srcreg, type);
+}
+
 /* Copy BLKmode value SRC into a register of mode MODE.  Return the
    register if it contains any data, otherwise return null.

diff --git a/gcc/expr.h b/gcc/expr.h
index 68cdb8d..f029671 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -334,6 +334,9 @@ extern rtx emit_group_move_into_temps (rtx);
    PARALLEL.  */
 extern void emit_group_store (rtx, rtx, tree, int);

+/* Copy object from a set of registers.  */
+extern rtx copy_from_reg (rtx, rtx, tree);
+
 /* Copy BLKmode object from a set of registers.  */
 extern rtx copy_blkmode_from_reg (rtx, rtx, tree);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]