Patch for RTL expand bug affecting aarch64 vector code.
authorJim Wilson <jim.wilson@linaro.org>
Sat, 13 May 2017 01:32:40 +0000 (01:32 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Sat, 13 May 2017 01:32:40 +0000 (18:32 -0700)
gcc/
PR middle-end/79794
     * expmed.c (extract_bit_field_1): Add alt_rtl argument.  Before
maybe_expand_insn call, set ops[0].target.  If still set after call,
set alt_rtl.  Add extra arg to recursive calls.
(extract_bit_field): Add alt_rtl argument.  Pass to
extract_bit_field.
* expmed.h (extract_bit_field): Fix prototype.
* expr.c (emit_group_load_1, copy_blkmode_from_reg)
(copy_blkmode_to_reg, read_complex_part, store_field): Pass extra NULL
to extract_bit_field_calls.
(expand_expr_real_1): Pass alt_rtl to expand_expr_real instead of 0.
Pass alt_rtl to extract_bit_field calls.
* calls.c (store_unaligned_arguments_into_psuedos)
load_register_parameters): Pass extra NULL to extract_bit_field calls.
* optabs.c (maybe_legitimize_operand): Clear op->target when call
gen_reg_rtx.
* optabs.h (struct expand_operand): Add target bitfield.

From-SVN: r248004

gcc/ChangeLog
gcc/calls.c
gcc/expmed.c
gcc/expmed.h
gcc/expr.c
gcc/optabs.c
gcc/optabs.h

index 1e14b0397d70dd836f53f275993834c518b31467..b58aacf9b53845a38fb40c76b042d62b0fb199ff 100644 (file)
@@ -1,3 +1,23 @@
+2017-05-12  Jim Wilson  <jim.wilson@linaro.org>
+
+       PR middle-end/79794
+       * expmed.c (extract_bit_field_1): Add alt_rtl argument.  Before
+       maybe_expand_insn call, set ops[0].target.  If still set after call,
+       set alt_rtl.  Add extra arg to recursive calls.
+       (extract_bit_field): Add alt_rtl argument.  Pass to
+       extract_bit_field.
+       * expmed.h (extract_bit_field): Fix prototype.
+       * expr.c (emit_group_load_1, copy_blkmode_from_reg)
+       (copy_blkmode_to_reg, read_complex_part, store_field): Pass extra NULL
+       to extract_bit_field_calls.
+       (expand_expr_real_1): Pass alt_rtl to expand_expr_real instead of 0.
+       Pass alt_rtl to extract_bit_field calls.
+       * calls.c (store_unaligned_arguments_into_psuedos)
+       load_register_parameters): Pass extra NULL to extract_bit_field calls.
+       * optabs.c (maybe_legitimize_operand): Clear op->target when call
+       gen_reg_rtx.
+       * optabs.h (struct expand_operand): Add target bitfield.
+
 2017-05-12  Uros Bizjak  <ubizjak@gmail.com>
 
        * compare-elim.c (try_eliminate_compare): Canonicalize
index bd081ccf46c3a3c5e6dab72bca1156ba4767b2f0..91a4466b00bec4f514344b80aacbe0ca30aac8fe 100644 (file)
@@ -1164,7 +1164,7 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
 
            args[i].aligned_regs[j] = reg;
            word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
