This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/20020] x86_64 - 128 bit structs not targeted to TImode
- From: "hjl.tools at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 15 Aug 2012 01:23:54 +0000
- Subject: [Bug target/20020] x86_64 - 128 bit structs not targeted to TImode
- Auto-submitted: auto-generated
- References: <bug-20020-4@http.gcc.gnu.org/bugzilla/>
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);