I think I did not make it clear. If GCC defines that passing 128 to a char value makes it the wrapping result -128, then the conversion from (char) abs ((int) char_val) to abs (char_val) is safe if we can guarantee abs (char(-128)) = -128 also. Then the subsequent methods used to get abs() should also guarantee wrapping on overflow. Shift-xor-sub is OK, but max(x, -x) is OK only if the result of the negation operation on -128 is also -128 (wrapping). I think that is right the behavior of SSE2 operation PSUBB ([0,...,0], [x,...,x]), as PSUBB can operate both signed/unsigned operands.
thanks, Cong On Wed, Oct 23, 2013 at 9:40 PM, Cong Hou <co...@google.com> wrote: > On Wed, Oct 23, 2013 at 8:52 AM, Joseph S. Myers > <jos...@codesourcery.com> wrote: >> On Tue, 22 Oct 2013, Cong Hou wrote: >> >>> For abs(char/short), type conversions are needed as the current abs() >>> function/operation does not accept argument of char/short type. >>> Therefore when we want to get the absolute value of a char_val using >>> abs (char_val), it will be converted into abs ((int) char_val). It >>> then can be vectorized, but the generated code is not efficient as >>> lots of packings and unpackings are envolved. But if we convert >>> (char) abs ((int) char_val) to abs (char_val), the vectorizer will be >>> able to generate better code. Same for short. >> >> ABS_EXPR has undefined overflow behavior. Thus, abs ((int) -128) is >> defined (and we also define the subsequent conversion of +128 to signed >> char, which ISO C makes implementation-defined not undefined), and >> converting to an ABS_EXPR on char would wrongly make it undefined. For >> such a transformation to be valid (in the absence of VRP saying that -128 >> isn't a possible value) you'd need a GIMPLE representation for >> ABS_EXPR<overflow:wrap>, as distinct from ABS_EXPR<overflow:undefined>. >> You don't have the option there is for some arithmetic operations of >> converting to a corresponding operation on unsigned types. >> > > Yes, you are right. The method I use can guarantee wrapping on > overflow (either shift-xor-sub or max(x, -x)). Can I just add the > condition if (flag_wrapv) before the conversion I made to prevent the > undefined behavior on overflow? > > Thank you! > > Cong > > >> -- >> Joseph S. Myers >> jos...@codesourcery.com