From patchwork Fri May 16 17:49:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 349701 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 6D385140084 for ; Sat, 17 May 2014 03:49:57 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=k89fd1pqZahLcquaPXA7fbZk6ZXSCnYhrCAdIVbHZPd9d1 aDAjyUGkeqtafhUlPJ8xsX09+KtpIc0tL0uE0rpiEdnZ2BMKySUzjnutp5VFfvAK NOmsw2W4mqYiGlpAqQ5Wkv2E5GRNud7dRl33TI3HpTnXxzkFa8p9IR6GY0vp4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=eaMZJVOmRNvu1ybWP2w8C6Cr3/w=; b=Z7wB8KFMOLwrJAVYBiKq pvV0kx5aFNP4tcDaPuThTOHN6GCdzyPiZ/ju4+snaeivbX0XEQZHropLQHuTaJtb vdAqj01f1Hv5StdevG8+aAV/tYW7xxEcHYYquRGADUqubNBxKg/JjcSSAkFfSiJZ XPTMGX9xLIteq/7RxJXu28I= Received: (qmail 15153 invoked by alias); 16 May 2014 17:49:50 -0000 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 Received: (qmail 15144 invoked by uid 89); 16 May 2014 17:49:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.3 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 16 May 2014 17:49:48 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s4GHnkxY014310 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 16 May 2014 13:49:47 -0400 Received: from Mair.local (vpn-56-88.rdu2.redhat.com [10.10.56.88]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s4GHnjJ3003262 for ; Fri, 16 May 2014 13:49:46 -0400 Message-ID: <53764FB9.6000000@redhat.com> Date: Fri, 16 May 2014 13:49:45 -0400 From: Vladimir Makarov User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-Version: 1.0 To: GCC Patches Subject: patch to fix PR60969 X-IsSubscribed: yes The following patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60969 The patch was bootstrapped and tested on x86/x86-64. Committed as rev. 210519 to gcc 4.9 branch and as rev. 210520 to trunk. 2014-05-16 Vladimir Makarov PR rtl-optimization/60969 * ira-costs.c (record_reg_classes): Allow only memory for pseudo. Calculate costs for this case. 2014-05-16 Vladimir Makarov PR rtl-optimization/60969 * g++.dg/pr60969.C: New. Index: ira-costs.c =================================================================== --- ira-costs.c (revision 210069) +++ ira-costs.c (working copy) @@ -762,10 +762,11 @@ record_reg_classes (int n_alts, int n_op into that class. */ if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER) { - if (classes[i] == NO_REGS) + if (classes[i] == NO_REGS && ! allows_mem[i]) { /* We must always fail if the operand is a REG, but - we did not find a suitable class. + we did not find a suitable class and memory is + not allowed. Otherwise we may perform an uninitialized read from this_op_costs after the `continue' statement @@ -783,50 +784,90 @@ record_reg_classes (int n_alts, int n_op bool out_p = recog_data.operand_type[i] != OP_IN; enum reg_class op_class = classes[i]; move_table *move_in_cost, *move_out_cost; + short (*mem_cost)[2]; ira_init_register_move_cost_if_necessary (mode); if (! in_p) { ira_assert (out_p); - move_out_cost = ira_may_move_out_cost[mode]; - for (k = cost_classes_ptr->num - 1; k >= 0; k--) + if (op_class == NO_REGS) { - rclass = cost_classes[k]; - pp_costs[k] - = move_out_cost[op_class][rclass] * frequency; + mem_cost = ira_memory_move_cost[mode]; + for (k = cost_classes_ptr->num - 1; k >= 0; k--) + { + rclass = cost_classes[k]; + pp_costs[k] = mem_cost[rclass][0] * frequency; + } + } + else + { + move_out_cost = ira_may_move_out_cost[mode]; + for (k = cost_classes_ptr->num - 1; k >= 0; k--) + { + rclass = cost_classes[k]; + pp_costs[k] + = move_out_cost[op_class][rclass] * frequency; + } } } else if (! out_p) { ira_assert (in_p); - move_in_cost = ira_may_move_in_cost[mode]; - for (k = cost_classes_ptr->num - 1; k >= 0; k--) + if (op_class == NO_REGS) { - rclass = cost_classes[k]; - pp_costs[k] - = move_in_cost[rclass][op_class] * frequency; + mem_cost = ira_memory_move_cost[mode]; + for (k = cost_classes_ptr->num - 1; k >= 0; k--) + { + rclass = cost_classes[k]; + pp_costs[k] = mem_cost[rclass][1] * frequency; + } + } + else + { + move_in_cost = ira_may_move_in_cost[mode]; + for (k = cost_classes_ptr->num - 1; k >= 0; k--) + { + rclass = cost_classes[k]; + pp_costs[k] + = move_in_cost[rclass][op_class] * frequency; + } } } else { - move_in_cost = ira_may_move_in_cost[mode]; - move_out_cost = ira_may_move_out_cost[mode]; - for (k = cost_classes_ptr->num - 1; k >= 0; k--) - { - rclass = cost_classes[k]; - pp_costs[k] = ((move_in_cost[rclass][op_class] - + move_out_cost[op_class][rclass]) - * frequency); + if (op_class == NO_REGS) + { + mem_cost = ira_memory_move_cost[mode]; + for (k = cost_classes_ptr->num - 1; k >= 0; k--) + { + rclass = cost_classes[k]; + pp_costs[k] = ((mem_cost[rclass][0] + + mem_cost[rclass][1]) + * frequency); + } + } + else + { + move_in_cost = ira_may_move_in_cost[mode]; + move_out_cost = ira_may_move_out_cost[mode]; + for (k = cost_classes_ptr->num - 1; k >= 0; k--) + { + rclass = cost_classes[k]; + pp_costs[k] = ((move_in_cost[rclass][op_class] + + move_out_cost[op_class][rclass]) + * frequency); + } } } /* If the alternative actually allows memory, make things a bit cheaper since we won't need an extra insn to load it. */ - pp->mem_cost - = ((out_p ? ira_memory_move_cost[mode][op_class][0] : 0) - + (in_p ? ira_memory_move_cost[mode][op_class][1] : 0) - - allows_mem[i]) * frequency; + if (op_class != NO_REGS) + pp->mem_cost + = ((out_p ? ira_memory_move_cost[mode][op_class][0] : 0) + + (in_p ? ira_memory_move_cost[mode][op_class][1] : 0) + - allows_mem[i]) * frequency; /* If we have assigned a class to this allocno in our first pass, add a cost to this alternative corresponding to what we would add if this @@ -836,15 +877,28 @@ record_reg_classes (int n_alts, int n_op enum reg_class pref_class = pref[COST_INDEX (REGNO (op))]; if (pref_class == NO_REGS) + { + if (op_class != NO_REGS) + alt_cost + += ((out_p + ? ira_memory_move_cost[mode][op_class][0] + : 0) + + (in_p + ? ira_memory_move_cost[mode][op_class][1] + : 0)); + } + else if (op_class == NO_REGS) alt_cost += ((out_p - ? ira_memory_move_cost[mode][op_class][0] : 0) + ? ira_memory_move_cost[mode][pref_class][1] + : 0) + (in_p - ? ira_memory_move_cost[mode][op_class][1] + ? ira_memory_move_cost[mode][pref_class][0] : 0)); else if (ira_reg_class_intersect[pref_class][op_class] == NO_REGS) - alt_cost += ira_register_move_cost[mode][pref_class][op_class]; + alt_cost += (ira_register_move_cost + [mode][pref_class][op_class]); } } } Index: testsuite/g++.dg/pr60969.C =================================================================== --- testsuite/g++.dg/pr60969.C (revision 0) +++ testsuite/g++.dg/pr60969.C (working copy) @@ -0,0 +1,30 @@ +/* { dg-do compile { target i?86-*-* } } */ +/* { dg-options "-O2 -ftree-vectorize -march=pentium4" } */ + +struct A +{ + float f, g, h, k; + A () {} + A (float v0, float x, float y) : f(v0), g(x), h(y), k(0.0f) {} + A bar (A &a, float t) { return A (f + a.f * t, g + a.g * t, h + a.h * t); } +}; + +A +baz (A &x, A &y, float t) +{ + return x.bar (y, t); +} + +A * +foo (A &s, A &t, A &u, A &v, int y, int z) +{ + A *x = new A[y * z]; + for (int i = 0; i < 7; i++) + { + A s = baz (s, u, i / (float) z); + A t = baz (t, v, i / (float) z); + for (int j = 0; j < 7; j++) + x[i * y + j] = baz (s, t, j / (float) y); + } + return x; +}