From patchwork Sun Aug 7 12:38:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 108817 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 7E930B6F75 for ; Sun, 7 Aug 2011 22:39:06 +1000 (EST) Received: (qmail 19678 invoked by alias); 7 Aug 2011 12:39:05 -0000 Received: (qmail 19665 invoked by uid 22791); 7 Aug 2011 12:39:04 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_ZJ, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-pz0-f49.google.com (HELO mail-pz0-f49.google.com) (209.85.210.49) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 07 Aug 2011 12:38:50 +0000 Received: by pzk6 with SMTP id 6so8027034pzk.8 for ; Sun, 07 Aug 2011 05:38:50 -0700 (PDT) MIME-Version: 1.0 Received: by 10.142.195.14 with SMTP id s14mr4470541wff.1.1312720729941; Sun, 07 Aug 2011 05:38:49 -0700 (PDT) Received: by 10.142.118.41 with HTTP; Sun, 7 Aug 2011 05:38:49 -0700 (PDT) In-Reply-To: References: Date: Sun, 7 Aug 2011 14:38:49 +0200 Message-ID: Subject: Re: [RFC PATCH, i386]: Allow zero_extended addresses (+ problems with reload and offsetable address, "o" constraint) From: Uros Bizjak To: gcc-patches@gcc.gnu.org Cc: GCC Development , "H.J. Lu" Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org On Fri, Aug 5, 2011 at 8:51 PM, Uros Bizjak wrote: > As I read this sentence, the RTX is forced into a temporary register, > and reload tries to satisfy "o" constraint with plus ((reg ...) > (const_int ...)), as said at the introduction of "o" constraint a > couple of pages earlier. Unfortunately, this does not seem to be the > case. > > Is there anything wrong with my approach, or is there something wrong in reload? To answer my own question, the problem was in *add3_doubleword pattern, defined as: (define_insn_and_split "*add3_doubleword" [(set (match_operand: 0 "nonimmediate_operand" "=r,o") (plus: (match_operand: 1 "nonimmediate_operand" "%0,0") (match_operand: 2 "" "ro,r"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, mode, operands)" When reload tried to satisfy alternative 1 (the "o" and matching "0") with a non-offsettable (in this particular case, zero-extended) address, it CSE'd operand 0 and operand 1 to a temporary TImode register. Unfortunately a Timode move has its own constraints: (define_insn "*movti_internal_rex64" [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm") (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" where move from/to a general register to/from non-offsettable memory is not valid. Although, it would be nice for reload to subsequently fix CSE'd non-offsetable memory by copying address to temporary reg (*as said in the documentation*), we could simply require an XMM temporary for TImode reloads to/from integer registers, and this fixes ICE for x32. The testcase to play with (gcc -O2 -mx32): --cut here-- void test (__int128 *array, int idx, int off) { __int128 *dest = &array [idx]; dest[0] += 1; dest[off] = 0; } --cut here-- So, following additional patch saves the day: Uros. Index: i386/i386.c =================================================================== --- i386/i386.c (revision 177536) +++ i386/i386.c (working copy) @@ -28233,6 +28248,15 @@ ix86_secondary_reload (bool in_p, rtx x, reg_class enum machine_mode mode, secondary_reload_info *sri ATTRIBUTE_UNUSED) { + /* Double-word spills from general registers to non-offsettable + memory references go through XMM register. Following code + handles zero-extended addresses on x32 target. */ + if (TARGET_64BIT + && GET_MODE_SIZE (mode) > UNITS_PER_WORD + && rclass == GENERAL_REGS + && !offsettable_memref_p (x)) + return SSE_REGS; + /* QImode spills from non-QI registers require intermediate register on 32bit targets. */ if (!TARGET_64BIT