[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