Call to fract causing crash

This may well be a bug in the implementation I’m using, but I wanted to check if this is sound code.

In my kernel I have the following lines:


float func (float4 p) {
    float4 ip, fp;
    fp = fract(p, &ip);
    [rest of function snipped....]

This compiles fine, but at runtime (on the CPU under snow leopard) produces a <EXC_BAD_ACCESS> error. Am I doing something wrong here? Have I mis-interpretted how to use that function?

Removing the call to fract cures the problem.

Ok, forget that. It’s not the call to fract, but something else. I think the optimiser must be playing tricks with me as I was putting printf’s in before/after that call. As I could only see the ones before I assumed it was that line. Seems like some instruction re-ordering is going on.

I’m now in the process of, having stripped everything out of this function, slowly reintroducing code a line at a time.

Ok, just to close this, I found my problem.

Once I’d gotten the integer part of my vector with fract I cast it to an int4


float4 fp,ip;
fp = fract(p, &ip);
int4 idx = (int4) ip;

I then used the components of idx to index into an array. The problem is that that cast is illegal according to the spec, but Snow Leopard allows it (at least when targeting the CPU) and what it does is copy the float vector into the int vector with no float->int conversion. The result is that index becomes huge, and I overflowed my arrays in a big way.

When I removed the call to fract, I replaced it with zero. Floating point zero == integer zero, so there was no problem.

Hopefully this might stop somebody else doing the same. Nasty one to track down. Thank god for printf.