-                                     word_mode, word_mode, false);
+                                     word_mode, word_mode, false, NULL);
 
            /* There is no need to restrict this code to loading items
               in TYPE_ALIGN sized hunks.  The bitfield instructions can
@@ -2557,7 +2557,8 @@ load_register_parameters (struct arg_data *args, int num_actuals,
                  unsigned int bitoff = (nregs - 1) * BITS_PER_WORD;
                  unsigned int bitsize = size * BITS_PER_UNIT - bitoff;
                  rtx x = extract_bit_field (mem, bitsize, bitoff, 1, dest,
-                                            word_mode, word_mode, false);
+                                            word_mode, word_mode, false,
+                                            NULL);
                  if (BYTES_BIG_ENDIAN)
                    x = expand_shift (LSHIFT_EXPR, word_mode, x,
                                      BITS_PER_WORD - bitsize, dest, 1);
index c0260c53853cda4deffca4ca4cdd9c825e023aef..0c812806f9bfbf5eb75842345c3580de8aadc668 100644 (file)
@@ -1534,7 +1534,7 @@ static rtx
 extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
                     unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
                     machine_mode mode, machine_mode tmode,
-                    bool reverse, bool fallback_p)
+                    bool reverse, bool fallback_p, rtx *alt_rtl)
 {
   rtx op0 = str_rtx;
   machine_mode int_mode;
@@ -1610,10 +1610,13 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       unsigned HOST_WIDE_INT pos = bitnum / GET_MODE_BITSIZE (innermode);
 
       create_output_operand (&ops[0], target, innermode);
+      ops[0].target = 1;
       create_input_operand (&ops[1], op0, outermode);
       create_integer_operand (&ops[2], pos);
       if (maybe_expand_insn (icode, 3, ops))
        {
+         if (alt_rtl && ops[0].target)
+           *alt_rtl = target;
          target = ops[0].value;
          if (GET_MODE (target) != mode)
            return gen_lowpart (tmode, target);
@@ -1735,7 +1738,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
            = extract_bit_field_1 (op0, MIN (BITS_PER_WORD,
                                             bitsize - i * BITS_PER_WORD),
                                   bitnum + bit_offset, 1, target_part,
-                                  mode, word_mode, reverse, fallback_p);
+                                  mode, word_mode, reverse, fallback_p, NULL);
 
          gcc_assert (target_part);
          if (!result_part)
@@ -1838,7 +1841,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
          xop0 = copy_to_reg (xop0);
          rtx result = extract_bit_field_1 (xop0, bitsize, bitpos,
                                            unsignedp, target,
-                                           mode, tmode, reverse, false);
+                                           mode, tmode, reverse, false, NULL);
          if (result)
            return result;
          delete_insns_since (last);
@@ -1894,7 +1897,8 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 rtx
 extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
                   unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
-                  machine_mode mode, machine_mode tmode, bool reverse)
+                  machine_mode mode, machine_mode tmode, bool reverse,
+                  rtx *alt_rtl)
 {
   machine_mode mode1;
 
@@ -1929,7 +1933,7 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
     }
 
   return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp,
-                             target, mode, tmode, reverse, true);
+                             target, mode, tmode, reverse, true, alt_rtl);
 }
 \f
 /* Use shifts and boolean operations to extract a field of BITSIZE bits
index db1ce00c3f7c60a86536ddd5aa1e4bf2ce1fbdd8..64476c3b4b2ff55c97a98e9bb6b9a6e501c3ca12 100644 (file)
@@ -725,7 +725,7 @@ extern void store_bit_field (rtx, unsigned HOST_WIDE_INT,
                             machine_mode, rtx, bool);
 extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT,
                              unsigned HOST_WIDE_INT, int, rtx,
-                             machine_mode, machine_mode, bool);
+                             machine_mode, machine_mode, bool, rtx *);
 extern rtx extract_low_bits (machine_mode, machine_mode, rtx);
 extern rtx expand_mult (machine_mode, rtx, rtx, rtx, int);
 extern rtx expand_mult_highpart_adjust (machine_mode, rtx, rtx, rtx, rtx, int);
index 4749cc508b88600d880ce9ed130a1e58cf60e97b..5febf07929d0add0ad0ae1356baef008524f0c7c 100644 (file)
@@ -2192,7 +2192,8 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
                      && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)))
                tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
                                             subpos * BITS_PER_UNIT,
-                                            1, NULL_RTX, mode, mode, false);
+                                            1, NULL_RTX, mode, mode, false,
+                                            NULL);
            }
          else
            {
@@ -2202,7 +2203,8 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
              mem = assign_stack_temp (GET_MODE (src), slen);
              emit_move_insn (mem, src);
              tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
-                                          0, 1, NULL_RTX, mode, mode, false);
+                                          0, 1, NULL_RTX, mode, mode, false,
+                                          NULL);
            }
        }
       /* FIXME: A SIMD parallel will eventually lead to a subreg of a
@@ -2245,7 +2247,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
       else
        tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
                                     bytepos * BITS_PER_UNIT, 1, NULL_RTX,
-                                    mode, mode, false);
+                                    mode, mode, false, NULL);
 
       if (shift)
        tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
@@ -2697,7 +2699,7 @@ copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
                       extract_bit_field (src, bitsize,
                                          xbitpos % BITS_PER_WORD, 1,
                                          NULL_RTX, copy_mode, copy_mode,
-                                         false),
+                                         false, NULL),
                       false);
     }
 }
@@ -2776,7 +2778,7 @@ copy_blkmode_to_reg (machine_mode mode, tree src)
                       extract_bit_field (src_word, bitsize,
                                          bitpos % BITS_PER_WORD, 1,
                                          NULL_RTX, word_mode, word_mode,
-                                         false),
+                                         false, NULL),
                       false);
     }
 
@@ -3225,7 +3227,7 @@ read_complex_part (rtx cplx, bool imag_p)
     }
 
   return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
-                           true, NULL_RTX, imode, imode, false);
+                           true, NULL_RTX, imode, imode, false, NULL);
 }
 \f
 /* A subroutine of emit_move_insn_1.  Yet another lowpart generator.
@@ -6911,7 +6913,7 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
        {
          machine_mode temp_mode = smallest_mode_for_size (bitsize, MODE_INT);
          temp = extract_bit_field (temp, bitsize, 0, 1, NULL_RTX, temp_mode,
-                                   temp_mode, false);
+                                   temp_mode, false, NULL);
        }
 
       /* Store the value in the bitfield.  */
