This patch fixes PR target/94557, on PowerPC.  It was a regression on the GCC 9
branch caused by my recent patch for PR target/93932.

The patch for 93932 was a back port from the master branch of a fix for the
vec_extract built-in function.  This patch fixes the case where we are
optimizing a vector extract from an vector in memory to be a scalar load
instead of loading the vector to a register and then doing an extract.  In the
tests that fail, the index for the vector extract built-in function goes
outside of the bounds of the vector.

In the master branch, I had made a previous change to limit the variable
extraction to be valid via masking.  I had done this as part of optimizing
vector extracts for PC-relative addresses.  When I back ported the fix for PR
target/93932, I did not include this masking.  I had originally only tested the
fix for PR target/93932 on a little endian power8 system.  The test cases that
fail do not fail on a little endian power8 system, but they would fail on a
little endian power9 system and also a big endian power8 system.

This patch adds in the masking of the vector index that is in the master
branch.  I re-implemented the change for GCC 9, since the changes on the master
branch are more extensive, and include PC-relative support that is not in GCC
9.

I have tested this patch via compiler bootstrap and running the make check
options on the following systems.  There were no regressions in the run, and
several of the tests that started to fail with my last patch are now fixed.
Can I check this into the GCC 9 branch?

        little endian power8 running Linux
        little endian power9 running Linux
        big endian power8 running Linux

2020-04-13  Michael Meissner  <meiss...@linux.ibm.com>

        PR target/94557
        * config/rs6000/rs6000.c (rs6000_adjust_vec_address): Mask
        variable vector extract index so it does not go beyond the vector
        when extracting a vector element from memory.  This change is a
        simplification of the 2020-02-03 patch that went into the trunk.

--- /tmp/4XFFqK_rs6000.c        2020-04-13 15:28:33.514011024 -0500
+++ gcc/config/rs6000/rs6000.c  2020-04-13 14:24:01.296932921 -0500
@@ -7047,18 +7047,25 @@ rs6000_adjust_vec_address (rtx scalar_re
     element_offset = GEN_INT (INTVAL (element) * scalar_size);
   else
     {
+      /* Mask the element to make sure the element number is between 0 and the
+        maximum number of elements - 1 so that we don't generate an address
+        outside the vector.  */
+      rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (GET_MODE (mem)) - 1);
+      rtx and_op = gen_rtx_AND (Pmode, element, num_ele_m1);
+      emit_insn (gen_rtx_SET (base_tmp, and_op));
+
       int byte_shift = exact_log2 (scalar_size);
       gcc_assert (byte_shift >= 0);
 
       if (byte_shift == 0)
-       element_offset = element;
+       element_offset = base_tmp;
 
       else
        {
          if (TARGET_POWERPC64)
-           emit_insn (gen_ashldi3 (base_tmp, element, GEN_INT (byte_shift)));
+           emit_insn (gen_ashldi3 (base_tmp, base_tmp, GEN_INT (byte_shift)));
          else
-           emit_insn (gen_ashlsi3 (base_tmp, element, GEN_INT (byte_shift)));
+           emit_insn (gen_ashlsi3 (base_tmp, base_tmp, GEN_INT (byte_shift)));
 
          element_offset = base_tmp;
        }


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797

Reply via email to