From patchwork Thu Jan 3 22:55:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1020546 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-493364-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="hSeHsN+Q"; dkim-atps=neutral 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 43W3D55BhCz9s3l for ; Fri, 4 Jan 2019 09:55:31 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=EA2EPzgT/RXBpDciOqZqBbJQMd/CV gkPwF65tfX+SuxcV8vbTRDg+APgFIGN05mlB09yar5xfBq0kSCx6yMMVTVw1Kgrf Wh6h3x33iLcESIRET5TaomkOqFtqIe/hAmu3YVuBZcNuQtqRVaXoU1xp4nh7Q/Ip QeKUZcB1D2JJtQ= 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:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=QzEUegqYHjAXWAlJRrqXJdQYLlw=; b=hSe HsN+Q5dPAKdrC4y9rYSwCvjUb/MTsC3Dw005iYAiFuI0w6/XgTZvysAxAcEBdBdD E6wIRuPK7oKL5hqpUyI8pHzx9/+9ab4GUBuwdozbyjea5umIZkwFPG5hnuGtr7aB vfCmEC2m4HMLIAtwhNgCL68SkgAL3ciF84+JlbuI= Received: (qmail 3007 invoked by alias); 3 Jan 2019 22:55:24 -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 2997 invoked by uid 89); 3 Jan 2019 22:55:24 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=xa 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; Thu, 03 Jan 2019 22:55:21 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4712E20265; Thu, 3 Jan 2019 22:55:20 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-116-18.ams2.redhat.com [10.36.116.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D7F3F5D757; Thu, 3 Jan 2019 22:55:19 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id x03MtHwF031528; Thu, 3 Jan 2019 23:55:17 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id x03MtG6X031526; Thu, 3 Jan 2019 23:55:16 +0100 Date: Thu, 3 Jan 2019 23:55:16 +0100 From: Jakub Jelinek To: Richard Biener , Jeff Law Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix expansion ICE with call returning VL structure (PR middle-end/82564, PR target/88620) Message-ID: <20190103225516.GV30353@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-IsSubscribed: yes Hi! The following testcases ICE on x86_64 and other targets. The problem is that a function with nested functions returning VLA structures is inlined (or versioned) so that the variable sizes become constant, but we still have a MEM_REF[(struct S *) &D.1234] = fn (); where the D.1234 variable has fixed non-BLKmode size, but struct S is still a VLA type. Furthermore, D.1234 isn't marked as addressable, because it is only accessed through such MEM_REFs. Because of that mem_ref_refers_to_non_mem_p is true and we take a different expand_assignment path from normal VLA return expansion and try to create the VLA structure temporary, which ICEs obviously. The following patch fixes that by using a MEM temporary for this rare case. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-01-03 Jakub Jelinek PR middle-end/82564 PR target/88620 * expr.c (expand_assignment): For calls returning VLA structures if to_rtx is not a MEM, force it into a stack temporary. * gcc.dg/nested-func-12.c: New test. * gcc.c-torture/compile/pr82564.c: New test. Jakub --- gcc/expr.c.jj 2019-01-01 12:37:16.751981612 +0100 +++ gcc/expr.c 2019-01-03 19:17:25.882346422 +0100 @@ -5254,6 +5254,21 @@ expand_assignment (tree to, tree from, b emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true)); } } + /* For calls to functions returning variable length structures, if TO_RTX + is not a MEM, go through a MEM because we must not create temporaries + of the VLA type. */ + else if (!MEM_P (to_rtx) + && TREE_CODE (from) == CALL_EXPR + && COMPLETE_TYPE_P (TREE_TYPE (from)) + && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST) + { + rtx temp = assign_stack_temp (GET_MODE (to_rtx), + GET_MODE_SIZE (GET_MODE (to_rtx))); + result = store_field (temp, bitsize, bitpos, bitregion_start, + bitregion_end, mode1, from, get_alias_set (to), + nontemporal, reversep); + emit_move_insn (to_rtx, temp); + } else { if (MEM_P (to_rtx)) --- gcc/testsuite/gcc.dg/nested-func-12.c.jj 2019-01-03 19:25:46.466084209 +0100 +++ gcc/testsuite/gcc.dg/nested-func-12.c 2019-01-03 19:25:38.181220942 +0100 @@ -0,0 +1,48 @@ +/* PR target/88620 */ +/* { dg-do run } */ +/* { dg-options "-Ofast --param ipa-cp-eval-threshold=0 -fno-guess-branch-probability -fno-inline-small-functions" } */ +/* { dg-require-effective-target alloca } */ + +void +foo (int n) +{ + struct S { int a[n]; }; + + struct S + fn (void) + { + struct S s; + s.a[0] = 42; + return s; + } + + auto struct S + fn2 (void) + { + return fn (); + } + + struct S x; + fn (); + fn2 (); + x = fn (); + + if (x.a[0] != 42) + __builtin_abort (); + + if (fn ().a[0] != 42) + __builtin_abort (); + + __typeof__ (fn ()) *p = &x; + if (p->a[0] != 42) + __builtin_abort (); + + if (fn2 ().a[0] != 42) + __builtin_abort (); +} + +int +main (void) +{ + foo (1); +} --- gcc/testsuite/gcc.c-torture/compile/pr82564.c.jj 2019-01-03 19:22:36.763215290 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr82564.c 2019-01-03 19:24:44.607105204 +0100 @@ -0,0 +1,15 @@ +/* PR middle-end/82564 */ +/* { dg-require-effective-target alloca } */ + +int +main () +{ + int t = 8, i; + typedef struct { char v[t]; } B; + B a, b; + B __attribute__ ((noinline)) f () { return b; } + for (i = 0; i < 8; i++) + b.v[i] = i; + a = f (); + return 0; +}