On 08/01/16 22:24, Joseph Myers wrote:
On Fri, 8 Jan 2016, Matthew Wahab wrote:

Hello,

The C/C++ front-ends apply type conversions to expressions using ABS
with integral arguments of type smaller than int. This means that, for
short x, ABS(x) becomes something like (short)ABS((int)x)). When the
argument is the result of memory access, this restricts the vectorizer
apparently because the alignment of the operation doesn't match the
alignment of the memory access. This causes two failures in
gcc.target/aarch64/vec-abs-compile.c where the expected abs instructions
aren't generated.

This patch adds a case to convert_to_integer_1 to push the integer type
conversions applied to an ABS expression into the argument, when it is
safe to do so. This fixes the failing test cases.

Note that, for example, (int) labs (INT_MIN) is well-defined if long is
wider than int (in GNU C, where conversion of out-of-range values to
signed types is well-defined).  But abs (INT_MIN) is undefined.  That is,
such transformations can never be safe unless the minimum value of the
type of the ABS_EXPR argument is not a possible value of the contained
expression.

The case I'm trying to fix has (short)abs((int)short_var). I'd thought that if
abs(short_var) was undefined because the result couldn't be represented then 
the type
conversion from int to short would also be undefined. In fact, it's 
implementation
defined and S4.5 of the GCC manual says that the value is reduced until it can 
be
represented. So (short)abs((int)short_var) will produce a value when abs(short_var) is undefined meaning this transformation isn't correct. I'll drop this patch.

Thanks,
Matthew

What's your definition of safe?  I'd expect a patch like this to contain
lots of testcases verifying that the transformation occurs in cases where
it's OK, but that (int) labs (int_var) does not end up with an ABS_EXPR on
type int (for example) (in the absence of a guarantee that said ABS_EXPR
will return INT_MIN for an argument of INT_MIN - which might be the case
for -fwrapv, but can't be otherwise because *_nonnegative*_p assume
ABS_EXPR always produces a nonnegative result).


Reply via email to