From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28906 invoked by alias); 15 Aug 2012 01:24:59 -0000 Received: (qmail 28894 invoked by uid 22791); 15 Aug 2012 01:24:58 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00,KHOP_THREADED X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 15 Aug 2012 01:24:45 +0000 From: "hjl.tools at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/20020] x86_64 - 128 bit structs not targeted to TImode Date: Wed, 15 Aug 2012 01:24:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Keywords: ABI, missed-optimization X-Bugzilla-Severity: enhancement X-Bugzilla-Who: hjl.tools at gmail dot com X-Bugzilla-Status: NEW X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2012-08/txt/msg00914.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20020 --- Comment #36 from H.J. Lu 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);