On Fri, Apr 5, 2013 at 2:40 PM, Joshua Cranmer 🐧 <Pidgeot18 at gmail.com>wrote: ...> Per C and C++, integer division by 0 is undefined. That means, if it > happens, the compiler is free to do whatever it wants. It is perfectly > legal for LLVM to define r to be, say, 42 in this code; it is not required > to preserve the fact that the idiv instruction on x86 and x86-64 will trap.This is quite a conundrum to me. Yes, I agree with you on the C/C++ Standards interpretation. However, the x86-64 expectations are orthogonal. I find that other compilers, including GCC, will trap by default at high optimization levels on x86-64 for this test case. Hardly scientific, but every other compiler on our machines issues a trap. We take safety seriously in our compiler. Our other components go to great lengths not to constant fold an integer division by zero. We would also like LLVM to do the same. Are there others in the community who feel this way? I can envision an option which preserves faults during constant folding. E.g. an integer version of -enable-unsafe-fp-math or gfortran's -ffpe-trap. More accurately, this hypothetical option would suppress the folding of unsafe integer expressions altogether. Would an option such as this benefit the community at large? To be complete, I've also explored the idea of generating a __builtin_trap() call for such expressions before the IR level. However, I have not yet convinced myself that this will generate the same fault as the actual sdiv/udiv instruction would. Things to do. -Cameron -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130405/ddc211b4/attachment.html>
On Apr 5, 2013, at 1:42 PM, Cameron McInally <cameron.mcinally at nyu.edu> wrote:> On Fri, Apr 5, 2013 at 2:40 PM, Joshua Cranmer 🐧 <Pidgeot18 at gmail.com> wrote: > ... > Per C and C++, integer division by 0 is undefined. That means, if it happens, the compiler is free to do whatever it wants. It is perfectly legal for LLVM to define r to be, say, 42 in this code; it is not required to preserve the fact that the idiv instruction on x86 and x86-64 will trap. > > This is quite a conundrum to me. Yes, I agree with you on the C/C++ Standards interpretation. However, the x86-64 expectations are orthogonal. I find that other compilers, including GCC, will trap by default at high optimization levels on x86-64 for this test case. Hardly scientific, but every other compiler on our machines issues a trap. > > We take safety seriously in our compiler. Our other components go to great lengths not to constant fold an integer division by zero. We would also like LLVM to do the same. Are there others in the community who feel this way? > > I can envision an option which preserves faults during constant folding. E.g. an integer version of -enable-unsafe-fp-math or gfortran's -ffpe-trap. More accurately, this hypothetical option would suppress the folding of unsafe integer expressions altogether. Would an option such as this benefit the community at large?Clang's -fsanitize=integer-divide-by-zero option seems to provide what you want. See the Clang User Manual: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation --Owen -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130405/b37d9dd7/attachment.html>
On Fri, Apr 5, 2013 at 5:06 PM, Owen Anderson <resistor at mac.com> wrote: ...> Clang's -fsanitize=integer-divide-by-zero option seems to provide what you > want. See the Clang User Manual: > http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation > >That looks pretty close. I assume there are performance penalties for the runtime checks? I would really like to produce the actual sdiv/udiv instruction and allow the processor to fault on it. That seems like the right fix to me. -Cameron -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130405/da0edf52/attachment.html>
On Fri, Apr 5, 2013 at 1:42 PM, Cameron McInally <cameron.mcinally at nyu.edu>wrote:> This is quite a conundrum to me. Yes, I agree with you on the C/C++ > Standards interpretation. However, the x86-64 expectations are orthogonal. > I find that other compilers, including GCC, will trap by default at high > optimization levels on x86-64 for this test case. Hardly scientific, but > every other compiler on our machines issues a trap. >The platform is irrelevant; division by zero is undefined, and compilers are allowed to optimize as if it can't happen. Both gcc and clang will lift the division out of this loop, for example, causing the hardware trap to happen in the "wrong" place if bar is passed zero: void foo(int x, int y); void bar(int x) { for (int i = 0; i < 100; ++i) { foo(i, 200/x); } } If your program relies on the exact semantics of the 'idiv'/'udiv' hardware instruction, you might want to use an asm volatile statement. -Joe -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130405/9c179cb4/attachment.html>
On Fri, Apr 5, 2013 at 6:49 PM, Joe Groff <arcata at gmail.com> wrote: ... The platform is irrelevant; division by zero is undefined, and compilers> are allowed to optimize as if it can't happen. >Understood. I don't mean to nag, but I'm not arguing which is [more] correct: the Standards or the platform. Both have their own merits. At least to me they both have merits. The choice should be up to the compiler implementor. And, I would like to see LLVM make that choice easy for the compiler implementor. Maybe an anachronism, but there is some history of this option being built-in to other major compilers: GNU, Sun, HP, IBM, SGI, Compaq, etc. But, if others can not (or will not) benefit from this option, I will not force my individual needs on the whole. Both gcc and clang will lift the division out of this loop, for example,> causing the hardware trap to happen in the "wrong" place if bar is passed > zero: > > void foo(int x, int y); > > void bar(int x) { > for (int i = 0; i < 100; ++i) { > foo(i, 200/x); > } > } >I'm less concerned about "where" the trap happens as I am about "if" it happens. For example, a Fortran program with division-by-zero is, by the Standard, non-conforming. Pragmatically, not a Fortran program. Rather than wrong answers, I would like to see a hard error indicating that a program is non-conforming to the Standard. -Cameron>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130405/62181469/attachment.html>