[llvm-dev] FW: clarification needed for the constrained fp implementation.

陳韋任 via llvm-dev llvm-dev at lists.llvm.org
Fri Nov 3 15:26:39 PDT 2017


2017-11-04 4:29 GMT+08:00 Kaylor, Andrew via llvm-dev <
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>; Sumner, Brian <Brian.Sumner at amd.com>;
> Arsenault, Matthew <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?

Regards,
chenwj

-- 
Wei-Ren Chen (陳韋任)
Homepage: https://people.cs.nctu.edu.tw/~chenwj
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171104/f2e75a9b/attachment.html>


More information about the llvm-dev mailing list