From patchwork Fri Dec 9 14:03:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyrill Tkachov X-Patchwork-Id: 87481 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp321108qgi; Fri, 9 Dec 2016 06:04:06 -0800 (PST) X-Received: by 10.99.95.86 with SMTP id t83mr145053831pgb.0.1481292246439; Fri, 09 Dec 2016 06:04:06 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id t135si34009487pgc.127.2016.12.09.06.04.06 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Dec 2016 06:04:06 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-443986-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-443986-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-443986-patch=linaro.org@gcc.gnu.org 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:cc:subject:content-type; q=dns; s=default; b=BhA12pqywRZE0a1uWGuu9Ft2cvUsxB2IbE+3M5porlB XwZq9zkroEH4q8Xx01QbJL2pn1MFfNIjOpxPKj6DFo6Y0JGbaAQgwDfzlQOxcNzg gTinDmnQgaKet5ntRNMYffXnL3TbXnke3UHMl0klJARy4Y0ViRuK6SvHVwLNvM+s = 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:cc:subject:content-type; s=default; bh=6eiMbwsNu4lxJMg1oIZfKJEfO5Q=; b=cB4N1io86Wf5zvR84 51GKsUwiWN4V9vNT+6J2rOf8Q+IwpXLQHwtI4UlK/IqSc6N//FWYUhu04EffZZct TOBoXoBVyZVkGDieH7e0boe6ooHL9OXG8aFaOfcjjIFhuu6AQdqEe//PQQLkE350 BwMKXXG8/lf7ugp4Mv07aEry3M= Received: (qmail 4699 invoked by alias); 9 Dec 2016 14:03:37 -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 4669 invoked by uid 89); 9 Dec 2016 14:03:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.9 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=_Bool, _bool, 955 X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 09 Dec 2016 14:03:33 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DBB9D1570; Fri, 9 Dec 2016 06:03:31 -0800 (PST) Received: from [10.2.207.77] (e100706-lin.cambridge.arm.com [10.2.207.77]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 3C8DF3F220; Fri, 9 Dec 2016 06:03:31 -0800 (PST) Message-ID: <584AB9B1.2070004@foss.arm.com> Date: Fri, 09 Dec 2016 14:03:29 +0000 From: Kyrill Tkachov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches CC: Ramana Radhakrishnan , Richard Earnshaw Subject: [PATCH][ARM] PR target/78694: Avoid invalid RTL sharing in minipool code Hi all, In this ICE GCC reports invalid RTL sharing in the pattern: (insn 955 954 956 (unspec_volatile [ (const:SI (unspec:SI [ (symbol_ref:SI ("a") [flags 0xe8] ) (const_int 4 [0x4]) ] UNSPEC_TLS)) ] VUNSPEC_POOL_4) -1 (nil)) seb.c:116:1: error: shared rtx (const:SI (unspec:SI [ (symbol_ref:SI ("a") [flags 0xe8] ) (const_int 4 [0x4]) ] UNSPEC_TLS)) This is the consttable_4 pattern emitted by dump_minipool and the shared rtx that's causing the problem is the operand to that pattern that comes from the 'value' field of Mnode. I'm not very familiar with the exact restrictions on sharing RTL but I believe the right way to fix these is to do a copy_rtx of the value we want to use. So this patch does that when the pool entries are emitted. The ICE is quite fragile. See the PR for more details, but I've been able to reliably reproduce it on an arm-none-linux-gnueabihf target with -mcpu=arm7tdmi -mfloat-abi=soft -mfpu=vfp -mthumb and this patch fixes that there. Bootstrapped and tested on arm-none-linux-gnueabihf. Ok for trunk? Thanks, Kyrill 2016-12-09 Kyrylo Tkachov PR target/78694 * config/arm/arm.c (dump_minipool): Copy mp->value before emitting it in the minipool to avoid invalid RTL sharing. 2016-12-09 Kyrylo Tkachov PR target/78694 * gcc.c-torture/compile/pr78694.c: New test. commit 947b7660395c31e79605db30c4a1e306a4b050bf Author: Kyrylo Tkachov Date: Thu Dec 8 11:45:46 2016 +0000 [ARM] PR target/78694: Avoid invalid RTL sharing in minipool code diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 437da6f..6fcc23f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15959,35 +15959,37 @@ dump_minipool (rtx_insn *scan) fputc ('\n', dump_file); } + rtx val = copy_rtx (mp->value); + switch (GET_MODE_SIZE (mp->mode)) { #ifdef HAVE_consttable_1 case 1: - scan = emit_insn_after (gen_consttable_1 (mp->value), scan); + scan = emit_insn_after (gen_consttable_1 (val), scan); break; #endif #ifdef HAVE_consttable_2 case 2: - scan = emit_insn_after (gen_consttable_2 (mp->value), scan); + scan = emit_insn_after (gen_consttable_2 (val), scan); break; #endif #ifdef HAVE_consttable_4 case 4: - scan = emit_insn_after (gen_consttable_4 (mp->value), scan); + scan = emit_insn_after (gen_consttable_4 (val), scan); break; #endif #ifdef HAVE_consttable_8 case 8: - scan = emit_insn_after (gen_consttable_8 (mp->value), scan); + scan = emit_insn_after (gen_consttable_8 (val), scan); break; #endif #ifdef HAVE_consttable_16 case 16: - scan = emit_insn_after (gen_consttable_16 (mp->value), scan); + scan = emit_insn_after (gen_consttable_16 (val), scan); break; #endif diff --git a/gcc/testsuite/gcc.c-torture/compile/pr78694.c b/gcc/testsuite/gcc.c-torture/compile/pr78694.c new file mode 100644 index 0000000..bc31944 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr78694.c @@ -0,0 +1,118 @@ +/* PR target/78694. */ + +enum +{ + MEMMODEL_RELAXED, + MEMMODEL_ACQUIRE, + PRIORITY_INSERT_END +}; +enum +{ + PQ_CHILDREN, + PQ_TASKGROUP +}; +struct gomp_team_state +{ + struct gomp_team *team; +}; +enum gomp_task_kind +{ + GOMP_TASK_UNDEFERRED, + GOMP_TASK_WAITING +}; +struct gomp_taskwait +{ + _Bool in_taskwait; +}; +struct gomp_task +{ + struct gomp_task *parent; + int children_queue; + struct gomp_taskgroup *taskgroup; + int dependers; + struct gomp_taskwait taskwait; + enum gomp_task_kind kind; + _Bool in_tied_task; +} j, q, *n; +struct gomp_taskgroup +{ + _Bool in_taskgroup_wait; + int num_children; +} l; +struct gomp_team +{ + int task_queue; + int task_running_count; +}; +struct gomp_thread +{ + struct gomp_team_state ts; + struct gomp_task task; +} extern __thread a; + +int b, c, d, e, f, g, h, i, k, m, o, p, r; + +void priority_queue_next_task (struct gomp_task *, int, int); +int gomp_task_run_pre (struct gomp_task *, struct gomp_task, struct gomp_team); +void priority_queue_insert (int, struct gomp_task); +void priority_queue_insert2 (int, struct gomp_task, int, int, int); +void priority_queue_insert3 (int, struct gomp_task, int, int, int); +void gomp_sem_post (int); +void free (void *); + +_Bool s; +int +GOMP_taskgroup_end () +{ + struct gomp_thread *t = &a; + struct gomp_team u = *t->ts.team; + struct gomp_task *v = &t->task, *w; + if (__atomic_load_n (&l.num_children, MEMMODEL_ACQUIRE)) + while (1) + { + if (l.num_children) + priority_queue_next_task (v, u.task_queue, r); + else if (w) + free (w); + if (n->kind == GOMP_TASK_WAITING) + { + s = gomp_task_run_pre (n, q, u); + if (__builtin_expect (s, 0)) + { + if (w) + free (w); + goto finish_cancelled; + } + n = 0; + l.in_taskgroup_wait = 1; + } + if (w) + { + t->task = *n; + if (__builtin_expect (p, 0)) + if (o) + t->task = *v; + } + if (n) + { + struct gomp_task x = x; + for (; i; b++) + { + struct gomp_task y = j; + if (g) + continue; + priority_queue_insert (PQ_CHILDREN, x); + if (x.taskwait.in_taskwait) + priority_queue_insert2 (PQ_TASKGROUP, y, e, 0, d); + if (h) + gomp_sem_post (f); + priority_queue_insert3 (k, y, PRIORITY_INSERT_END, 0, d); + ++c; + } + } + finish_cancelled: + w = (struct gomp_task *) (n - u.task_running_count - v); + } + v->taskgroup = (struct gomp_taskgroup *) m; + return 1; +}