From patchwork Thu Oct 11 17:43:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 982632 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-487373-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="aaIbnap0"; 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 42WJHB45ftz9s89 for ; Fri, 12 Oct 2018 04:43:48 +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:subject:message-id:reply-to:mime-version:content-type; q=dns; s=default; b=H2vDKyddMZiq7ReMPgQ0Nup1pQQHCIpwTUf0icMWx9f 9JGd32ZrxOr2UO7DkeUpN1Rn045kQ5BnhvBRWjvZ0R9Knr9mBEANES+0ju8CBSfc A1mzMO1DKEwPeGNpMb6ErwdjGSrmlzF7v3nJLFPEtyb+YvfZHDLaXvcQ6D02inRw = 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:subject:message-id:reply-to:mime-version:content-type; s=default; bh=p9FrDDoz+myXuSHDTcpJaQjc/iM=; b=aaIbnap0+N/UDL4Se 5fSLBLARHvX4krM2ut83qVgIcPW3lrtd1nzY8ZIz8ZCBQRATgBLzdl6cNbPTBGXq 7rY3ONMyUUiVM/pdnytKO2CO3L1gyBunmBsT9t93g043iGSyCVRjaEC/N6uhMKm4 9p4x2iPsGO++uNBAZGPTAJQU3M= Received: (qmail 67887 invoked by alias); 11 Oct 2018 17:43:39 -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 67874 invoked by uid 89); 11 Oct 2018 17:43:39 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=sk:dwarf2o, sk:ggc_cle 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, 11 Oct 2018 17:43:36 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 90D59307D973 for ; Thu, 11 Oct 2018 17:43:35 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-117-222.ams2.redhat.com [10.36.117.222]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0D04076553 for ; Thu, 11 Oct 2018 17:43:34 +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 w9BHhWqQ006025 for ; Thu, 11 Oct 2018 19:43:33 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id w9BHhWVN006024 for gcc-patches@gcc.gnu.org; Thu, 11 Oct 2018 19:43:32 +0200 Date: Thu, 11 Oct 2018 19:43:32 +0200 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: Backports to gcc-8-branch Message-ID: <20181011174332.GD11625@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.9.2 (2017-12-15) X-IsSubscribed: yes Hi! I've bootstrapped/regtested and committed following 4 backports from trunk to gcc-8-branch. Jakub 2018-10-11 Jakub Jelinek Backported from mainline 2018-09-12 Jakub Jelinek Andreas Krebbel PR tree-optimization/86844 * gimple-ssa-store-merging.c (imm_store_chain_info::coalesce_immediate): For overlapping stores, if there are any overlapping stores in between them, make sure they are also coalesced or we give up completely. * gcc.c-torture/execute/pr86844.c: New test. * gcc.dg/store_merging_22.c: New test. * gcc.dg/store_merging_23.c: New test. 2018-10-11 Jakub Jelinek Backported from mainline 2018-09-26 Jakub Jelinek PR target/87414 * config/i386/i386.c: Include debug.h and dwarf2out.h. (output_indirect_thunk): Emit DW_CFA_def_cfa_offset after the call. --- gcc/config/i386/i386.c (revision 264650) +++ gcc/config/i386/i386.c (revision 264651) @@ -91,6 +91,8 @@ along with GCC; see the file COPYING3. #include "ipa-prop.h" #include "ipa-fnsummary.h" #include "wide-int-bitmask.h" +#include "debug.h" +#include "dwarf2out.h" /* This file should be included last. */ #include "target-def.h" @@ -11014,6 +11016,23 @@ output_indirect_thunk (enum indirect_thu ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); + /* The above call insn pushed a word to stack. Adjust CFI info. */ + if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ()) + { + if (! dwarf2out_do_cfi_asm ()) + { + dw_cfi_ref xcfi = ggc_cleared_alloc (); + xcfi->dw_cfi_opc = DW_CFA_advance_loc4; + xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2); + vec_safe_push (cfun->fde->dw_fde_cfi, xcfi); + } + dw_cfi_ref xcfi = ggc_cleared_alloc (); + xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset; + xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD; + vec_safe_push (cfun->fde->dw_fde_cfi, xcfi); + dwarf2out_emit_cfi (xcfi); + } + if (regno != INVALID_REGNUM) { /* MOV. */ 2018-10-11 Jakub Jelinek Backported from mainline 2018-10-10 Jakub Jelinek PR target/87550 * config/i386/i386-builtin.def (IX86_BUILTIN_RDPMC): Move from args set to special_args set. * gcc.target/i386/pr87550.c: New test. --- gcc/config/i386/i386-builtin.def (revision 265006) +++ gcc/config/i386/i386-builtin.def (revision 265007) @@ -90,6 +90,7 @@ BDESC_END (PCMPISTR, SPECIAL_ARGS) BDESC_FIRST (special_args, SPECIAL_ARGS, 0, CODE_FOR_nothing, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID) BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED) +BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT) BDESC (0, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID) /* 80387 (for use internally for atomic compound assignment). */ @@ -427,7 +428,6 @@ BDESC_END (SPECIAL_ARGS, ARGS) BDESC_FIRST (args, ARGS, 0, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, (int) INT_FTYPE_INT) BDESC (OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64) -BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT) BDESC (0, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT) BDESC (0, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT) BDESC (0, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT) --- gcc/testsuite/gcc.target/i386/pr87550.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr87550.c (revision 265007) @@ -0,0 +1,21 @@ +/* PR target/87550 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include + +int +foo (int x) +{ + return __rdtsc () + __rdtsc (); +} + +/* { dg-final { scan-assembler-times "\trdtsc\[\n\r]" 2 } } */ + +int +bar (int x) +{ + return __rdpmc (0) + __rdpmc (0); +} + +/* { dg-final { scan-assembler-times "\trdpmc\[\n\r]" 2 } } */ 2018-10-11 Jakub Jelinek PR c++/87582 * typeck.c (maybe_warn_about_returning_address_of_local): If whats_returned is a structured binding identifier and the structured binding is a reference, recurse on its initializer. * g++.dg/cpp1z/decomp48.C: New test. --- gcc/cp/typeck.c (revision 265040) +++ gcc/cp/typeck.c (revision 265041) @@ -9067,6 +9067,22 @@ maybe_warn_about_returning_address_of_lo && !(TREE_STATIC (whats_returned) || TREE_PUBLIC (whats_returned))) { + if (VAR_P (whats_returned) + && DECL_DECOMPOSITION_P (whats_returned) + && DECL_DECOMP_BASE (whats_returned) + && DECL_HAS_VALUE_EXPR_P (whats_returned)) + { + /* When returning address of a structured binding, if the structured + binding is not a reference, continue normally, if it is a + reference, recurse on the initializer of the structured + binding. */ + tree base = DECL_DECOMP_BASE (whats_returned); + if (TREE_CODE (TREE_TYPE (base)) == REFERENCE_TYPE) + { + tree init = DECL_INITIAL (base); + return maybe_warn_about_returning_address_of_local (init); + } + } if (TREE_CODE (valtype) == REFERENCE_TYPE) warning_at (DECL_SOURCE_LOCATION (whats_returned), OPT_Wreturn_local_addr, --- gcc/testsuite/g++.dg/cpp1z/decomp48.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/decomp48.C (revision 265041) @@ -0,0 +1,134 @@ +// PR c++/87582 +// { dg-do run { target c++11 } } +// { dg-options "-Wreturn-local-addr" } + +struct S { int s, t; }; +S v {1, 2}; +int a[3] = {1, 2, 3}; + +int & +f1 () +{ + auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-bogus "reference to local variable '.' returned" } +} + +int & +f2 () +{ + S v {1, 2}; // { dg-warning "reference to local variable 'v' returned" } + auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; +} + +int & +f3 () +{ + auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-bogus "reference to local variable '.' returned" } +} + +int & +f4 () +{ + int a[3] = {1, 2, 3}; // { dg-warning "reference to local variable 'a' returned" } + auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; +} + +int & +f5 () +{ + auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 's' returned" "" { target *-*-* } .-1 } +} + +int & +f6 () +{ + S v {1, 2}; + auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 's' returned" "" { target *-*-* } .-1 } +} + +int & +f7 () +{ + auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 's' returned" "" { target *-*-* } .-1 } +} + +int & +f8 () +{ + int a[3] = {1, 2, 3}; + auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 's' returned" "" { target *-*-* } .-1 } +} + +int * +f9 () +{ + auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-bogus "address of local variable '.' returned" } +} + +int * +f10 () +{ + S v {1, 2}; // { dg-warning "address of local variable 'v' returned" } + auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; +} + +int * +f11 () +{ + auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-bogus "address of local variable '.' returned" } +} + +int * +f12 () +{ + int a[3] = {1, 2, 3}; // { dg-warning "address of local variable 'a' returned" } + auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; +} + +int * +f13 () +{ + auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 's' returned" "" { target *-*-* } .-1 } +} + +int * +f14 () +{ + S v {1, 2}; + auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 's' returned" "" { target *-*-* } .-1 } +} + +int * +f15 () +{ + auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 's' returned" "" { target *-*-* } .-1 } +} + +int * +f16 () +{ + int a[3] = {1, 2, 3}; + auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 's' returned" "" { target *-*-* } .-1 } +} + +int +main () +{ + if (&f1 () != &v.s || &f3 () != &a[0] || f9 () != &v.s || f11 () != &a[0]) + __builtin_abort (); +} --- gcc/gimple-ssa-store-merging.c (revision 264231) +++ gcc/gimple-ssa-store-merging.c (revision 264232) @@ -2648,15 +2648,80 @@ imm_store_chain_info::coalesce_immediate { /* Only allow overlapping stores of constants. */ if (info->rhs_code == INTEGER_CST - && merged_store->stores[0]->rhs_code == INTEGER_CST - && check_no_overlap (m_store_info, i, INTEGER_CST, - MAX (merged_store->last_order, info->order), - MAX (merged_store->start - + merged_store->width, - info->bitpos + info->bitsize))) + && merged_store->stores[0]->rhs_code == INTEGER_CST) { - merged_store->merge_overlapping (info); - continue; + unsigned int last_order + = MAX (merged_store->last_order, info->order); + unsigned HOST_WIDE_INT end + = MAX (merged_store->start + merged_store->width, + info->bitpos + info->bitsize); + if (check_no_overlap (m_store_info, i, INTEGER_CST, + last_order, end)) + { + /* check_no_overlap call above made sure there are no + overlapping stores with non-INTEGER_CST rhs_code + in between the first and last of the stores we've + just merged. If there are any INTEGER_CST rhs_code + stores in between, we need to merge_overlapping them + even if in the sort_by_bitpos order there are other + overlapping stores in between. Keep those stores as is. + Example: + MEM[(int *)p_28] = 0; + MEM[(char *)p_28 + 3B] = 1; + MEM[(char *)p_28 + 1B] = 2; + MEM[(char *)p_28 + 2B] = MEM[(char *)p_28 + 6B]; + We can't merge the zero store with the store of two and + not merge anything else, because the store of one is + in the original order in between those two, but in + store_by_bitpos order it comes after the last store that + we can't merge with them. We can merge the first 3 stores + and keep the last store as is though. */ + unsigned int len = m_store_info.length (), k = i; + for (unsigned int j = i + 1; j < len; ++j) + { + store_immediate_info *info2 = m_store_info[j]; + if (info2->bitpos >= end) + break; + if (info2->order < last_order) + { + if (info2->rhs_code != INTEGER_CST) + { + /* Normally check_no_overlap makes sure this + doesn't happen, but if end grows below, then + we need to process more stores than + check_no_overlap verified. Example: + MEM[(int *)p_5] = 0; + MEM[(short *)p_5 + 3B] = 1; + MEM[(char *)p_5 + 4B] = _9; + MEM[(char *)p_5 + 2B] = 2; */ + k = 0; + break; + } + k = j; + end = MAX (end, info2->bitpos + info2->bitsize); + } + } + + if (k != 0) + { + merged_store->merge_overlapping (info); + + for (unsigned int j = i + 1; j <= k; j++) + { + store_immediate_info *info2 = m_store_info[j]; + gcc_assert (info2->bitpos < end); + if (info2->order < last_order) + { + gcc_assert (info2->rhs_code == INTEGER_CST); + merged_store->merge_overlapping (info2); + } + /* Other stores are kept and not merged in any + way. */ + } + ignore = k; + continue; + } + } } } /* |---store 1---||---store 2---| --- gcc/testsuite/gcc.c-torture/execute/pr86844.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/execute/pr86844.c (revision 264232) @@ -0,0 +1,24 @@ +/* PR tree-optimization/86844 */ + +__attribute__((noipa)) void +foo (int *p) +{ + *p = 0; + *((char *)p + 3) = 1; + *((char *)p + 1) = 2; + *((char *)p + 2) = *((char *)p + 6); +} + +int +main () +{ + int a[2] = { -1, 0 }; + if (sizeof (int) != 4) + return 0; + ((char *)a)[6] = 3; + foo (a); + if (((char *)a)[0] != 0 || ((char *)a)[1] != 2 + || ((char *)a)[2] != 3 || ((char *)a)[3] != 1) + __builtin_abort (); + return 0; +} --- gcc/testsuite/gcc.dg/store_merging_22.c (nonexistent) +++ gcc/testsuite/gcc.dg/store_merging_22.c (revision 264232) @@ -0,0 +1,16 @@ +/* PR tree-optimization/86844 */ +/* { dg-do compile } */ +/* { dg-require-effective-target store_merge } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ + +void +foo (int *p) +{ + *p = 0; + *((char *)p + 3) = 1; + *((char *)p + 1) = 2; + *((char *)p + 2) = *((char *)p + 38); +} + +/* { dg-final { scan-tree-dump-times "Merging successful" 1 "store-merging" } } */ +/* { dg-final { scan-tree-dump-times "New sequence of 1 stmts to replace old one of 3 stmts" 1 "store-merging" } } */ --- gcc/testsuite/gcc.dg/store_merging_23.c (nonexistent) +++ gcc/testsuite/gcc.dg/store_merging_23.c (revision 264232) @@ -0,0 +1,16 @@ +/* PR tree-optimization/86844 */ +/* { dg-do compile } */ +/* { dg-require-effective-target store_merge } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ + +void +foo (int *p) +{ + *p = 0; + int one = 1; + __builtin_memcpy ((char *) p + 3, &one, sizeof (int)); + *((char *)p + 4) = *((char *)p + 36); + *((char *)p + 1) = 2; +} + +/* { dg-final { scan-tree-dump-not "Merging successful" "store-merging" } } */