Hi Cameron, On 07/04/13 19:42, Cameron McInally wrote:> On Sun, Apr 7, 2013 at 1:23 PM, Duncan Sands <baldrick at free.fr > <mailto:baldrick at free.fr>> wrote: > ... > > If you want a trap you are going to have to (IMO) output IR > instructions rather than a constant expression. For example you can output the > equivalent of > if (x == 0) > llvm.trap() // or maybe some special trap routine > y = whatever/x > ... use y ... > rather than the constant expression "whatever/x". If the optimizers can prove > that x is never zero then this will be sunk back into a constant expression (if > "whatever" is a constant expression). > > > Ah, that's super interesting. I'll have to give it some more thought. Thanks for > this, Duncan. > > My knee-jerk reaction is that emulating hardware behaviour in software should be > avoided. At least in this specific case.I reckon it shouldn't be too hard to teach the code generators to turn this IR sequence into "y = target-divide whatever/x" on targets for which dividing by 0 traps in a satisfactory way, so it turns into something efficient. Ciao, Duncan.
On Apr 8, 2013 8:42 AM, "Duncan Sands" <baldrick at free.fr> wrote:> > Hi Cameron, > > > On 07/04/13 19:42, Cameron McInally wrote: >> >> On Sun, Apr 7, 2013 at 1:23 PM, Duncan Sands <baldrick at free.fr >> <mailto:baldrick at free.fr>> wrote: >> ... >> >> If you want a trap you are going to have to (IMO) output IR >> instructions rather than a constant expression. For example you canoutput the>> equivalent of >> if (x == 0) >> llvm.trap() // or maybe some special trap routine >> y = whatever/x >> ... use y ... >> rather than the constant expression "whatever/x". If the optimizerscan prove>> that x is never zero then this will be sunk back into a constantexpression (if>> "whatever" is a constant expression). >> >> >> Ah, that's super interesting. I'll have to give it some more thought.Thanks for>> this, Duncan. >> >> My knee-jerk reaction is that emulating hardware behaviour in softwareshould be>> avoided. At least in this specific case. > > > I reckon it shouldn't be too hard to teach the code generators to turnthis IR> sequence into "y = target-divide whatever/x" on targets for whichdividing by 0> traps in a satisfactory way, so it turns into something efficient. >If the application is safety related, then the if (x == 0) should be there in the source code anyway. If it happens to be able to optimize it into the div instruction at target lowering, then it could do it then. If a target cpu does not do the div trap then the target lowering would at least maintain the safety at the expense of an extra branch. James. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130408/69314498/attachment.html>
Hey Duncan, On Mon, Apr 8, 2013 at 3:39 AM, Duncan Sands <baldrick at free.fr> wrote: ...> I reckon it shouldn't be too hard to teach the code generators to turn > this IR > sequence into "y = target-divide whatever/x" on targets for which dividing > by 0 > traps in a satisfactory way, so it turns into something efficient. >I was just writing Chandler about a similar implementation. With my current understanding of the problem, my constant division will end up as either a trap call or a load of an undefined value in the IR, depending on what the FE chooses to do. It's not clear to me, at least with my current knowledge of LLVM, how to recreate the actual division instruction in the target backend from that information (trap or undefined value). Hopefully there is a way. ;) Thanks again, Duncan. -Cameron -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130408/f0a190d8/attachment.html>
Hey again, I have a nagging thought that my past comments may not have enough meat to them. So... On Mon, Apr 8, 2013 at 12:01 PM, Cameron McInally <cameron.mcinally at nyu.edu>wrote: ...> I was just writing Chandler about a similar implementation. With my > current understanding of the problem, my constant division will end up as > either a trap call or a load of an undefined value in the IR, depending on > what the FE chooses to do. It's not clear to me, at least with my current > knowledge of LLVM, how to recreate the actual division instruction in the > target backend from that information (trap or undefined value). Hopefully > there is a way. ;) >I've tried my little test case with an unmodified Clang and -fsanitize=integer-divide-by-zero. After LLVM runs the Function Integration/Inlining Pass, I end up with this IR: *** IR Dump Before Deduce function attributes *** define i32 @main() #0 { entry: call void @__ubsan_handle_divrem_overflow(i8* bitcast ({ { i8*, i32, i32 }, { i16, i16, [6 x i8] }* }* @2 to i8*), i64 6, i64 0) #3 %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str, i64 0, i64 0), i32 undef) #3 ret i32 0 } The problem I'm facing is how to safely convert this __ubsan_handle_divrem_overflow call back to the actual integer division in the target backend. Is it possible and I'm missing it? Any insight would be warmly welcomed. On a related note, this investigation into Clang has proven insightful. My compiler's usage of LLVM differs from Clang's in many ways. So, it could be that the issues I face are peculiar to my compiler. Without delving, my input LLVM IR is heavily optimized. -Cameron -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130408/e0848c6c/attachment.html>