From patchwork Sun Jul 31 18:06:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 107609 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 D388AB7010 for ; Mon, 1 Aug 2011 04:06:34 +1000 (EST) Received: (qmail 17392 invoked by alias); 31 Jul 2011 18:06:32 -0000 Received: (qmail 17384 invoked by uid 22791); 31 Jul 2011 18:06:30 -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, 31 Jul 2011 18:06:04 +0000 Received: by pzk33 with SMTP id 33so10510845pzk.36 for ; Sun, 31 Jul 2011 11:06:04 -0700 (PDT) MIME-Version: 1.0 Received: by 10.68.42.131 with SMTP id o3mr6507655pbl.514.1312135563999; Sun, 31 Jul 2011 11:06:03 -0700 (PDT) Received: by 10.143.34.2 with HTTP; Sun, 31 Jul 2011 11:06:03 -0700 (PDT) Date: Sun, 31 Jul 2011 20:06:03 +0200 Message-ID: Subject: =?windows-1252?Q?=5BPATCH=2C_i386=5D=3A_Fix_PR49920=2C_unable_to_find_a_registe?= =?windows-1252?Q?r_to_spill_in_class_=91DIREG=92?= From: Uros Bizjak To: gcc-patches@gcc.gnu.org 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 Hello! The problem is similar to PR11001, where we should not expand to special x86 stringop insn when one of necessary registers is marked fixed. In this particular PR, the problem was, that combine synthesized an instruction that exactly matched stringop insn. However, special registers were also marked fixed, so reload (obviously) didn't manage to get one. Attached patch disables stringop patterns when one of needed registers is marked fixed and this way prevents combine to synthesize stringop insn. Since nothing prevents combine to synthesize other stringop patterns, the patch conditionally disables these as well. 2011-07-31 Uros Bizjak PR target/49920 * config/i386/i386.md (strset): Do not expand strset_singleop when %eax or $edi are fixed. (*strsetdi_rex_1): Disable when %eax or %edi are fixed. (*strsetsi_1): Ditto. (*strsethi_1): Ditto. (*strsetqi_1): Ditto. (*rep_stosdi_rex64): Disable when %eax, %ecx or %edi are fixed. (*rep_stossi): Ditto. (*rep_stosqi): Ditto. (cmpstrnsi): Also fail when %ecx is fixed. (*cmpstrnqi_nz_1): Disable when %ecx, %esi or %edi are fixed. (*cmpstrnqi_1): Ditto. (*strlenqi_1): Ditto. (*strmovdi_rex_1): Disable when %esi or %edi are fixed. (*strmovsi_1): Ditto. (*strmovhi_1): Ditto. (*strmovqi_1): Ditto. (*rep_movdi_rex64): Disable when %ecx, %esi or %edi are fixed. (*rep_movsi): Ditto. (*rep_movqi): Ditto. testsuite/ChangeLog: 2011-07-31 Uros Bizjak PR target/49920 * gcc.target/i386/pr49920.c: New test. Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}. Patch was committed to mainline SVN and will be backported to release branches. Uros. Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 176960) +++ config/i386/i386.md (working copy) @@ -15421,7 +15421,8 @@ (set (match_operand:DI 1 "register_operand" "=S") (plus:DI (match_dup 3) (const_int 8)))] - "TARGET_64BIT" + "TARGET_64BIT + && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])" "movsq" [(set_attr "type" "str") (set_attr "memory" "both") @@ -15436,7 +15437,7 @@ (set (match_operand:P 1 "register_operand" "=S") (plus:P (match_dup 3) (const_int 4)))] - "" + "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" "movs{l|d}" [(set_attr "type" "str") (set_attr "memory" "both") @@ -15451,7 +15452,7 @@ (set (match_operand:P 1 "register_operand" "=S") (plus:P (match_dup 3) (const_int 2)))] - "" + "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" "movsw" [(set_attr "type" "str") (set_attr "memory" "both") @@ -15466,7 +15467,7 @@ (set (match_operand:P 1 "register_operand" "=S") (plus:P (match_dup 3) (const_int 1)))] - "" + "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" "movsb" [(set_attr "type" "str") (set_attr "memory" "both") @@ -15501,7 +15502,8 @@ (set (mem:BLK (match_dup 3)) (mem:BLK (match_dup 4))) (use (match_dup 5))] - "TARGET_64BIT" + "TARGET_64BIT + && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" "rep{%;} movsq" [(set_attr "type" "str") (set_attr "prefix_rep" "1") @@ -15520,7 +15522,7 @@ (set (mem:BLK (match_dup 3)) (mem:BLK (match_dup 4))) (use (match_dup 5))] - "" + "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" "rep{%;} movs{l|d}" [(set_attr "type" "str") (set_attr "prefix_rep" "1") @@ -15537,7 +15539,7 @@ (set (mem:BLK (match_dup 3)) (mem:BLK (match_dup 4))) (use (match_dup 5))] - "" + "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" "rep{%;} movsb" [(set_attr "type" "str") (set_attr "prefix_rep" "1") @@ -15580,7 +15582,9 @@ operands[3] = gen_rtx_PLUS (Pmode, operands[0], GEN_INT (GET_MODE_SIZE (GET_MODE (operands[2])))); - if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) + /* Can't use this if the user has appropriated eax or edi. */ + if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) + && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])) { emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], operands[3])); @@ -15602,7 +15606,8 @@ (set (match_operand:DI 0 "register_operand" "=D") (plus:DI (match_dup 1) (const_int 8)))] - "TARGET_64BIT" + "TARGET_64BIT + && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])" "stosq" [(set_attr "type" "str") (set_attr "memory" "store") @@ -15614,7 +15619,7 @@ (set (match_operand:P 0 "register_operand" "=D") (plus:P (match_dup 1) (const_int 4)))] - "" + "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" "stos{l|d}" [(set_attr "type" "str") (set_attr "memory" "store") @@ -15626,7 +15631,7 @@ (set (match_operand:P 0 "register_operand" "=D") (plus:P (match_dup 1) (const_int 2)))] - "" + "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" "stosw" [(set_attr "type" "str") (set_attr "memory" "store") @@ -15638,7 +15643,7 @@ (set (match_operand:P 0 "register_operand" "=D") (plus:P (match_dup 1) (const_int 1)))] - "" + "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" "stosb" [(set_attr "type" "str") (set_attr "memory" "store") @@ -15669,7 +15674,8 @@ (const_int 0)) (use (match_operand:DI 2 "register_operand" "a")) (use (match_dup 4))] - "TARGET_64BIT" + "TARGET_64BIT + && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" "rep{%;} stosq" [(set_attr "type" "str") (set_attr "prefix_rep" "1") @@ -15686,7 +15692,7 @@ (const_int 0)) (use (match_operand:SI 2 "register_operand" "a")) (use (match_dup 4))] - "" + "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" "rep{%;} stos{l|d}" [(set_attr "type" "str") (set_attr "prefix_rep" "1") @@ -15702,7 +15708,7 @@ (const_int 0)) (use (match_operand:QI 2 "register_operand" "a")) (use (match_dup 4))] - "" + "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" "rep{%;} stosb" [(set_attr "type" "str") (set_attr "prefix_rep" "1") @@ -15727,8 +15733,8 @@ if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS) FAIL; - /* Can't use this if the user has appropriated esi or edi. */ - if (fixed_regs[SI_REG] || fixed_regs[DI_REG]) + /* Can't use this if the user has appropriated ecx, esi or edi. */ + if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) FAIL; out = operands[0]; @@ -15823,7 +15829,7 @@ (clobber (match_operand:P 0 "register_operand" "=S")) (clobber (match_operand:P 1 "register_operand" "=D")) (clobber (match_operand:P 2 "register_operand" "=c"))] - "" + "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" "repz{%;} cmpsb" [(set_attr "type" "str") (set_attr "mode" "QI") @@ -15863,7 +15869,7 @@ (clobber (match_operand:P 0 "register_operand" "=S")) (clobber (match_operand:P 1 "register_operand" "=D")) (clobber (match_operand:P 2 "register_operand" "=c"))] - "" + "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" "repz{%;} cmpsb" [(set_attr "type" "str") (set_attr "mode" "QI") @@ -15904,7 +15910,7 @@ (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS)) (clobber (match_operand:P 1 "register_operand" "=D")) (clobber (reg:CC FLAGS_REG))] - "" + "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" "repnz{%;} scasb" [(set_attr "type" "str") (set_attr "mode" "QI") Index: testsuite/gcc.target/i386/pr49920.c =================================================================== --- testsuite/gcc.target/i386/pr49920.c (revision 0) +++ testsuite/gcc.target/i386/pr49920.c (revision 0) @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target ia32 } */ + +typedef __SIZE_TYPE__ size_t; +extern void *malloc (size_t); + +register unsigned int MR_mr0 asm ("esi"); +register unsigned int MR_mr1 asm ("edi"); + +void ml_backend__ml_closure_gen_module11 (void) +{ + unsigned int MR_tempr1, MR_tempr2, MR_tempr3; + + MR_tempr1 = (unsigned int)((char *) malloc (sizeof (unsigned int)) + 4); + MR_tempr3 = ((unsigned int *) MR_mr0)[0]; + + ((unsigned int *) (MR_tempr1 - 4))[0] = MR_tempr3; + + MR_tempr2 = (unsigned int)((char *) malloc (2 * sizeof (unsigned int))); + + ((unsigned int *) MR_tempr2)[1] = MR_tempr1; +}