From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 24B183857346 for ; Tue, 5 Dec 2023 16:44:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 24B183857346 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 24B183857346 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701794652; cv=none; b=nPIyYO+rLd1yeLUoO5NJYjfwinIsKMm3ML8ShsvT0o8CwQ9C1MiS6/YyEsctvevkz83WtjqIhNH0G5Y5U50A6WEEBWK1tIyZbZ0kKqGriAidx46kgWVxx03qTmKCplUQ+HWowbn8wOAhkWF6l14ItvajN9Gs5/d/OAPImYKYpfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701794652; c=relaxed/simple; bh=0p4TPpeVqtyvB7JMXSp8GA8ExN3ZknYkK+YvgJUCSwM=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=m3XnnPEiU1m1N470szlteoqs/d2y2PcCUxUWpDyKkGTcfQ+9KPbn+lWjd2TVJqMIKPs7/uRIGj0Wwkl/NNBe/hNOCSWr0F/KE4lDfoiAxeeQpMO0vMkEk8LgFFDajBr/W9NaIcALVq/GLq0w4T9y9pMS1FsDH72H9D6pqzPEu20= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1701794649; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hsA0NAedNwwDr9fsXOa1qOb4Y3+TkzVWZkdgxAEn3F8=; b=AVtulmZFzsChksqFBoSILoK8WTn5CLk2GAHw2kEjy7W6chvoA9TvUZp2M40GkK/tlWzZBZ uPAD0SqIvq+gSDJjItV4NMNvM3UXoNBHPhQsbnk6WdKvheOi/AIZmAZk0weAzSfLimmi1r oQj2OiqIgunFVwigmMOcXp7o4Tln5Xs= Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-17-t2ZMMJwOO02PpVlrhasujg-1; Tue, 05 Dec 2023 11:16:51 -0500 X-MC-Unique: t2ZMMJwOO02PpVlrhasujg-1 Received: by mail-qv1-f69.google.com with SMTP id 6a1803df08f44-67ad8f3b956so22120826d6.0 for ; Tue, 05 Dec 2023 08:16:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701793010; x=1702397810; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=hsA0NAedNwwDr9fsXOa1qOb4Y3+TkzVWZkdgxAEn3F8=; b=rr887qucvB6cIAc87DzuiN2Tu2UtEnHy80BuKdPX50quZ6HuZGrQM1RLhp8ArYcSsW Z3IV9tcQRMjE86c4iG00ftSpMab/69NITUimOXOaWQqq1wodynbNxgVihpgaaDdOVVs8 BP/3c02c0G4yr6UV876LEhemEBmO/vnv2xn/au5/UKSPHrt7T+drqeyxI+DGp6atup7z EP48DUUGxpDwGkiMShOwtk2fWU1iEkE7W3vJKg4Rq/FuPIGS/K2CaJldS2Mf0M8BiSLU 0lXrdRF1uUZh+B3ARoMssBoLr+dlBrLAU3Hhjk+Wt3Unr7RQ7Zt4Zw7adCNdgrf5JGkU iOBw== X-Gm-Message-State: AOJu0Yzey7ciTaRNBAUGZYR/HGSyGl1/VBYG0WDDjqUehiMkubFinStC i2pjzF85GPGGdLhedMWIC5vyjwXfQCfhbvqIdhJ4hgBhllDgUHPwGfLamPiwffZ7Y81pON57d0o 3O604wxlGzxMkYRuEAJvXbB7WMg== X-Received: by 2002:a0c:f546:0:b0:67a:a2a2:3935 with SMTP id p6-20020a0cf546000000b0067aa2a23935mr1946795qvm.7.1701793009920; Tue, 05 Dec 2023 08:16:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IEPcjYNA6r/lUG9JfUR5AInR7qO/1Gj/EGE0N98fMndsVGyISkD+NGrWn5ZSqdgzaEMXfieEg== X-Received: by 2002:a0c:f546:0:b0:67a:a2a2:3935 with SMTP id p6-20020a0cf546000000b0067aa2a23935mr1946780qvm.7.1701793009576; Tue, 05 Dec 2023 08:16:49 -0800 (PST) Received: from [192.168.1.145] (130-44-146-16.s12558.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.146.16]) by smtp.gmail.com with ESMTPSA id y10-20020a0cc54a000000b0067a34a4dd3asm5237311qvi.130.2023.12.05.08.16.48 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 05 Dec 2023 08:16:49 -0800 (PST) Message-ID: <48633634-cf1e-413c-9a11-9388a2e07a96@redhat.com> Date: Tue, 5 Dec 2023 11:16:48 -0500 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] c++, v2: Further #pragma GCC unroll C++ fix [PR112795] To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org References: <984d11ad-ba57-4a7a-aa50-61296162c325@redhat.com> From: Jason Merrill In-Reply-To: X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-5.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,RCVD_IN_SORBS_WEB,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 12/5/23 11:03, Jakub Jelinek wrote: > On Tue, Dec 05, 2023 at 10:07:19AM -0500, Jason Merrill wrote: >> Please. Maybe check_pragma_unroll? check_unroll_factor? > > So like this (assuming it passes bootstrap/regtest, so far passed just > GXX_TESTSUITE_STDS=98,11,14,17,20,23,26 make check-g++ RUNTESTFLAGS="dg.exp='unroll*'" > )? OK. > 2023-12-05 Jakub Jelinek > > PR c++/112795 > * cp-tree.h (cp_check_pragma_unroll): Declare. > * semantics.cc (cp_check_pragma_unroll): New function. > * parser.cc (cp_parser_pragma_unroll): Use cp_check_pragma_unroll. > * pt.cc (tsubst_expr) : Likewise. > (tsubst_stmt) : Likwsie. > > * g++.dg/ext/unroll-2.C: Use { target c++11 } instead of dg-skip-if for > -std=gnu++98. > * g++.dg/ext/unroll-3.C: Likewise. > * g++.dg/ext/unroll-7.C: New test. > * g++.dg/ext/unroll-8.C: New test. > > --- gcc/cp/cp-tree.h.jj 2023-12-05 09:06:06.140878013 +0100 > +++ gcc/cp/cp-tree.h 2023-12-05 16:21:05.564736203 +0100 > @@ -7918,6 +7918,7 @@ extern tree most_general_lambda (tree) > extern tree finish_omp_target (location_t, tree, tree, bool); > extern void finish_omp_target_clauses (location_t, tree, tree *); > extern void maybe_warn_unparenthesized_assignment (tree, tsubst_flags_t); > +extern tree cp_check_pragma_unroll (location_t, tree); > > /* in tree.cc */ > extern int cp_tree_operand_length (const_tree); > --- gcc/cp/semantics.cc.jj 2023-12-04 08:59:06.888357091 +0100 > +++ gcc/cp/semantics.cc 2023-12-05 16:56:03.718410332 +0100 > @@ -13016,4 +13016,33 @@ cp_build_bit_cast (location_t loc, tree > return ret; > } > > +/* Diagnose invalid #pragma GCC unroll argument and adjust > + it if needed. */ > + > +tree > +cp_check_pragma_unroll (location_t loc, tree unroll) > +{ > + HOST_WIDE_INT lunroll = 0; > + if (type_dependent_expression_p (unroll)) > + ; > + else if (!INTEGRAL_TYPE_P (TREE_TYPE (unroll)) > + || (!value_dependent_expression_p (unroll) > + && (!tree_fits_shwi_p (unroll) > + || (lunroll = tree_to_shwi (unroll)) < 0 > + || lunroll >= USHRT_MAX))) > + { > + error_at (loc, "%<#pragma GCC unroll%> requires an" > + " assignment-expression that evaluates to a non-negative" > + " integral constant less than %u", USHRT_MAX); > + unroll = integer_one_node; > + } > + else if (TREE_CODE (unroll) == INTEGER_CST) > + { > + unroll = fold_convert (integer_type_node, unroll); > + if (integer_zerop (unroll)) > + unroll = integer_one_node; > + } > + return unroll; > +} > + > #include "gt-cp-semantics.h" > --- gcc/cp/parser.cc.jj 2023-12-05 09:05:37.533281014 +0100 > +++ gcc/cp/parser.cc 2023-12-05 16:18:32.224909370 +0100 > @@ -50243,27 +50243,7 @@ cp_parser_pragma_unroll (cp_parser *pars > { > location_t location = cp_lexer_peek_token (parser->lexer)->location; > tree unroll = cp_parser_constant_expression (parser); > - unroll = fold_non_dependent_expr (unroll); > - HOST_WIDE_INT lunroll = 0; > - if (type_dependent_expression_p (unroll)) > - ; > - else if (!INTEGRAL_TYPE_P (TREE_TYPE (unroll)) > - || (!value_dependent_expression_p (unroll) > - && (!tree_fits_shwi_p (unroll) > - || (lunroll = tree_to_shwi (unroll)) < 0 > - || lunroll >= USHRT_MAX))) > - { > - error_at (location, "%<#pragma GCC unroll%> requires an" > - " assignment-expression that evaluates to a non-negative" > - " integral constant less than %u", USHRT_MAX); > - unroll = NULL_TREE; > - } > - else if (TREE_CODE (unroll) == INTEGER_CST) > - { > - unroll = fold_convert (integer_type_node, unroll); > - if (integer_zerop (unroll)) > - unroll = integer_one_node; > - } > + unroll = cp_check_pragma_unroll (location, fold_non_dependent_expr (unroll)); > cp_parser_skip_to_pragma_eol (parser, pragma_tok); > return unroll; > } > --- gcc/cp/pt.cc.jj 2023-12-05 09:06:06.175877520 +0100 > +++ gcc/cp/pt.cc 2023-12-05 16:48:05.641109116 +0100 > @@ -18407,22 +18407,24 @@ tsubst_stmt (tree t, tree args, tsubst_f > complain, in_decl, decomp); > } > > + tree unroll = RECUR (RANGE_FOR_UNROLL (t)); > + if (unroll) > + unroll > + = cp_check_pragma_unroll (EXPR_LOCATION (RANGE_FOR_UNROLL (t)), > + unroll); > if (processing_template_decl) > { > RANGE_FOR_IVDEP (stmt) = RANGE_FOR_IVDEP (t); > - RANGE_FOR_UNROLL (stmt) = RANGE_FOR_UNROLL (t); > + RANGE_FOR_UNROLL (stmt) = unroll; > RANGE_FOR_NOVECTOR (stmt) = RANGE_FOR_NOVECTOR (t); > finish_range_for_decl (stmt, decl, expr); > if (decomp && decl != error_mark_node) > cp_finish_decomp (decl, decomp); > } > else > - { > - tree unroll = RECUR (RANGE_FOR_UNROLL (t)); > - stmt = cp_convert_range_for (stmt, decl, expr, decomp, > - RANGE_FOR_IVDEP (t), unroll, > - RANGE_FOR_NOVECTOR (t)); > - } > + stmt = cp_convert_range_for (stmt, decl, expr, decomp, > + RANGE_FOR_IVDEP (t), unroll, > + RANGE_FOR_NOVECTOR (t)); > > bool prev = note_iteration_stmt_body_start (); > RECUR (RANGE_FOR_BODY (t)); > @@ -21506,30 +21508,8 @@ tsubst_expr (tree t, tree args, tsubst_f > tree op3 = RECUR (TREE_OPERAND (t, 2)); > if (TREE_CODE (op2) == INTEGER_CST > && wi::to_widest (op2) == (int) annot_expr_unroll_kind) > - { > - HOST_WIDE_INT lunroll; > - if (type_dependent_expression_p (op3)) > - ; > - else if (!INTEGRAL_TYPE_P (TREE_TYPE (op3)) > - || (!value_dependent_expression_p (op3) > - && (!tree_fits_shwi_p (op3) > - || (lunroll = tree_to_shwi (op3)) < 0 > - || lunroll >= USHRT_MAX))) > - { > - error_at (EXPR_LOCATION (TREE_OPERAND (t, 2)), > - "%<#pragma GCC unroll%> requires an " > - "assignment-expression that evaluates to a " > - "non-negative integral constant less than %u", > - USHRT_MAX); > - op3 = integer_one_node; > - } > - else if (TREE_CODE (op3) == INTEGER_CST) > - { > - op3 = fold_convert (integer_type_node, op3); > - if (integer_zerop (op3)) > - op3 = integer_one_node; > - } > - } > + op3 = cp_check_pragma_unroll (EXPR_LOCATION (TREE_OPERAND (t, 2)), > + op3); > RETURN (build3_loc (EXPR_LOCATION (t), ANNOTATE_EXPR, > TREE_TYPE (op1), op1, op2, op3)); > } > --- gcc/testsuite/g++.dg/ext/unroll-2.C.jj 2023-12-04 11:55:52.154142189 +0100 > +++ gcc/testsuite/g++.dg/ext/unroll-2.C 2023-12-05 16:17:29.976792279 +0100 > @@ -1,6 +1,5 @@ > -// { dg-do compile } > +// { dg-do compile { target c++11 } } > // { dg-options "-O2 -fdump-tree-cunrolli-details" } > -// { dg-skip-if "range for" { *-*-* } { "-std=gnu++98" } { "" } } > > void > foo (int (&a)[8], int *b, int *c) > --- gcc/testsuite/g++.dg/ext/unroll-3.C.jj 2023-12-04 11:55:52.154142189 +0100 > +++ gcc/testsuite/g++.dg/ext/unroll-3.C 2023-12-05 16:17:29.988792108 +0100 > @@ -1,6 +1,5 @@ > -// { dg-do compile } > +// { dg-do compile { target c++11 } } > // { dg-options "-O2 -fdump-tree-cunrolli-details" } > -// { dg-skip-if "range for" { *-*-* } { "-std=gnu++98" } { "" } } > > template > void > --- gcc/testsuite/g++.dg/ext/unroll-7.C.jj 2023-12-05 16:17:29.988792108 +0100 > +++ gcc/testsuite/g++.dg/ext/unroll-7.C 2023-12-05 16:17:29.988792108 +0100 > @@ -0,0 +1,45 @@ > +// PR c++/112795 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2 -fdump-tree-cunrolli-details" } > + > +void baz (int); > +constexpr int n = 3; > +constexpr int m = 7; > + > +template > +void > +foo (int (&a)[3], T b) > +{ > +#pragma GCC unroll(n) > + for (auto i : a) > + baz (i); > +#pragma GCC unroll(m) > + for (auto i : b) > + baz (i); > +} > + > +template > +void > +bar (int (&a)[N]) > +{ > +#pragma GCC unroll(N) > + for (auto i : a) > + baz (i); > +} > + > +void > +qux () > +{ > + int a[3] = { 1, 2, 3 }; > + int b[7] = { 4, 5, 6, 7, 8, 9, 10 }; > + int c[6] = { 11, 12, 13, 14, 15, 16 }; > + int d[10] = { 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; > + foo (a, b); > + bar <6> (c); > + bar <10> (d); > +} > + > +// { dg-final { scan-tree-dump "loop with 3 iterations completely unrolled" "cunrolli" } } > +// { dg-final { scan-tree-dump "loop with 6 iterations completely unrolled" "cunrolli" } } > +// { dg-final { scan-tree-dump "loop with 7 iterations completely unrolled" "cunrolli" } } > +// { dg-final { scan-tree-dump "loop with 10 iterations completely unrolled" "cunrolli" } } > --- gcc/testsuite/g++.dg/ext/unroll-8.C.jj 2023-12-05 16:17:29.988792108 +0100 > +++ gcc/testsuite/g++.dg/ext/unroll-8.C 2023-12-05 16:17:29.988792108 +0100 > @@ -0,0 +1,86 @@ > +// PR c++/112795 > +// { dg-do compile { target c++11 } } > + > +void > +foo (int (&a)[3]) > +{ > + #pragma GCC unroll 1.0f // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll 0xffffffffffffffffULL // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll -42 // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > +} > + > +template > +void > +bar (U a) > +{ > + #pragma GCC unroll 1.0f // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll 0xffffffffffffffffULL // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll -42 // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > +} > + > +template > +void > +baz (U a) > +{ > + #pragma GCC unroll (N + 1.0f) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll (N + 0xffffffffffffffffULL) > + for (auto i : a) > + ; > + #pragma GCC unroll (N - 42) > + for (auto i : a) > + ; > + #pragma GCC unroll ((T) 1.0f) > + for (auto i : a) > + ; > + #pragma GCC unroll ((T) 0xffffffffffffffffULL) > + for (auto i : a) > + ; > + #pragma GCC unroll ((T) -42) > + for (auto i : a) > + ; > +} > + > +template > +void > +qux (U a) > +{ > + #pragma GCC unroll (N + 1.0f) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll (N + 0xffffffffffffffffULL)// { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll (N - 42) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll ((T) 1.0f) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll ((T) 0xffffffffffffffffULL)// { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > + #pragma GCC unroll ((T) -42) // { dg-error "'#pragma GCC unroll' requires an assignment-expression that evaluates to a non-negative integral constant less than" } > + for (auto i : a) > + ; > +} > + > +void > +corge () > +{ > + int a[3] = { 1, 2, 3 }; > + qux (a); > +} > > > Jakub >