This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PR tree-optimization/64946] Push integer type conversion to ABS_EXPR argument when possible.


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,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]