From patchwork Mon Oct 4 21:37:54 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [ia64] Patch for PR36898 & PR43760, predicated reg conflict warning Date: Mon, 04 Oct 2010 11:37:54 -0000 From: Steve Ellcey X-Patchwork-Id: 66741 Message-Id: <201010042137.o94LbsH28988@lucas.cup.hp.com> To: gcc-patches@gcc.gnu.org, wilson@codesourcery.com In looking at PR36898 and PR43760, where the GNU assembler on IA64 is putting out messages about possibly conflicting register usages, the problem is that the usages aren't conflicting because the usages are predicated and the predicate registers used are never both true but the assembler doesn't know this because GCC isn't putting out enough .pred.mutex psuedo-ops. After trying to fix this by having GCC put out better '.pred.mutex' psuedo-ops to tell the assembler that the usages aren't conflicting and not having much success, I wondered if it would be easier to just not use (possibly) conflicting registers in the same instruction bundle and make GCC more conservative in it's instruction bundling. I made the change in my local build tree and ran the SPEC2006 tests to see what the performance impact would be. For SPECint the slowdown averaged around 0.5% (between .02% and .79% depending on the options) and in SPECfp it was around 0.15% (between .06% and .24%). The tests were run under HP-UX in 32 and 64 bit modes and with -O2 and -O3. I think the slowdown is small enough that this is a reasonable fix for the problem. So I would like to check in this change to IA64 to simply not do multiple predicated loads or stores in a single bundle (using the same register). Any comments? If I don't hear any objections I will check it in. Steve Ellcey sje@cup.hp.com 2010-10-04 Steve Ellcey PR target/36898 PR middle-end/43760 * config/ia64/ia64.c (rws_access_regno): Remove predicate check. Index: config/ia64/ia64.c =================================================================== --- config/ia64/ia64.c (revision 164824) +++ config/ia64/ia64.c (working copy) @@ -5874,15 +5874,14 @@ rws_access_regno (int regno, struct reg_ break; case 1: - /* The register has been written via a predicate. If this is - not a complementary predicate, then we need a barrier. */ - /* ??? This assumes that P and P+1 are always complementary - predicates for P even. */ + /* The register has been written via a predicate. Treat + it like a unconditional write and do not try to check + for complementary pred reg in earlier write. */ if (flags.is_and && rws_sum[regno].written_by_and) ; else if (flags.is_or && rws_sum[regno].written_by_or) ; - else if ((rws_sum[regno].first_pred ^ 1) != pred) + else need_barrier = 1; if (!in_safe_group_barrier) rws_update (regno, flags, pred); @@ -5943,12 +5942,9 @@ rws_access_regno (int regno, struct reg_ break; case 1: - /* The register has been written via a predicate. If this is - not a complementary predicate, then we need a barrier. */ - /* ??? This assumes that P and P+1 are always complementary - predicates for P even. */ - if ((rws_sum[regno].first_pred ^ 1) != pred) - need_barrier = 1; + /* The register has been written via a predicate, assume we + need a barrier (don't check for complementary regs). */ + need_barrier = 1; break; case 2: ========= Test case change: 2010-10-04 Steve Ellcey * gcc.c-torture/compile/920625-1.c: Remove dg-prune-output lines. Index: gcc.c-torture/compile/920625-1.c =================================================================== --- gcc.c-torture/compile/920625-1.c (revision 164824) +++ gcc.c-torture/compile/920625-1.c (working copy) @@ -1,22 +1,3 @@ -/* The problem on IA-64 is that if-conversion creates a sequence - - (p17) cmp.geu p6, p7 = r48, r15 - (p16) cmp.gtu p6, p7 = r48, r15 - - where p16 and p17 are complemenary, but the assembler DV validation - code doesn't recognize that p6 and p7 are complimentary, and so - we end up warning for a later use - - (p6) addl r14 = 1, r0 - (p7) mov r14 = r0 - - that appears to be a WAW violation. */ - -/* { dg-prune-output "Assembler messages" } */ -/* { dg-prune-output "violate\[^\n\]*dependency" } */ -/* { dg-prune-output "first path encountering" } */ -/* { dg-prune-output "location of the conflicting" } */ - typedef unsigned long int unsigned_word; typedef signed long int signed_word; typedef unsigned_word word;