> Dorit Nuzman wrote:
>> Paul Schlie wrote:
>> ((char)x) = ((char)( ((int)((char)x)) << ((int)c) ) ) ::
>> ((char)x) = ((char)(       ((char)x)  << ((int)c) ) )
>>
>> if the shift count ((int)c) is semantically preserved.
>>
>> thereby conditionally shifting left ((char)x) by ((int)c) if c
>> is less than the smaller of it's shifted operand's or target's
>> precision (both being char in this instance) or otherwise
>> returning 0; is semantically equivalent and typically more
>> efficient on smaller lightly pipelined machines without
>> needing to literally promote the shifted operand to int width.
>
> Something along these lines may be useful to do in the vectorizer
> when we get code like this:
>      > ((char)x) = ((char)( ((int)((char)x)) << ((int)c) ) )
> and don't feel like doing all the unpacking of chars to ints and
> then packing the ints to chars after the shift. An alternative could
> be to transform the above pattern to:
>      char_x1 = 0
>      char_x2 = char_x << c
>      char_x = ((int)c < size_of_char) ? char_x2 : char_x1
> and vectorize that (since we already know how to vectorize selects).

Seems reasonable to me; and may analogously be further potentially
generalized to allow vectorizable operands specified as being wider
than the expression's target precision requirement to be reduced in
precision themselves. i.e. (presuming unsigned char):

(char)x = (unsigned)y + (unsigned)( ((int)z)<<((unsigned)n) );

=>

(char)x = (char)y + (n<sizeof(char))? ((char)z)<<((char)n) : 0;



Reply via email to