]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Fix %lo overflow with BLKmode references.
authorJim Wilson <jimw@sifive.com>
Tue, 19 Mar 2019 22:33:34 +0000 (22:33 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Tue, 19 Mar 2019 22:33:34 +0000 (15:33 -0700)
gcc/
PR target/89411
* config/riscv/riscv.c (riscv_valid_lo_sum_p): New arg x.  New locals
align, size, offset.  Use them to handle a BLKmode reference.  Update
comment.
(riscv_classify_address): Pass info->offset to riscv_valid_lo_sum_p.

gcc/testsuite/
PR target/89411
* gcc.target/riscv/losum-overflow.c: New test.

From-SVN: r269813

gcc/ChangeLog
gcc/config/riscv/riscv.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/riscv/losum-overflow.c [new file with mode: 0644]

index f4b59d7d9ebfe08094816c83436dcc2dc86b1dd3..adf1382a441359cdaf1b904d16132f1a2540b662 100644 (file)
@@ -1,3 +1,11 @@
+2019-03-19  Jim Wilson  <jimw@sifive.com>
+
+       PR target/89411
+       * config/riscv/riscv.c (riscv_valid_lo_sum_p): New arg x.  New locals
+       align, size, offset.  Use them to handle a BLKmode reference.  Update
+       comment.
+       (riscv_classify_address): Pass info->offset to riscv_valid_lo_sum_p.
+
 2019-03-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/89768
index 8e78ab763754845883ed0b39787279a50b6a4e56..d8446f82b9622d054e2fcffe0fb118a1ea703758 100644 (file)
@@ -708,11 +708,15 @@ riscv_split_symbol_type (enum riscv_symbol_type symbol_type)
 }
 
 /* Return true if a LO_SUM can address a value of mode MODE when the
-   LO_SUM symbol has type SYM_TYPE.  */
+   LO_SUM symbol has type SYM_TYPE.  X is the LO_SUM second operand, which
+   is used when the mode is BLKmode.  */
 
 static bool
-riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode)
+riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode,
+                     rtx x)
 {
+  int align, size;
+
   /* Check that symbols of type SYMBOL_TYPE can be used to access values
      of mode MODE.  */
   if (riscv_symbol_insns (sym_type) == 0)
@@ -722,11 +726,38 @@ riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode)
   if (!riscv_split_symbol_type (sym_type))
     return false;
 
+  /* We can't tell size or alignment when we have BLKmode, so try extracing a
+     decl from the symbol if possible.  */
+  if (mode == BLKmode)
+    {
+      rtx offset;
+
+      /* Extract the symbol from the LO_SUM operand, if any.  */
+      split_const (x, &x, &offset);
+
+      /* Might be a CODE_LABEL.  We can compute align but not size for that,
+        so don't bother trying to handle it.  */
+      if (!SYMBOL_REF_P (x))
+       return false;
+
+      /* Use worst case assumptions if we don't have a SYMBOL_REF_DECL.  */
+      align = (SYMBOL_REF_DECL (x)
+              ? DECL_ALIGN (SYMBOL_REF_DECL (x))
+              : 1);
+      size = (SYMBOL_REF_DECL (x) && DECL_SIZE (SYMBOL_REF_DECL (x))
+             ? tree_to_uhwi (DECL_SIZE (SYMBOL_REF_DECL (x)))
+             : 2*BITS_PER_WORD);
+    }
+  else
+    {
+      align = GET_MODE_ALIGNMENT (mode);
+      size = GET_MODE_BITSIZE (mode);
+    }
+
   /* We may need to split multiword moves, so make sure that each word
      can be accessed without inducing a carry.  */
-  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
-      && (!TARGET_STRICT_ALIGN
-         || GET_MODE_BITSIZE (mode) > GET_MODE_ALIGNMENT (mode)))
+  if (size > BITS_PER_WORD
+      && (!TARGET_STRICT_ALIGN || size > align))
     return false;
 
   return true;
@@ -772,7 +803,7 @@ riscv_classify_address (struct riscv_address_info *info, rtx x,
       info->symbol_type
        = riscv_classify_symbolic_expression (info->offset);
       return (riscv_valid_base_register_p (info->reg, mode, strict_p)
-             && riscv_valid_lo_sum_p (info->symbol_type, mode));
+             && riscv_valid_lo_sum_p (info->symbol_type, mode, info->offset));
 
     case CONST_INT:
       /* Small-integer addresses don't occur very often, but they
index cf01b2fea19eafae2bfb7f9329f31e3fcc381dbf..7ad6ccc1e4a0758aece2a0d8f276f36e536d40b0 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-19  Jim Wilson  <jimw@sifive.com>
+
+       PR target/89411
+       * gcc.target/riscv/losum-overflow.c: New test.
+
 2019-03-19  Martin Sebor  <msebor@redhat.com>
 
        PR tree-optimization/89644
diff --git a/gcc/testsuite/gcc.target/riscv/losum-overflow.c b/gcc/testsuite/gcc.target/riscv/losum-overflow.c
new file mode 100644 (file)
index 0000000..9c01c7f
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc -mabi=ilp32 -O2 -fno-section-anchors" } */
+
+/* Check for %lo overflow.  Adding an offset larger than the alignment can
+   overflow if the data is allocated to an address mod 4KB that is between
+   2KB-offset+1 and 2KB-1.  */
+typedef long long int int64_t;
+
+#pragma pack(push)
+#pragma pack(1)
+struct S0 {
+   signed f0 : 4;
+   const volatile int64_t  f1;
+   volatile signed f2 : 1;
+   signed f3 : 31;
+   unsigned f4 : 8;
+   signed f5 : 20;
+   unsigned f6 : 5;
+};
+#pragma pack(pop)
+
+struct S0 g_3030 = {0,-9L,-0,-22553,7,-841,1};
+
+int64_t
+sub (void)
+{
+  return g_3030.f1;
+}
+/* { dg-final { scan-assembler-not "%lo\\(g_3030\\+4\\)" } } */