www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - ldc doesn't elide bounds check

reply Kagamin <spam here.lot> writes:
void f(byte[] a, byte[] b)
{
	if(a.length<b.length)b=b[0..a.length];
	foreach(i,c;b)
	{
		a[i]=c;
		if(c==10)break;
	}
}
void g(ulong a, ulong b)
{
	if(a<b)b=a;
	foreach(i;0..b)
	{
		assert(i<=a);
		if(i==10)break;
	}
}

In the function f the code for assert failure is retained, but in 
the function g it disappears at optimization levels -Os and 
above. Is it just me is there some limit for the optimizer?
Mar 05 2018
next sibling parent Kagamin <spam here.lot> writes:
Ah, I see, for assert(i<a); the failure handler is retained 
again, but I wonder why.
Mar 05 2018
prev sibling parent reply kinke <noone nowhere.com> writes:
On Monday, 5 March 2018 at 19:36:20 UTC, Kagamin wrote:
 void f(byte[] a, byte[] b)
 {
 	if(a.length<b.length)b=b[0..a.length];
 	foreach(i,c;b)
 	{
 		a[i]=c;
 		if(c==10)break;
 	}
 }
 void g(ulong a, ulong b)
 {
 	if(a<b)b=a;
 	foreach(i;0..b)
 	{
 		assert(i<=a);
 		if(i==10)break;
 	}
 }

 In the function f the code for assert failure is retained, but 
 in the function g it disappears at optimization levels -Os and 
 above. Is it just me is there some limit for the optimizer?
Thx for noticing; I filed an LDC issue about it (https://github.com/ldc-developers/ldc/issues/2607), although gcc and clang are also unable to optimize away these checks for analogous C code: https://godbolt.org/g/AfyMJM
Mar 07 2018
parent Kagamin <spam here.lot> writes:
It's probably related to wrapping. If you iterate with step n and 
limit m and m is big enough, at some point i+n>m.max and will 
wrap, and the cycle will continue. The optimizer might check that 
it can't happen, but apparently doesn't.
Mar 25 2019