poly_int: find_bswap_or_nop_load
authorRichard Sandiford <richard.sandiford@linaro.org>
Thu, 21 Dec 2017 07:02:06 +0000 (07:02 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 21 Dec 2017 07:02:06 +0000 (07:02 +0000)
This patch handles polynomial offsets in find_bswap_or_nop_load,
which could be useful for constant-sized data at a variable offset.
It is needed for a later patch to compile.

2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* gimple-ssa-stor-merging.c (find_bswap_or_nop_load): Track polynomial
offsets for MEM_REFs.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255929

gcc/ChangeLog
gcc/gimple-ssa-store-merging.c

index 08052356f09b5c128bf1f3d3f3467bc146b6299b..58da0852dde4e6a71f14abf34d9c3af0d90a2ce6 100644 (file)
@@ -1,3 +1,10 @@
+2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * gimple-ssa-stor-merging.c (find_bswap_or_nop_load): Track polynomial
+       offsets for MEM_REFs.
+
 2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index dddafb7bf2739bbfd53d5ea7f76ceb1e1d53fd33..0d15ef76c38e4bc3792a57c6412cd39ae4cbeeb2 100644 (file)
@@ -374,35 +374,31 @@ find_bswap_or_nop_load (gimple *stmt, tree ref, struct symbolic_number *n)
     return false;
   else if (TREE_CODE (base_addr) == MEM_REF)
     {
-      offset_int bit_offset = 0;
+      poly_offset_int bit_offset = 0;
       tree off = TREE_OPERAND (base_addr, 1);
 
       if (!integer_zerop (off))
        {
-         offset_int boff, coff = mem_ref_offset (base_addr);
-         boff = coff << LOG2_BITS_PER_UNIT;
+         poly_offset_int boff = mem_ref_offset (base_addr);
+         boff <<= LOG2_BITS_PER_UNIT;
          bit_offset += boff;
        }
 
       base_addr = TREE_OPERAND (base_addr, 0);
 
       /* Avoid returning a negative bitpos as this may wreak havoc later.  */
-      if (wi::neg_p (bit_offset))
+      if (maybe_lt (bit_offset, 0))
        {
-         offset_int mask = wi::mask <offset_int> (LOG2_BITS_PER_UNIT, false);
-         offset_int tem = wi::bit_and_not (bit_offset, mask);
-         /* TEM is the bitpos rounded to BITS_PER_UNIT towards -Inf.
-            Subtract it to BIT_OFFSET and add it (scaled) to OFFSET.  */
-         bit_offset -= tem;
-         tem >>= LOG2_BITS_PER_UNIT;
+         tree byte_offset = wide_int_to_tree
+           (sizetype, bits_to_bytes_round_down (bit_offset));
+         bit_offset = num_trailing_bits (bit_offset);
          if (offset)
-           offset = size_binop (PLUS_EXPR, offset,
-                                   wide_int_to_tree (sizetype, tem));
+           offset = size_binop (PLUS_EXPR, offset, byte_offset);
          else
-           offset = wide_int_to_tree (sizetype, tem);
+           offset = byte_offset;
        }
 
-      bitpos += bit_offset.to_shwi ();
+      bitpos += bit_offset.force_shwi ();
     }
   else
     base_addr = build_fold_addr_expr (base_addr);