Xuan Tang via llvm-dev
2020-Sep-09 03:55 UTC
[llvm-dev] constrained cosine rounding mode behavior
Hi:
I am trying to implement interval arithmetic through llvm. I have a problem with
the rounding mode with llvm.experimental.constrained.cos
I have two pieces of codes:
; Function Attrs: norecurse nounwind readnone ssp uwtable
define double @cosine_down(double returned) local_unnamed_addr #0 {
; call the llvm intrinsic to perform downward cosine
%2 = call double @llvm.experimental.constrained.cos(double %0, metadata !"round.downward", metadata !"fpexcept.strict")
ret double %2
}
; Function Attrs: norecurse nounwind readnone ssp uwtable
define double @cosine_up(double returned) local_unnamed_addr #0 {
; call the llvm intrinsic to perform upward cosine
%2 = call double @llvm.experimental.constrained.cos(double %0, metadata !"round.upward", metadata !"fpexcept.strict")
ret double %2
}
When calling the function on a test number: 0.79358805865013693
The two functions return the same value: 0.7012920012119437.
Ideally, the two functions will give me the upper and lower bound of where the
true value will lie within, so maybe 0.7012920012119436 to 0.7012920012119438,
but it seems like even with the upward and downward rounding mode that’s not the
case.
I noted on the
page https://llvm.org/docs/LangRef.html#llvm-experimental-constrained-cos-intrinsic it
says This function returns the cosine of the specified operand, returning the
same values as the libm cos functions would
So does this mean that constrained cos does not care about the rounding mode but
instead will just return the same value?
Thank you
Xuan Tang
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20200908/19278381/attachment.html>
Craig Topper via llvm-dev
2020-Sep-09 05:28 UTC
[llvm-dev] constrained cosine rounding mode behavior
Hi Xuan Tang, The rounding mode argument to the intrinsic is supposed to be a hint to the compiler to tell us what the rounding mode has been changed to. In theory we could use this to constant fold the intrinsic with correct rounding but I don't think much of that is implemented. The compiler does not add any code to change the rounding mode in the hardware floating point unit in response to the intrinsic. It's up to the user to call something like fesetround in libm to change the rounding mode in hardware. Changing the rounding mode in hardware could have an effect on the result returned by the cos library function that we will ultimately call, but I don't know for sure. ~Craig On Tue, Sep 8, 2020 at 8:55 PM Xuan Tang via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi: > > I am trying to implement interval arithmetic through llvm. I have a > problem with the rounding mode with llvm.experimental.constrained.cos > > I have two pieces of codes: > > *; Function Attrs: norecurse nounwind readnone ssp uwtable* > *define* *double* *@cosine_down*(*double* returned) local_unnamed_addr #0 > { > *; call the llvm intrinsic to perform downward cosine* > *%2* = *call* *double* *@llvm.experimental.constrained.cos*(*double* > *%0*, *metadata* !"round.downward", *metadata* !"fpexcept.strict") > *ret* *double* *%2* > } > > *; Function Attrs: norecurse nounwind readnone ssp uwtable* > *define* *double* *@cosine_up*(*double* returned) local_unnamed_addr #0 { > *; call the llvm intrinsic to perform upward cosine* > *%2* = *call* *double* *@llvm.experimental.constrained.cos*(*double* > *%0*, *metadata* !"round.upward", *metadata* !"fpexcept.strict") > *ret* *double* *%2* > } > > When calling the function on a test number: 0.79358805865013693 > > The two functions return the same value: 0.7012920012119437. > > Ideally, the two functions will give me the upper and lower bound of where > the true value will lie within, so maybe 0.7012920012119436 to > 0.7012920012119438, but it seems like even with the upward and downward > rounding mode that’s not the case. > > I noted on the page > https://llvm.org/docs/LangRef.html#llvm-experimental-constrained-cos-intrinsic it > says This function returns the cosine of the specified operand, > returning the same values as the libm cos functions would > > So does this mean that constrained cos does not care about the rounding > mode but instead will just return the same value? > > Thank you > Xuan Tang > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200908/ad7ef5c1/attachment.html>
Xuan Tang via llvm-dev
2020-Sep-09 19:35 UTC
[llvm-dev] constrained cosine rounding mode behavior
Hi Craig:
Thanks for the reply. Now I put a set rounding mode before the corresponding
code, but strange things happen.
With the same input, the rounding down code returns larger value than the
rounding up value with cos.
Initially I thought it might because the input somehow got rounded down, and
since the input is between 0 and pi, which is on a downward slope, rounding down
the input will increase the value hence the error. Then I tested some value
larger than pi but smaller than 2pi, which has positive derivative, but the
error still happens. I think there might be something wrong with the cosine
intrinsic?
I’ve attached the code at the end, and before each call, the rounding mode is
set back to original (round to nearest).
; Function Attrs: ssp uwtable
define double @cosine_down(double returned) local_unnamed_addr #0 {
%2 = call i32 @fesetround(i32 1024)
%3 = call double @llvm.experimental.constrained.cos(double %0, metadata !"round.downward", metadata !"fpexcept.strict")
ret double %3
}
; Function Attrs: ssp uwtable
define double @cosine_up(double returned) local_unnamed_addr #0 {
%2 = call i32 @fesetround(i32 2048)
%3 = call double @llvm.experimental.constrained.cos(double %0, metadata !"round.upward", metadata !"fpexcept.strict")
ret double %3
}
Test result:
Input interval from 0.7935880586501369 to 0.7935880586501369, cosine result from
0.7012920012119436 to 0.7012920012119435
is empty: true
Input interval from 3.17588058650137 to 3.17588058650137, cosine result from
-0.9994122264169831 to -0.9994122265888515
is empty: true
Thank you
Xuan Tang
On Sep 9, 2020, 00:28 -0500, Craig Topper <craig.topper at gmail.com>,
wrote:> Hi Xuan Tang,
>
> The rounding mode argument to the intrinsic is supposed to be a hint to the
compiler to tell us what the rounding mode has been changed to. In theory we
could use this to constant fold the intrinsic with correct rounding but I
don't think much of that is implemented. The compiler does not add any code
to change the rounding mode in the hardware floating point unit in response to
the intrinsic. It's up to the user to call something like fesetround in libm
to change the rounding mode in hardware. Changing the rounding mode in hardware
could have an effect on the result returned by the cos library function that we
will ultimately call, but I don't know for sure.
>
> ~Craig
>
>
> > On Tue, Sep 8, 2020 at 8:55 PM Xuan Tang via llvm-dev <llvm-dev at
lists.llvm.org> wrote:
> > > Hi:
> > >
> > > I am trying to implement interval arithmetic through llvm. I have
a problem with the rounding mode with llvm.experimental.constrained.cos
> > >
> > > I have two pieces of codes:
> > >
> > > ; Function Attrs: norecurse nounwind readnone ssp uwtable
> > > define double @cosine_down(double returned) local_unnamed_addr
#0 {
> > > ; call the llvm intrinsic to perform downward cosine
> > >
%2 = call double @llvm.experimental.constrained.cos(double %0, metadata !"round.downward", metadata !"fpexcept.strict")
> > > ret double %2
> > > }
> > >
> > > ; Function Attrs: norecurse nounwind readnone ssp uwtable
> > > define double @cosine_up(double returned) local_unnamed_addr #0 {
> > > ; call the llvm intrinsic to perform upward cosine
> > >
%2 = call double @llvm.experimental.constrained.cos(double %0, metadata !"round.upward", metadata !"fpexcept.strict")
> > > ret double %2
> > > }
> > >
> > > When calling the function on a test number: 0.79358805865013693
> > >
> > > The two functions return the same value: 0.7012920012119437.
> > >
> > > Ideally, the two functions will give me the upper and lower bound
of where the true value will lie within, so maybe 0.7012920012119436 to
0.7012920012119438, but it seems like even with the upward and downward rounding
mode that’s not the case.
> > >
> > > I noted on the
page https://llvm.org/docs/LangRef.html#llvm-experimental-constrained-cos-intrinsic it
says This function returns the cosine of the specified operand, returning the
same values as the libm cos functions would
> > >
> > > So does this mean that constrained cos does not care about the
rounding mode but instead will just return the same value?
> > >
> > > Thank you
> > > Xuan Tang
> > > _______________________________________________
> > > LLVM Developers mailing list
> > > llvm-dev at lists.llvm.org
> > > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20200909/733590aa/attachment.html>
Cranmer, Joshua via llvm-dev
2020-Sep-10 16:04 UTC
[llvm-dev] constrained cosine rounding mode behavior
The LangRef does specify that the rounding mode/exception behavior is advisory,
not mandatory, although it could probably be spelled out better.
That said, there are some architectures where rounding mode can be configured on
a per-instruction basis (e.g., AVX-512 has the SAE bits that serve this purpose,
and I believe the various GPU architectures follow suit). It may be worth having
some support for this in LLVM.
From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Craig
Topper via llvm-dev
Sent: Wednesday, September 9, 2020 1:28
To: Xuan Tang <txstc55 at gmail.com>
Cc: llvm-dev <llvm-dev at lists.llvm.org>
Subject: Re: [llvm-dev] constrained cosine rounding mode behavior
Hi Xuan Tang,
The rounding mode argument to the intrinsic is supposed to be a hint to the
compiler to tell us what the rounding mode has been changed to. In theory we
could use this to constant fold the intrinsic with correct rounding but I
don't think much of that is implemented. The compiler does not add any code
to change the rounding mode in the hardware floating point unit in response to
the intrinsic. It's up to the user to call something like fesetround in libm
to change the rounding mode in hardware. Changing the rounding mode in hardware
could have an effect on the result returned by the cos library function that we
will ultimately call, but I don't know for sure.
~Craig
On Tue, Sep 8, 2020 at 8:55 PM Xuan Tang via llvm-dev <llvm-dev at
lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote:
Hi:
I am trying to implement interval arithmetic through llvm. I have a problem with
the rounding mode with llvm.experimental.constrained.cos
I have two pieces of codes:
; Function Attrs: norecurse nounwind readnone ssp uwtable
define double @cosine_down(double returned) local_unnamed_addr #0 {
; call the llvm intrinsic to perform downward cosine
%2 = call double @llvm.experimental.constrained.cos(double %0, metadata
!"round.downward", metadata !"fpexcept.strict")
ret double %2
}
; Function Attrs: norecurse nounwind readnone ssp uwtable
define double @cosine_up(double returned) local_unnamed_addr #0 {
; call the llvm intrinsic to perform upward cosine
%2 = call double @llvm.experimental.constrained.cos(double %0, metadata
!"round.upward", metadata !"fpexcept.strict")
ret double %2
}
When calling the function on a test number: 0.79358805865013693
The two functions return the same value: 0.7012920012119437.
Ideally, the two functions will give me the upper and lower bound of where the
true value will lie within, so maybe 0.7012920012119436 to 0.7012920012119438,
but it seems like even with the upward and downward rounding mode that’s not the
case.
I noted on the page
https://llvm.org/docs/LangRef.html#llvm-experimental-constrained-cos-intrinsic
it says This function returns the cosine of the specified operand, returning
the same values as the libm cos functions would
So does this mean that constrained cos does not care about the rounding mode but
instead will just return the same value?
Thank you
Xuan Tang
_______________________________________________
LLVM Developers mailing list
llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20200910/702b3762/attachment.html>