[llvm-dev] FW: clarification needed for the constrained fp implementation.
Hal Finkel via llvm-dev
llvm-dev at lists.llvm.org
Fri Nov 3 17:45:44 PDT 2017
On 11/03/2017 05:26 PM, 陳韋任 via llvm-dev wrote:
>
>
> 2017-11-04 4:29 GMT+08:00 Kaylor, Andrew via llvm-dev
> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>>:
>
> Copying the list on a discussion of potentially general interest….
>
> *From:* Kaylor, Andrew
> *Sent:* Friday, November 03, 2017 1:11 PM
> *To:* 'Ding, Wei' <Wei.Ding2 at amd.com <mailto:Wei.Ding2 at amd.com>>;
> Sumner, Brian <Brian.Sumner at amd.com
> <mailto:Brian.Sumner at amd.com>>; Arsenault, Matthew
> <Matthew.Arsenault at amd.com <mailto:Matthew.Arsenault at amd.com>>
> *Subject:* RE: clarification needed for the constrained fp
> implementation.
>
> Hi Wei,
>
> I’ve been meaning to write something up for discussion on the LLVM
> Dev list about this. I hope you don’t mind if I copy the list now
> to accomplish that while also answering your questions.
> Eventually I create a document describing this in more detail and
> less formally than the language definition.
>
> Basically, the “constraints” in the constrained FP intrinisics are
> constraints on the optimizer. They are a way of telling the
> optimizer what it can and cannot assume about rounding mode and FP
> exception behavior. By default, the optimizer assumes that the
> rounding mode is round-to-nearest and that FP exceptions are being
> ignored. If the user code is going to do anything that
> invalidates these assumptions, then we need a way to make the
> optimizer stop assuming that. That’s what the intrinisics do.
> Because most passes don’t recognize the intrinisics, they can’t do
> anything with the operations they represent and therefore can’t
> make any assumption about them.
>
> The intrinsics are not intended to do anything to change the
> rounding mode or FP exception handling state. I have an idea in
> mind for some additional intrinsics that would provide a way to
> control the FP environment. There are already some
> target-specific mechanisms for doing that, but I’d like to have
> something that’s target independent. I’ll say more about this in a
> minute.
>
> I mentioned in my review comments that my work on this has been
> motivated by the STDC pragmas, and I think if I explain that it
> might make the semantics of the intrinsics seem a little more
> natural. The primary pragma I have in mind here is the “STDC
> FENV_ACCESS” pragma. I believe this is part of the C99 standard,
> but compiler support for it is still mostly (if not entirely)
> missing. For instance, if you try to use this pragma with clang
> you will get a message telling you that the pragma isn’t supported
> and it will have no other effect. We want to change that.
>
> Basically, what the “STDC FENV_ACCESS” pragma does is provide
> programmers with a way to tell the compiler that the program might
> change the FP environment. This pragma represents a setting that
> has only two states -- on and off. The default setting of this
> state is documented as being implementation defined. In clang the
> default state will be off. The C99 standard states that accessing
> the FP environment (testing FP status flags, changing FP control
> modes, etc.) when FENV_ACCESS is off is undefined behavior. The
> C99 standard provides library calls to access the environment
> (fesetround, fegetround, fetestexcept, etc.) but you can only
> safely use these if you have set FENV_ACCESS to the “on” state. A
> typical usage might look like this:
>
> #include <fenv.h>
>
> double someFunc(double A, double B, bool ForceRoundUp) {
>
> #pragma STDC FENV_ACCESS ON
>
> double Result;
>
> if (ForceRoundUp) {
>
> int OldRM = fegetround();
>
> fesetround(FE_UPWARD);
>
> Result = A/B;
>
> fesetround(OldRM);
>
> } else {
>
> Result = A/B;
>
> }
>
> return Result;
>
> }
>
>
> ...
> abridge
> ...
>
>
> What I’m thinking is that we need something like this:
>
> void llvm.set.roundingmode(i32 mode)
>
> i32 lllvm.get.roundingmode()
>
> These would then get translated during instruction selection to
> target-specific instructions, which is equivalent to what
> fesetround() and fegetround() do. But I think it would also be
> useful to have something like this:
>
> void llvm.begin.local.roundingmode(i32 mode)
>
> void llvm.end.local.roundingmode()
>
>
> A little bit of curiously. What if user doesn't restore the OldRM
> like this
>
> double someFunc(double A, double B, bool ForceRoundUp) {
> #pragma STDC FENV_ACCESS ON
> double Result;
> if (ForceRoundUp) {
> int OldRM = fegetround();
> fesetround(FE_UPWARD);
> Result = A/B;
> //
> fesetround(OldRM);
> } else {
> Result = A/B;
> }
> return Result;
>
> }
>
>
> Are we still going to generate
> llvm.begin.local.roundingmode/llvm.end.local.roundingmode?
I think that, however we do this, we'll need a way of dealing with "live
in" and "live out" FP-environment state. Moreover, any external call can
change these as well (unless we prove/know that it doesn't). Translating
these calls into intrinsics so that the optimizer can reason about them
seems like a reasonable plan.
-Hal
>
> Regards,
> chenwj
>
> --
> Wei-Ren Chen (陳韋任)
> Homepage: https://people.cs.nctu.edu.tw/~chenwj
> <https://people.cs.nctu.edu.tw/%7Echenwj>
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171103/381f336d/attachment.html>
More information about the llvm-dev
mailing list