OpenCL shift on short/char types

Hello,

OpenCL defines shifts so the requested shift size is masked.

I’m looking at the IR generated by clang for shifts in OpenCL, and had a question.

For int shifts, clang creates a mask and does the shift on the mask of the requested shift, like so:

%shr.mask = and i32 %b, 31

%shr = lshr i32 %a, %shr.mask

This is basically what I would expect.

For shifts on shorts/chars:

uchar

s(uchar a, uchar b) {

return a >> b;

}

Clang generates:

define zeroext i8 @s(i8 zeroext %a, i8 zeroext %b) #0 {

entry:

%conv = zext i8 %a to i32

%conv1 = zext i8 %b to i32

%shr.mask = and i32 %conv1, 31

%shr = lshr i32 %conv, %shr.mask

%conv2 = trunc i32 %shr to i8

ret i8 %conv2

}

I expected the mask in this case to be done “and 7” rather than “and 31”.

Is this a bug in clang, or is my expectation/understanding wrong?

Thanks!

Pete

Hello,

OpenCL defines shifts so the requested shift size is masked.

I’m looking at the IR generated by clang for shifts in OpenCL, and had a
question.

For int shifts, clang creates a mask and does the shift on the mask of the
requested shift, like so:

  %shr.mask = and i32 %b, 31

  %shr = lshr i32 %a, %shr.mask

This is basically what I would expect.

For shifts on shorts/chars:

uchar

s(uchar a, uchar b) {

  return a >> b;

}

Clang generates:

define zeroext i8 @s(i8 zeroext %a, i8 zeroext %b) #0 {

entry:

  %conv = zext i8 %a to i32

  %conv1 = zext i8 %b to i32

  %shr.mask = and i32 %conv1, 31

  %shr = lshr i32 %conv, %shr.mask

  %conv2 = trunc i32 %shr to i8

  ret i8 %conv2

}

I expected the mask in this case to be done “and 7” rather than “and 31”.

Is this a bug in clang, or is my expectation/understanding wrong?

Thanks!

It isn't possible, in C, to shift around types whose rank is smaller than
'int'. The operands will be promoted to int and the shift operation will
apply to the promoted values.

Hello David,

Thanks for your answer here.

This point is clarified in the current OpenCL spec (I’m not sure what version I was looking at originally).

Thanks!

Pete