[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