Hal Finkel
2013-Sep-13 00:44 UTC
[LLVMdev] [RFC] New function attributes for errno-setting functions
Hello, Our current handling of -fno-math-errno (and this -ffast-math) in Clang is broken on systems for which libm functions do actually set errno. This is because, when -fno-math-errno is in effect, libm functions like sqrt, sin, cos, etc. are marked as readnone. As a result, these calls can be reordered with respect to other calls that set errno, and can clobber errno before it can be read. For example: int fd = open(...); if (fd == -1) { perror("oops"); } double f = sqrt(a); If we're on a system (like Linux, for example), where sqrt might set errno to EDOM when a is negative, we can have a problem if some optimization rearranges the code to something like this: int fd = open(...); double f = sqrt(a); if (fd == -1) { perror("oops"); } if the open fails, and a is -2.0, then perror will print the wrong error string (thus confusing the user). This is not really a problem with the optimization because sqrt was marked as readnone. On the other hand, we don't want to tag sqrt and writing to some arbitrary external state variable, because this will prevent autovectorization, will prevent CSE from collecting duplicate calls to sqrt, and a host of other important optimizations. To fix this problem, I think that we need to stop treating errno as some arbitrary external state, and model is explicitly. Functions need to be able carry two additional attributes: 1. 'writes-only-errno' - An attribute to indicate that the function may set errno, and that is the only external state to which it might write. This is useful because getModRefInfo queries can return more accurate answers when comparing to pointers that we know cannot point to errno (such as alloca'd memory and functions) [is this allowed at all?]. 2. 'errno-ignored' - Set when -fno-math-errno is in effect, indicating that it is safe to assume that the user does not care about any value of errno set by this function. This will allow CSE and autovectorization to happen (by modifying those passes to specifically query this attribute). With these new attributes, the functions are, on systems for which libm functions might set errno, not marked readnone or readonly. This will prevent unwanted reordering. Thoughts? Thanks again, Hal -- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory
Krzysztof Parzyszek
2013-Sep-13 18:52 UTC
[LLVMdev] [RFC] New function attributes for errno-setting functions
On 9/12/2013 7:44 PM, Hal Finkel wrote:> > To fix this problem, I think that we need to stop treating errno as some arbitrary external state, and model is explicitly.In such case it would make sense to know when "errno" is read. This way we could detect whether it's actually used, whether or not the -fno-math-errno (or some generic -fno-xyz-errno) was specified. Problem is that errno (referenced explicitly) may be a macro that expands to some system-specific function call. On that note, what would be really nice is if a function could have an "mod/use" sets attached to it, which would specify what external symbols this function can reference. I'm not sure how that could be expressed in the current IR though. -K -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Hal Finkel
2013-Sep-13 19:23 UTC
[LLVMdev] [RFC] New function attributes for errno-setting functions
----- Original Message -----> On 9/12/2013 7:44 PM, Hal Finkel wrote: > > > > To fix this problem, I think that we need to stop treating errno as > > some arbitrary external state, and model is explicitly. > > In such case it would make sense to know when "errno" is read. This > way > we could detect whether it's actually used, whether or not the > -fno-math-errno (or some generic -fno-xyz-errno) was specified. > Problem > is that errno (referenced explicitly) may be a macro that expands to > some system-specific function call.I agree, and this is exactly the problem: It is really hard, as far as I understand, to figure out what 'errno' actually is. On the other hand, the frontend has more information on this, at least in theory, and maybe it could communicate it to the backend somehow. Maybe the easiest way would be to insert an intrinsic @llvm.errno.read() whenever errno (as a source token) appears in the source as an rvalue (and do some similar thing when it appears as a lvalue). Thoughts?> > On that note, what would be really nice is if a function could have > an > "mod/use" sets attached to it, which would specify what external > symbols > this function can reference. I'm not sure how that could be > expressed > in the current IR though.We could attach this as metadata currently. In terms of extending the IR, we might be able to add 'implicit' function parameters similar to what we do for MIs. -Hal> > -K > > -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, > hosted by The Linux Foundation > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory
Dan Gohman
2013-Sep-13 21:02 UTC
[LLVMdev] [RFC] New function attributes for errno-setting functions
Food for thought: If you have a codebase which can't use -fno-math-errno, because it relies on errno values from math functions, it may be a more effective long-term strategy to work on modernizing your codebase, eliminating the dependencies on errno, rather than going through the trouble of adding even more complexity to compilers to keep errno support limping along. Of course, whether this actually makes sense for you in your situation depends on many factors. Dan On Thu, Sep 12, 2013 at 5:44 PM, Hal Finkel <hfinkel at anl.gov> wrote:> Hello, > > Our current handling of -fno-math-errno (and this -ffast-math) in Clang is > broken on systems for which libm functions do actually set errno. This is > because, when -fno-math-errno is in effect, libm functions like sqrt, sin, > cos, etc. are marked as readnone. As a result, these calls can be reordered > with respect to other calls that set errno, and can clobber errno before it > can be read. For example: > > int fd = open(...); > if (fd == -1) { > perror("oops"); > } > double f = sqrt(a); > > If we're on a system (like Linux, for example), where sqrt might set errno > to EDOM when a is negative, we can have a problem if some optimization > rearranges the code to something like this: > > int fd = open(...); > double f = sqrt(a); > if (fd == -1) { > perror("oops"); > } > > if the open fails, and a is -2.0, then perror will print the wrong error > string (thus confusing the user). This is not really a problem with the > optimization because sqrt was marked as readnone. On the other hand, we > don't want to tag sqrt and writing to some arbitrary external state > variable, because this will prevent autovectorization, will prevent CSE > from collecting duplicate calls to sqrt, and a host of other important > optimizations. > > To fix this problem, I think that we need to stop treating errno as some > arbitrary external state, and model is explicitly. Functions need to be > able carry two additional attributes: > > 1. 'writes-only-errno' - An attribute to indicate that the function may > set errno, and that is the only external state to which it might write. > This is useful because getModRefInfo queries can return more accurate > answers when comparing to pointers that we know cannot point to errno (such > as alloca'd memory and functions) [is this allowed at all?]. > > 2. 'errno-ignored' - Set when -fno-math-errno is in effect, indicating > that it is safe to assume that the user does not care about any value of > errno set by this function. This will allow CSE and autovectorization to > happen (by modifying those passes to specifically query this attribute). > > With these new attributes, the functions are, on systems for which libm > functions might set errno, not marked readnone or readonly. This will > prevent unwanted reordering. Thoughts? > > Thanks again, > Hal > > -- > Hal Finkel > Assistant Computational Scientist > Leadership Computing Facility > Argonne National Laboratory > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130913/6c25ba3e/attachment.html>
Hal Finkel
2013-Sep-13 21:07 UTC
[LLVMdev] [RFC] New function attributes for errno-setting functions
----- Original Message -----> > Food for thought: If you have a codebase which can't use > -fno-math-errno, because it relies on errno values from math > functions, it may be a more effective long-term strategy to work on > modernizing your codebase, eliminating the dependencies on errno, > rather than going through the trouble of adding even more complexity > to compilers to keep errno support limping along. >Wouldn't that require 'modernizing' POSIX? ;) How else can you get the error code from open() or any number of other functions? -Hal> > Of course, whether this actually makes sense for you in your > situation depends on many factors. > > > Dan > > > > On Thu, Sep 12, 2013 at 5:44 PM, Hal Finkel < hfinkel at anl.gov > > wrote: > > > Hello, > > Our current handling of -fno-math-errno (and this -ffast-math) in > Clang is broken on systems for which libm functions do actually set > errno. This is because, when -fno-math-errno is in effect, libm > functions like sqrt, sin, cos, etc. are marked as readnone. As a > result, these calls can be reordered with respect to other calls > that set errno, and can clobber errno before it can be read. For > example: > > int fd = open(...); > if (fd == -1) { > perror("oops"); > } > double f = sqrt(a); > > If we're on a system (like Linux, for example), where sqrt might set > errno to EDOM when a is negative, we can have a problem if some > optimization rearranges the code to something like this: > > int fd = open(...); > double f = sqrt(a); > if (fd == -1) { > perror("oops"); > } > > if the open fails, and a is -2.0, then perror will print the wrong > error string (thus confusing the user). This is not really a problem > with the optimization because sqrt was marked as readnone. On the > other hand, we don't want to tag sqrt and writing to some arbitrary > external state variable, because this will prevent > autovectorization, will prevent CSE from collecting duplicate calls > to sqrt, and a host of other important optimizations. > > To fix this problem, I think that we need to stop treating errno as > some arbitrary external state, and model is explicitly. Functions > need to be able carry two additional attributes: > > 1. 'writes-only-errno' - An attribute to indicate that the function > may set errno, and that is the only external state to which it might > write. This is useful because getModRefInfo queries can return more > accurate answers when comparing to pointers that we know cannot > point to errno (such as alloca'd memory and functions) [is this > allowed at all?]. > > 2. 'errno-ignored' - Set when -fno-math-errno is in effect, > indicating that it is safe to assume that the user does not care > about any value of errno set by this function. This will allow CSE > and autovectorization to happen (by modifying those passes to > specifically query this attribute). > > With these new attributes, the functions are, on systems for which > libm functions might set errno, not marked readnone or readonly. > This will prevent unwanted reordering. Thoughts? > > Thanks again, > Hal > > -- > Hal Finkel > Assistant Computational Scientist > Leadership Computing Facility > Argonne National Laboratory > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >-- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory
Dan Gohman
2013-Sep-13 22:03 UTC
[LLVMdev] [RFC] New function attributes for errno-setting functions
It was pointed out to me that I misunderstood what problem you were trying to solve. Sorry for the noise. Dan On Fri, Sep 13, 2013 at 2:02 PM, Dan Gohman <dan433584 at gmail.com> wrote:> Food for thought: If you have a codebase which can't use -fno-math-errno, > because it relies on errno values from math functions, it may be a more > effective long-term strategy to work on modernizing your codebase, > eliminating the dependencies on errno, rather than going through the > trouble of adding even more complexity to compilers to keep errno support > limping along. > > Of course, whether this actually makes sense for you in your situation > depends on many factors. > > Dan > > > On Thu, Sep 12, 2013 at 5:44 PM, Hal Finkel <hfinkel at anl.gov> wrote: > >> Hello, >> >> Our current handling of -fno-math-errno (and this -ffast-math) in Clang >> is broken on systems for which libm functions do actually set errno. This >> is because, when -fno-math-errno is in effect, libm functions like sqrt, >> sin, cos, etc. are marked as readnone. As a result, these calls can be >> reordered with respect to other calls that set errno, and can clobber errno >> before it can be read. For example: >> >> int fd = open(...); >> if (fd == -1) { >> perror("oops"); >> } >> double f = sqrt(a); >> >> If we're on a system (like Linux, for example), where sqrt might set >> errno to EDOM when a is negative, we can have a problem if some >> optimization rearranges the code to something like this: >> >> int fd = open(...); >> double f = sqrt(a); >> if (fd == -1) { >> perror("oops"); >> } >> >> if the open fails, and a is -2.0, then perror will print the wrong error >> string (thus confusing the user). This is not really a problem with the >> optimization because sqrt was marked as readnone. On the other hand, we >> don't want to tag sqrt and writing to some arbitrary external state >> variable, because this will prevent autovectorization, will prevent CSE >> from collecting duplicate calls to sqrt, and a host of other important >> optimizations. >> >> To fix this problem, I think that we need to stop treating errno as some >> arbitrary external state, and model is explicitly. Functions need to be >> able carry two additional attributes: >> >> 1. 'writes-only-errno' - An attribute to indicate that the function may >> set errno, and that is the only external state to which it might write. >> This is useful because getModRefInfo queries can return more accurate >> answers when comparing to pointers that we know cannot point to errno (such >> as alloca'd memory and functions) [is this allowed at all?]. >> >> 2. 'errno-ignored' - Set when -fno-math-errno is in effect, indicating >> that it is safe to assume that the user does not care about any value of >> errno set by this function. This will allow CSE and autovectorization to >> happen (by modifying those passes to specifically query this attribute). >> >> With these new attributes, the functions are, on systems for which libm >> functions might set errno, not marked readnone or readonly. This will >> prevent unwanted reordering. Thoughts? >> >> Thanks again, >> Hal >> >> -- >> Hal Finkel >> Assistant Computational Scientist >> Leadership Computing Facility >> Argonne National Laboratory >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130913/712979f1/attachment.html>
Krzysztof Parzyszek
2013-Sep-17 19:10 UTC
[LLVMdev] [RFC] New function attributes for errno-setting functions
On 9/12/2013 7:44 PM, Hal Finkel wrote:> > 1. 'writes-only-errno' > 2. 'errno-ignored'Do we really need the first one? We already know which standard functions could potentially set errno, and we know which standard functions don't modify any other storage (other than that which is passed via parameters). I think it's safe to assume that standard functions can be recognized by name, since the standard prohibits user objects to use a predefined name. We could have an attribute like "side-effects-ignored" indicating that whatever modifications the given function makes, nobody will read them (at least not without an intervening store). This would include errno, but could also be used in more general contexts. -K -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Hal Finkel
2013-Sep-17 19:43 UTC
[LLVMdev] [RFC] New function attributes for errno-setting functions
----- Original Message -----> On 9/12/2013 7:44 PM, Hal Finkel wrote: > > > > 1. 'writes-only-errno' > > 2. 'errno-ignored' > > Do we really need the first one? We already know which standard > functions could potentially set errno, and we know which standard > functions don't modify any other storage (other than that which is > passed via parameters). I think it's safe to assume that standard > functions can be recognized by name, since the standard prohibits > user > objects to use a predefined name.I agree that we could put a list into LLVM instead of adding attributes in the frontend. We need to be a little careful that -fno-builtin is passed to the backend in this case.> > We could have an attribute like "side-effects-ignored" indicating > that > whatever modifications the given function makes, nobody will read > them > (at least not without an intervening store). This would include > errno, > but could also be used in more general contexts.That would depend on how this attribute was used; it could only be used by a pass that did actually understand what those side effects were (like the loop vectorizer understanding that, if errno is ignored, then vectorizing cos() is legal). I don't object to making the name generic, but I want to make sure that we're all on the same page regarding what it means. Thanks, Hal> > -K > > > -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, > hosted by The Linux Foundation > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory
Apparently Analagous Threads
- [LLVMdev] [RFC] New function attributes for errno-setting functions
- [LLVMdev] [RFC] New function attributes for errno-setting functions
- [LLVMdev] [RFC] New function attributes for errno-setting functions
- [LLVMdev] [RFC] How to fix sqrt vs llvm.sqrt optimization asymmetry
- [LLVMdev] [RFC] How to fix sqrt vs llvm.sqrt optimization asymmetry