From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS22989 209.51.188.0/24 X-Spam-Status: No, score=-3.4 required=3.0 tests=AWL,BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id EE1CC1F461 for ; Fri, 28 Jun 2019 21:10:58 +0000 (UTC) Received: from localhost ([::1]:36372 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgy92-0008Gu-3Q for normalperson@yhbt.net; Fri, 28 Jun 2019 17:10:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54066) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgy6V-0006bJ-Va for bug-gnulib@gnu.org; Fri, 28 Jun 2019 17:08:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hgy6U-0007j8-6a for bug-gnulib@gnu.org; Fri, 28 Jun 2019 17:08:19 -0400 Received: from mail-ot1-x332.google.com ([2607:f8b0:4864:20::332]:42046) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hgy6S-0007fE-R3 for bug-gnulib@gnu.org; Fri, 28 Jun 2019 17:08:18 -0400 Received: by mail-ot1-x332.google.com with SMTP id l15so7345497otn.9 for ; Fri, 28 Jun 2019 14:08:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=HOrMmQEm9jWBfwD7c7FjdOiWInhNHTe8lvhrU/9EVgU=; b=KybW0/5QBUmutANtQyM5zPaNaH3Rr8Z/4/occ2wvvdABlo98fR6A7Aw+tJn3LlFgMo yG41dVCZ7kUjLZkXbEFRjjPdp5Trxb5RgwExQydRacHrRUem7LBJWLY30cSi5joy7Cb9 TalCe+CMjsEdWsmcCkioCjhsDr8NDQ5Dz/C2/gvGq4egCfrOnMrPawdFmWsNZILzdYki RCbTmye2YgglBa1wbm/Ki1/L9tkrSUbUQPn9/Wvp9vdAsFVRcZ2p3hmmOalfhvfGmmRK H+7Li0vIXJ3JhJAtLnH4e5w8kh083MILBYTVUH6zlrEh90Ob9ZxDd3AKBDWOPlmA6/Vu 4fJA== 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; bh=HOrMmQEm9jWBfwD7c7FjdOiWInhNHTe8lvhrU/9EVgU=; b=HxWlhQPbVWJ0uF9pLx0E1hi0j6vENnHapnzkgpf9gWq3GPFEw1mJGIBIniY/3jWgXP 66kJUYSK13XJTAEEEIrjQrSAsgrYbsH8m+yB6Ja1HOcmcc7wM+ens9xDDPaypmY3xFho VCrlY/fVAS2jNOA957NIpanfLTXz2WdO92YrZRInWm5fMMoPpNtRc5vPomMN/omqUYT8 QB5BbI+Cb8GckgGCt/4eKk3wzFV1WOOBe1Ejn5MWfIb0FDOBt+bo8oFRSMGinAn5Zcu/ Q7ouJxlnWMVE+gllt1yJaoRFW+2pJsT27FigV93shsIq41pc90Mh02NZAIjV780Q//oN RjbQ== X-Gm-Message-State: APjAAAUaBpy5hEP2dlHrY4J0pScOmqPCE0sua/Bpz3dvfDQgEZiUDRTC Nbl5OAjsKoUK5/lBjc+jGRkccDK6pFA8UW26flc= X-Google-Smtp-Source: APXvYqyAsHNltupA2PFc2hVGyp0OfMUHOxYyMdj5P+nqnA9UmTBE3JfLzJSehtkHVXazT5i8b7aTeZJNA/9ZHLAemvo= X-Received: by 2002:a9d:3c5:: with SMTP id f63mr9475512otf.210.1561756093089; Fri, 28 Jun 2019 14:08:13 -0700 (PDT) MIME-Version: 1.0 References: <8979488.cRkkfcT1mV@omega> <11002295.LrvMqknVDZ@omega> In-Reply-To: <11002295.LrvMqknVDZ@omega> From: Pip Cet Date: Fri, 28 Jun 2019 21:07:37 +0000 Message-ID: Subject: Re: bug#36370: 27.0.50; XFIXNAT called on negative numbers To: Bruno Haible Content-Type: text/plain; charset="UTF-8" X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::332 X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: 36370@debbugs.gnu.org, Paul Eggert , bug-gnulib@gnu.org Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" On Fri, Jun 28, 2019 at 7:11 PM Bruno Haible wrote: > Pip Cet wrote: > > Sorry, can't reproduce that here. I'm sure the changes I need to make > > are obvious once I've found them, but can you let me know your gcc > > version? > > I reproduce this with GCC versions 5.4.0, 6.5.0, 7.4.0, 8.3.0, and 9.1.0. > 1. Take the files foo.c and bar.c from > > 2. Compile and disassemble: > gcc -O2 -m32 -flto foo.c bar.c -shared -o libfoo.so && objdump --disassemble > libfoo.so > Observe that f_assume pushes an immediate $0 argument on the stack for the > function call. > 3. Enable the second 'assume' definition instead of the first one. > 4. Compile and disassemble: > gcc -O2 -m32 -flto foo.c bar.c -shared -o libfoo.so && objdump --disassemble > libfoo.so > Observe that f_assume is now an alias of f_generic, that pushes a > computed value as argument on the stack for the function call (push %eax). Thanks. I have no idea what I was doing wrong, but I can confirm that this case indeed demonstrates a GCC weakness when there is a non-split eassume (A && B), where A and B are both assumable (in the sense that __builtin_constant_p(!A == !A). > > Sorry to be pedantic, but do you disagree that it is better in these > > cases, or in general? > > I disagree that it is better in general. > You're apparently setting out a high goal for the 'assume' macro: > (1) that the programmer may call it with an expression that involves > function calls, That's the status quo in Emacs and many other projects that have started believing the "an inline function is as fast as a macro" mantra*, assuming you include inline functions with "function calls". (* - as have I) > (2) that the generated code will never include these function calls, > because the generated code with the 'assume' invocation should be > optimized at least as well as the generated code without the > 'assume' invocation. I think it should be the rarest of exceptions for an assume() to result in slower code, yes. I believe that includes the case where functions marked inline aren't inlined, because of compiler options, for example. > I'm adding certain quality criteria: > - It is not "good" if a construct behaves unpredictably, that is, > if it hard to document precisely how it will behave. (*) Uhm, isn't the whole point of assume() to make the program behavior undefined in a certain case? int i = 1; assume(i == 0); will behave unpredictably. That's why we use the assume(), to speed up execution by providing the compiler with an expression which "may or may not be evaluated", and allowing it to do just anything if the expression evaluates to false. That's the documented API. If you want your program to behave predictably, in the strict sense, you cannot ever use the current assume() API. If you want it to behave predictably in some looser sense, the sense I suggest is that assume(C) may or may not evaluate C. Again, that's what the documentation says. > - It is not "good" if the behaviour with no LTO is different from > the behaviour with LTO. I agree I should investigate the LTO example further, but please let's keep in mind that I observed problematic behavior of assume(A && B) in other contexts, so I'm not convinced LTO is the decisive factor here. However, optimization can and will influence program behavior in many ways. One of these ways is whether the argument to assume, which the programmer knows "may or may not be evaluated", is evaluated or not. > The implementation with the __builtin_constant, while attaining the > goals (1) and (2), does not satisfy the two quality criteria. For the record, my quality criteria are: (1) implement the documented API, and don't change it (2) when optimizing for speed, do not produce slower code with eassume() than we would without it. Even when the programmer wrongly guessed that a function would be inlined. (3) when optimizing for size, do not produce larger code with eassume() than we would without it. Even when inline functions are not inlined. (4) be at least as fast as gnulib assume() > I believe the only way to attain the goals and the quality criteria > is, as you suggested, to ask the GCC people to add a __builtin_assume > built-in. I think there's a significant probability that the GCC people would agree to add such a built-in, but insist on its having "may or may not evaluate its argument" semantics. > > > 1. The new 'assume' is worse when -flto is in use. > > > > Maybe. Even if it is, though, that's a GCC limitation which I consider > > likely to be fixable > > Yes, *maybe* the GCC people can change the semantics of __builtin_constant_p > so that it is effectively computed at link-time, rather than when a single > compilation unit gets compiled. Or maybe not. I don't know... Hmm. My observations suggest that __builtin_constant_p is effectively computed at link-time; all I have to do is to split the assume() in your example. > > It's way too easy to do something like > > > > eassume(ptr->field >= 0 && f(ptr)); > > > > when what you mean is > > > > eassume(ptr->field >= 0); > > eassume(f(ptr)); > > I argue that it's unnatural if the two don't behave exactly the same. But you're arguing for a __builtin_assume which doesn't evaluate its argument, still? Because { i++; __builtin_assume(i == 0); __builtin_assume(infloop()); i++; } could validly be optimized to i = 1, while { i++; __builtin_assume(i == 0 && infloop()); i++; } could not be. Or did I misunderstand the semantics you suggested for __builtin_assume? > Like everyone expects that > x = foo ? yes : no; > is equivalent to > if (foo) x = yes; else x = no; It is. > And everyone expects that > if (A && B) { ... } > is equivalent to > if (A) if (B) { ... } It is. Sorry if I'm being a bit dense here.