From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by sourceware.org (Postfix) with ESMTPS id 7C718388A010 for ; Tue, 11 Jan 2022 07:12:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7C718388A010 Received: by mail-ed1-x530.google.com with SMTP id w16so63257966edc.11 for ; Mon, 10 Jan 2022 23:12:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=OJ+N3knKZOhAoZ7QLmKgtEcwdrg23rCrDu+KqG6eulY=; b=rFmeZiMTM7vihu1Fp4wdzwgsZzgI3PadnvR56wA/Oi3AO65nVuTK3w467qKgBGUcDx cn9O1GMeZfzaTBnXemKlgf64G9gsDtHBTaVDk2LXar52nWwL9+TP8USD5Uuje77Zjvvn ZwsFpnCpONI/+Ac4Qop2A7i+4La5KXrRSM6q/JHyhUPv/BD6oV/BHMyCdkgxpdIJXphi fbkn2p6mshVV8eJ9Rih9ltu1svJWkPIciUdzbAk3YON9xyQjMfT5DpYswAN02zIj4E5z ZCVTzQtANNCdG4Pw4BJfRwWnLA4rYGuwurwFCx/J+XVk2Q9YLq12wIPj8RSVN/3uQ8gJ XBBg== X-Gm-Message-State: AOAM531AFy1weIDMsqVwj7mtzLZ+HKb20lDjDYIRO4CsycWukjYnXlc4 BrF0QgB4roxyZDEO+O7y5jusIBaE+kLGJwVloT8= X-Google-Smtp-Source: ABdhPJwfgiFwoyd21t4x9Uk5bp7FAUOQiDgKsK9q7paBOGIUZiErw/GtiCEt7jnSKdM3l2RK+IVMADJK/oi41MX252o= X-Received: by 2002:a17:907:1c1f:: with SMTP id nc31mr608729ejc.624.1641885126474; Mon, 10 Jan 2022 23:12:06 -0800 (PST) MIME-Version: 1.0 References: <832b1b3957a0243ca37378a774effe537642eed3.camel@gmail.com> <40fd9a2f078cd6e87fedbc5f1e77baf8445a7356.camel@gmail.com> In-Reply-To: <40fd9a2f078cd6e87fedbc5f1e77baf8445a7356.camel@gmail.com> From: Richard Biener Date: Tue, 11 Jan 2022 08:11:55 +0100 Message-ID: Subject: Re: reordering of trapping operations and volatile To: Martin Uecker Cc: Andrew Pinski , "gcc@gcc.gnu.org" Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, 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: Tue, 11 Jan 2022 07:12:10 -0000 On Mon, Jan 10, 2022 at 6:36 PM Martin Uecker wrote: > > Am Montag, den 10.01.2022, 10:04 +0100 schrieb Richard Biener: > > On Sat, Jan 8, 2022 at 10:09 PM Martin Uecker via Gcc wrote: > > > Am Samstag, den 08.01.2022, 10:35 -0800 schrieb Andrew Pinski: > > > > On Sat, Jan 8, 2022 at 12:33 AM Martin Uecker via Gcc wrote: > > > > > Hi Richard, > > > > > > > > > > I have a question regarding reodering of volatile > > > > > accesses and trapping operations. My initial > > > > > assumption (and hope) was that compilers take > > > > > care to avoid creating traps that are incorrectly > > > > > ordered relative to observable behavior. > > > > > > > > > > I had trouble finding examples, and my cursory > > > > > glace at the code seemed to confirm that GCC > > > > > carefully avoids this. But then someone showed > > > > > me this example, where this can happen in GCC: > > > > > > > > > > > > > > > volatile int x; > > > > > > > > > > int foo(int a, int b, _Bool store_to_x) > > > > > { > > > > > if (!store_to_x) > > > > > return a / b; > > > > > x = b; > > > > > return a / b; > > > > > } > > > > > > > > > > > > > > > https://godbolt.org/z/vq3r8vjxr > > > > > > > > The question becomes what is a trapping instruction vs an undefined > > > > instruction? > > > > For floating point types, it is well defined what is a trapping > > > > instruction while for integer types it is not well defined. > > > > On some (many?) targets dividing by 0 is just undefined and does not > > > > trap (powerpc, aarch64, arm and many others; MIPS it depends on the > > > > options passed to GCC if the conditional trap should be inserted or > > > > not). > > > > The other side is if there is undefined code on the path, should > > > > observable results happen first (stores to volatile/atomics, etc.)? > > > > > > I think for volatile stores and I/O, I think it would be > > > nice of we could guarantee that those happen before the UB > > > ruins the day. (I am not sure about atomics, those are > > > not directly obsevable) > > > > > > For I/O this is probably already the case (?). > > > > I/O usually happens through function calls where this is usually > > already guaranteed as GCC doesn't know whether the function > > will always return normally so the UB of a divide by zero might > > be properly guarded. > > Yes. > > > > For volatile, it seems this would need some tweaks. > > > > Yes, likewise when re-ordering (observable) traps like > > > > r = a / b; > > q = c / d; > > I think this could also be useful. But at the moment I am > concerned about the effect previous defined behavior > being affected. For this, reordering traps is OK. Also > sinking traps across observable behavior is OK. Just > hoisting it up across observable behavior would > be a problem. But in general that would apply to all UB. Consider int foo (int a, int b) { if (a < b) return a + b; bar (); return a + b; } we are happily hoisting a + b to the start of the function but of course a + b can invoke UB. We consider that to not matter because we eventually invoke this UB anyway. Unless of course bar() does not return. I realize that UB in a + b isn't (usually) observable but UB resulting in traps are. So I'm still wondering why you think that 'volatile' makes a critical difference we ought to honor? I don't remember 'volatile' being special in the definition of the abstract machine with regarding to observability (as opposed to sequence points). > > > I am trying to figure out whether this is feasible. > > > > For PRE yes, you'd just need to include the observable stmts you > > care in the set of stmts that cause PRE to set BB_MAY_NOTRETURN. > > In general this is of course harder. > > What other passes would need to be checked? All that do code motion by design or by accident. The difficulty is that the resulting "wrong IL" is not wrong per se, just the difference is which is hard to write a checker for (well, in priciple you could copy the IL before passes and compare to the IL after) > And do you think there is any negative impact on > an important optimization (considering this affects > only volatile accesses)? Probably not. But then semantics of 'volatile' are very weak defined so I'd like to see a reference to a part of the standard that supports declaring this (and only this - the 'volatile' case) a bug. > > > > GCC assumes by default that divide is trappable but stores not are not > > > > observable. This is where -fnon-call-exceptions come into play. > > > > > > Ok, thanks! I will look at this! > > > > > > > In the second case, GCC assumes reducing trappable instructions are > > > > fine. > > > > > > -fnon-call-exceptions would treat trapping instructions > > > as defined (and trapping) instead of UB? This is > > > then probably even stronger than the requirement above. > > > > No, I don't think it turns UB into defined behavior. Some frontends might > > expect that to some extent. So even with -fnon-call-exceptions we'd > > happily do the re-ordering unless the exception is catched in the same > > function. > > Thanks, > Martin > > > > > Note I thought -fno-delete-dead-exceptions would fix the sink > > > > but it didn't. > > > > > > Martin > > > > > > >