Restrict for values that are not parameters

I cannot get Clang to add noalias via a cast operation. This code does not produce any warnings, and I believe it’s legal, but the restrict qualifier is lost. Am I incorrect about this code being legal? Any idea why the qualifier is stripped? (It is a contrived example. You could imagine address checking and two separate loops.)

#define NOALIAS __restrict

//#define NOALIAS attribute((noalias))

void move(

int* velocity_x, int* velocity_y, int* velocity_z,

int* position_x,int* position_y,int* position_z,

int* acceleration_x, int* acceleration_y, int* acceleration_z,

int time_step,

int count,

int stride )

{

{

int* NOALIAS r_acceleration_x = (int* NOALIAS)acceleration_x;

int* NOALIAS r_velocity_x = (int* NOALIAS)velocity_x;

int* NOALIAS r_position_x = (int* NOALIAS)position_x;

int* NOALIAS r_acceleration_y = (int* NOALIAS)acceleration_y;

int* NOALIAS r_velocity_y = (int* NOALIAS)velocity_y;

int* NOALIAS r_position_y = (int* NOALIAS)position_y;

int* NOALIAS r_acceleration_z = (int* NOALIAS)acceleration_z;

int* NOALIAS r_velocity_z = (int* NOALIAS)velocity_z;

int* NOALIAS r_position_z = (int* NOALIAS)position_z;

for (int i=0;i<count*stride;i+=stride)

{

r_velocity_x[i] += r_acceleration_x[i] * time_step;

r_velocity_y[i] += r_acceleration_y[i] * time_step;

r_velocity_z[i] += r_acceleration_z[i] * time_step;

r_position_x[i] += r_velocity_x[i] * time_step;

r_position_y[i] += r_velocity_y[i] * time_step;

r_position_z[i] += r_velocity_z[i] * time_step;

}

}

}

I cannot get Clang to add noalias via a cast operation. This code does
not produce any warnings, and I believe it’s legal, but the restrict
qualifier is lost. Am I incorrect about this code being legal? Any idea
why the qualifier is stripped? (It is a contrived example. You could
imagine address checking and two separate loops.)

We have no way to model this use of 'restrict' in our IR. Putting the
'restrict' on a function parameter should work. If you have an address
checks and two separate loops, you could try factoring the 'noalias' loop
out to a separate function.

#define NOALIAS __restrict

//#define NOALIAS __attribute__((noalias))

void move(

    int* velocity_x, int* velocity_y, int* velocity_z,

    int* position_x,int* position_y,int* position_z,

    int* acceleration_x, int* acceleration_y, int* acceleration_z,

    int time_step,

    int count,

    int stride )

{

    {

        int* NOALIAS r_acceleration_x = (int* NOALIAS)acceleration_x;

The cast on the right-hand side does nothing; per C11 6.7.3/4, "The
properties associated with qualified types are meaningful only for
expressions that are lvalues."

         int* NOALIAS r_velocity_x = (int* NOALIAS)velocity_x;

From: "Richard Smith" <richard@metafoo.co.uk>
To: "Mark Schimmel" <Mark.Schimmel@synopsys.com>
Cc: cfe-dev@cs.uiuc.edu
Sent: Friday, March 6, 2015 8:21:26 PM
Subject: Re: [cfe-dev] Restrict for values that are not parameters

I cannot get Clang to add noalias via a cast operation. This code
does not produce any warnings, and I believe it’s legal, but the
restrict qualifier is lost. Am I incorrect about this code being
legal? Any idea why the qualifier is stripped? (It is a contrived
example. You could imagine address checking and two separate loops.)

We have no way to model this use of 'restrict' in our IR. Putting the
'restrict' on a function parameter should work. If you have an
address checks and two separate loops, you could try factoring the
'noalias' loop out to a separate function.

To this I'll add that the necessary IR extensions for this have already been discussed on the llvmdev list (see this thread for the details: http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-November/078786.html), and I'm planning to implement them this month. So we should have better support for this soon.

-Hal