This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PR tree-optimization/64946] Push integer type conversion to ABS_EXPR argument when possible.
- From: Matthew Wahab <matthew dot wahab at foss dot arm dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 8 Jan 2016 15:53:22 +0000
- Subject: [PR tree-optimization/64946] Push integer type conversion to ABS_EXPR argument when possible.
- Authentication-results: sourceware.org; auth=none
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.
Tested aarch64-none-elf with cross-compiled check-gcc, Also tested
aarch64-none-linux-gnu and x86_64-linux-gnu with native bootstrap and
make check.
Ok for trunk?
Matthew
gcc/
2016-01-07 Matthew Wahab <matthew.wahab@arm.com>
PR tree-optimization/64946
* convert.c (convert_to_integer_1): Push narrowing type
conversions for ABS_EXPR into the argument when possible.
diff --git a/gcc/convert.c b/gcc/convert.c
index 4b1e1f1..95ff1e2 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -852,6 +852,24 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
}
break;
+ case ABS_EXPR:
+ /* Convert (N) abs ((W)x) -> abs ((N)x)
+ if N, W and the type T of x are all signed integer types
+ and the precision of N is >= the precision of T. */
+ {
+ tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
+ tree arg0_type = TREE_TYPE (arg0);
+
+ if (!TYPE_UNSIGNED (type)
+ && !TYPE_UNSIGNED (arg0_type)
+ && outprec >= TYPE_PRECISION (arg0_type))
+ {
+ return fold_build1 (ABS_EXPR, type,
+ convert (type, arg0));
+ }
+ break;
+ }
+
case NEGATE_EXPR:
case BIT_NOT_EXPR:
/* This is not correct for ABS_EXPR,