@@ -9780,7 +9782,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
            case GIMPLE_SINGLE_RHS:
              {
                r = expand_expr_real (gimple_assign_rhs1 (g), target,
-                                     tmode, modifier, NULL, inner_reference_p);
+                                     tmode, modifier, alt_rtl,
+                                     inner_reference_p);
                break;
              }
            default:
@@ -10210,7 +10213,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
                                        0, TYPE_UNSIGNED (TREE_TYPE (exp)),
                                        (modifier == EXPAND_STACK_PARM
                                         ? NULL_RTX : target),
-                                       mode, mode, false);
+                                       mode, mode, false, alt_rtl);
          }
        if (reverse
            && modifier != EXPAND_MEMORY
@@ -10707,7 +10710,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
            op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
                                     (modifier == EXPAND_STACK_PARM
                                      ? NULL_RTX : target),
-                                    ext_mode, ext_mode, reversep);
+                                    ext_mode, ext_mode, reversep, alt_rtl);
 
            /* If the result has a record type and the mode of OP0 is an
               integral mode then, if BITSIZE is narrower than this mode
@@ -10928,7 +10931,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
       else if (reduce_bit_field)
        return extract_bit_field (op0, TYPE_PRECISION (type), 0,
                                  TYPE_UNSIGNED (type), NULL_RTX,
-                                 mode, mode, false);
+                                 mode, mode, false, NULL);
       /* As a last resort, spill op0 to memory, and reload it in a
         different mode.  */
       else if (!MEM_P (op0))
index 48e37f8bb40fe717487b36c11707da2c4652d20c..b69e75943cc99d6c5792ae2f151f5343d2bdbc1a 100644 (file)
@@ -6962,6 +6962,7 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
        return true;
 
       op->value = gen_reg_rtx (mode);
+      op->target = 0;
       break;
 
     case EXPAND_INPUT:
index b2dd31acd068c089c0fec4d8909882cdc3e83fe2..728b866f08db01de2cc330ad29088ab252f4d3ad 100644 (file)
@@ -48,8 +48,11 @@ struct expand_operand {
      rather than signed.  Only meaningful for certain types.  */
   unsigned int unsigned_p : 1;
 
+  /* Is the target operand.  */
+  unsigned int target : 1;
+
   /* Unused; available for future use.  */
-  unsigned int unused : 7;
+  unsigned int unused : 6;
 
   /* The mode passed to the convert_*_operand function.  It has a
      type-dependent meaning.  */