From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x531.google.com (mail-ed1-x531.google.com [IPv6:2a00:1450:4864:20::531]) by sourceware.org (Postfix) with ESMTPS id 5CA25396E07B for ; Wed, 4 Aug 2021 11:51:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5CA25396E07B Received: by mail-ed1-x531.google.com with SMTP id b7so3146528edu.3 for ; Wed, 04 Aug 2021 04:51:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=ayo/b/LMdTLUpNfenuf3/Bh7k6cbyf0awHiQ/hrY1R4=; b=Uku5prVkaCQeb5IYvaqLKNEMIa++ZRJf+s6wxuZVq1X+JCTBQBgryAZ6e8S54YpHRI yG98sB1u0/hshKtrclXW7ebVbYSvqTQfxTJ0yoRQrtXpf9icwNzEtGaXUbKh82BPpWgY kOtzYwLsDLbHj66suhj0+a3DZzabXCyoWX7mrGZFYw22EjRcgyBCF6/rb3mEz/h4cVXE vOrFhavlHSnWVjtSD9fwQyWVmpFwZGPftgeKkiS//i7HZovSMq5W/XDf+6zmX+qT921Q 9+Fu9ZIfcBTSWcRKpU9In5//oWLqGJX4ud2ZSONdGRDrKZt/ZidKXcp5bWmUTloQ0cHT iNpg== X-Gm-Message-State: AOAM5336atr9kSGx//pzRbe0ozQ97kV/Dc/MNczu1YtCAzHH+nyY0DGR gUFUODR6yNpNYcGlb3w/V03KyRQWSfVI7vDGi1pu+A== X-Google-Smtp-Source: ABdhPJzKMU/fEAIwerSIR+7pLwyICp24OZlFtFHGAJrgU3ShT9IHY3ydNP0SS671ghm25MAL9O2t8XbUHPkiTEIDXIg= X-Received: by 2002:a05:6402:6cb:: with SMTP id n11mr31707682edy.112.1628077895281; Wed, 04 Aug 2021 04:51:35 -0700 (PDT) MIME-Version: 1.0 References: <20210803215538.GU1583@gate.crashing.org> <20210804101722.GD1583@gate.crashing.org> In-Reply-To: <20210804101722.GD1583@gate.crashing.org> From: Prathamesh Kulkarni Date: Wed, 4 Aug 2021 17:20:58 +0530 Message-ID: Subject: Re: [RFC] Adding a new attribute to function param to mark it as constant To: Segher Boessenkool Cc: GCC Development , Richard Earnshaw Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Aug 2021 11:51:38 -0000 On Wed, 4 Aug 2021 at 15:49, Segher Boessenkool wrote: > > On Wed, Aug 04, 2021 at 03:20:45PM +0530, Prathamesh Kulkarni wrote: > > On Wed, 4 Aug 2021 at 03:27, Segher Boessenkool > > wrote: > > > The Linux kernel has a macro __is_constexpr to test if something is a= n > > > integer constant expression, see . That is a much > > > better idea imo. There could be a builtin for that of course, but an > > > attribute is less powerful, less usable, less useful. > > Hi Segher, > > Thanks for the suggestions. I am not sure tho if we could use a macro > > similar to __is_constexpr > > to check if parameter is constant inside an inline function (which is > > the case for intrinsics) ? > > I said we can make a builtin that returns if its arg is an ICE -- we do > not have to do tricky tricks :-) > > The macro would work fine in an inline function though, or, where do you > see potential problems? > > > For eg: > > #define __is_constexpr(x) \ > > (sizeof(int) =3D=3D sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (= int *)8))) > > > > inline int foo(const int x) > > { > > _Static_assert (__is_constexpr (x)); > > return x; > > } > > > > int main() > > { > > return foo (1); > > } > > > > results in: > > foo.c: In function =E2=80=98foo=E2=80=99: > > foo.c:8:3: error: static assertion failed > > 8 | _Static_assert (__is_constexpr (x)); > > And that is correct, x is *not* an integer constant expression here. > Because it is a variable, instead :-) > > If you do this in a macro it should work though? > > > Initially we tried to use __Static_assert (__builtin_constant_p (arg)) > > for the same purpose but that did not work > > because while parsing the intrinsic function, the FE cannot determine > > if the arg is indeed a constant. > > Yes. If you want something like that you need to test very late during > compilation whether something is a constant then: it will not be earlier. > > > I guess the static assertion or __is_constexpr would work only if the > > intrinsic were defined as a macro instead of an inline function ? > > Or am I misunderstanding ? > > Both __builtin_constant_p and __is_constexpr will not work in your use > case (since a function argument is not a constant, let alone an ICE). > It only becomes a constant value later on. The manual (for the former) > says: > You may use this built-in function in either a macro or an inline > function. However, if you use it in an inlined function and pass an > argument of the function as the argument to the built-in, GCC never > returns 1 when you call the inline function with a string constant or > compound literal (see Compound Literals) and does not return 1 when you > pass a constant numeric value to the inline function unless you specify > the -O option. Indeed, that's why I was thinking if we should use an attribute to mark par= am as a constant, so during type-checking the function call, the compiler can emit a diagnostic if the passed arg is not a constant. Alternatively -- as you suggest, we could define a new builtin, say __builtin_ice(x) that returns true if 'x' is an ICE. And wrap the intrinsic inside a macro that would check if the arg is an ICE= ? For eg: __extension__ extern __inline int32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshl_n_s32_1 (int32x2_t __a, const int __b) { return __builtin_neon_vshl_nv2si (__a, __b); } #define vshl_n_s32(__a, __b) \ ({ typeof (__a) a =3D (__a); \ _Static_assert (__builtin_constant_p ((__b)), #__b " is not an integer constant"); \ vshl_n_s32_1 (a, (__b)); }) void f(int32x2_t x, const int y) { vshl_n_s32 (x, 2); vshl_n_s32 (x, y); int z =3D 1; vshl_n_s32 (x, z); } With this, the compiler rejects vshl_n_s32 (x, y) and vshl_n_s32 (x, z) at all optimization levels since neither 'y' nor 'z' is an ICE. Instead of __builtin_constant_p, we could use __builtin_ice. Would that be a reasonable approach ? But this changes the semantics of intrinsic from being an inline function to a macro, and I am not sure if that's a good idea. Thanks, Prathamesh > An integer constant expression is well-defined whatever the optimisation > level is, it is a feature of the language. > > If some x is an ICE you can do > asm ("" :: "n"(x)); > and if it is a constant you can do > asm ("" :: "i"(x)); > (not that that gets you much further, but it might help explorng this). > > > Segher