[LLVMdev] Proposal: add intrinsics for safe division

Philip Reames listmail at philipreames.com
Fri May 2 17:01:22 PDT 2014


On 05/02/2014 04:46 PM, Andrew Trick wrote:
>
> On May 2, 2014, at 4:25 PM, Philip Reames <listmail at philipreames.com 
> <mailto:listmail at philipreames.com>> wrote:
>
>>
>> I'm still not happy with hiding the explicit control flow, but I can 
>> achieve the same effect as:
>> if( div by zero ) throw
>> (r, o, d) = safe.div(a,b);
>> if( o ) {
>>   r = a;
>> }
>>
>> i.e. emit a separate guard branch for the interesting condition and 
>> not utilize the value from the safe div.
>
> Oh, I was just assuming you would deopt on either div-by-zero or 
> overflow in order to optimize the common case.
>
> So, the point of safe.div is that you don’t need control flow in the 
> IR except to indicate the throw.
>
> (r, o, d) = safe.div(a,b)
> if (d) { patchpoint(throw, state) }
>
> You could also explicitly check div-by-zero but it would be harder to 
> fold away that extra check during lowering.
I think I may have worded this badly.  The motivation for the explicit 
guard is to enable LICM and other branch simplifications. This point is 
completely separate from the choice to deopt or not.

Consider the example below.  This is specifically for x86 with it's 
trapping divide.  Assume I am not utilizing traps, but need to guard the 
divide to handle the two special cases.  The exact handling of the edge 
cases isn't really significant, but the guards must exist.

Given:
void foo(int[] a, int d) {
   for i = 0....a.length {
     a[i] = a[i]/d
   }
}

I want:
void foo(int[]a, int d) {
   // A single check here, not one per iteration
   if( a.length > 0 && d == 0 ) throw;
   for i = 0...a.length {
     // arguably, it might be better to split the loop for d == -1
     if( a[i] == INT_MIN && d == -1 ) {
        continue;
     }
     a[i] = x86_div(a[i], d);
   }
}

Not:
void foo(int[]a, int d) {

   for i = 0...a.length {
     if( a[i] == INT_MIN && d == -1 ) {
        continue;
     }
     if( d == 0 ) throw;
     a[i] = x86_div(a[i], d);
   }
}

Hopefully, this helps clarify my point.

Philip

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140502/8b1637e0/attachment.html>


More information about the llvm-dev mailing list