Hi,

In simplify_set we try transforming the paradoxical subreg expression:

  (set FOO (subreg:M (mem:N BAR) 0))

in to:

  (set FOO (zero_extend:M (mem:N BAR)))

However, this code does not consider the case where M is a vector
mode, allowing it to construct (for example):

  (zero_extend:V4SI (mem:SI))

This would clearly have the wrong semantics, but fortunately we fail long
before then in expand_compound_operation. As we really don't want a vector
zero_extend of a scalar value.

We need to explicitly reject vector modes from this transformation.

This fixes a failure I'm seeing on a branch in which I'm trying to
tackle some performance regressions, so I have no live testcase for
this, but it is wrong by observation.

Tested on aarch64-none-elf and bootstrapped on aarch64-none-linux-gnu with
no issues.

OK?

Thanks,
James

---
2017-12-11  James Greenhalgh  <james.greenha...@arm.com>

        * combine.c (simplify_set): Do not transform subregs to zero_extends
        if the destination mode is a vector mode.

diff --git a/gcc/combine.c b/gcc/combine.c
index 786a840..562eae6 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -6962,11 +6962,13 @@ simplify_set (rtx x)
 
   /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this
      would require a paradoxical subreg.  Replace the subreg with a
-     zero_extend to avoid the reload that would otherwise be required.  */
+     zero_extend to avoid the reload that would otherwise be required.
+     Don't do this for vector modes, as the transformation is incorrect.  */
 
   enum rtx_code extend_op;
   if (paradoxical_subreg_p (src)
       && MEM_P (SUBREG_REG (src))
+      && !VECTOR_MODE_P (GET_MODE (src))
       && (extend_op = load_extend_op (GET_MODE (SUBREG_REG (src)))) != UNKNOWN)
     {
       SUBST (SET_SRC (x),

Reply via email to