Fix regression caused by PR target/93932 backport.

When I back ported the fix for PR target/93932 to the GCC 9 branch, I put in an
unintended regression when the GCC compiler is optimizing the vec_extract
built-in function, and the vector element is in memory, and the index is
variable.  This patch masks the vector index so that it does not go out of
bounds.

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

        PR target/94557
        * config/rs6000/rs6000.c (rs6000_adjust_vec_address): Fix
        regression caused by PR target/93932 backport.  Mask variable
        vector extract index so it does not go beyond the vector when
        extracting a vector element from memory.

--- /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;
        }

--- /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