]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR87793] reject non-toplevel unspecs in debug loc exprs on x86
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Nov 2018 10:15:46 +0000 (10:15 +0000)
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Nov 2018 10:15:46 +0000 (10:15 +0000)
Before revision 254025, we'd reject UNSPECs in debug loc exprs.
TARGET_CONST_NOT_OK_FOR_DEBUG_P still rejects that by default, on all
ports that override it, except for x86, that accepts @gotoff unspecs.
We can indeed accept them in top-level expressions, but not as
subexpressions: the assembler rejects the difference between two
@gotoff symbols, for example.

We could simplify such a difference and drop the @gotoffs, provided
that the symbols are in the same section; we could also accept
@gotoffs plus literal constants.  However, accepting those but
rejecting such combinations as subexpressions would be ugly, and most
likely not worth the trouble: sym@gotoff+litconst hardly makes sense
as a standalone expression, and the difference between @gotoffs should
be avoided to begin with, as follows.

Ideally, the debug loc exprs would use the symbolic data in
REG_EQUIV/REG_EQUAL notes, or delegitimized addresses, instead of
simplifying the difference between two legitimized addresses so that
the occurrences of the GOT register cancel each other.  That would
require some more elaborate surgery in var-tracking and cselib than
would be appropriate at this stage.

for  gcc/ChangeLog

PR target/87793
* config/i386/i386.c (ix86_const_not_ok_for_debug_p): Reject
non-toplevel UNSPEC.

for  gcc/testsuite/ChangeLog

PR target/87793
* gcc.dg/pr87793.c: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@265956 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr87793.c [new file with mode: 0644]

index 9df874d646b97bc5db991618a92b9dd066324252..21d9ae799a655caa7c4f98c078dc9ffe88f2976e 100644 (file)
@@ -1,3 +1,9 @@
+2018-11-09  Alexandre Oliva <aoliva@redhat.com>
+
+       PR target/87793
+       * config/i386/i386.c (ix86_const_not_ok_for_debug_p): Reject
+       non-toplevel UNSPEC.
+
 2018-11-08  Aldy Hernandez  <aldyh@redhat.com>
 
        * tree-vrp.c (value_range::check): Do not access internals
index 77dec0f21b35365ce3f11c99c5dacf3dbd746d1a..711bec0cc9d7ce98abbf8a40517234f933f5edd9 100644 (file)
@@ -17177,6 +17177,18 @@ ix86_const_not_ok_for_debug_p (rtx x)
   if (SYMBOL_REF_P (x) && strcmp (XSTR (x, 0), GOT_SYMBOL_NAME) == 0)
     return true;
 
+  /* Reject UNSPECs within expressions.  We could accept symbol@gotoff
+     + literal_constant, but that would hardly come up in practice,
+     and it's not worth the trouble of having to reject that as an
+     operand to pretty much anything else.  */
+  if (UNARY_P (x)
+      && GET_CODE (XEXP (x, 0)) == UNSPEC)
+    return true;
+  if (BINARY_P (x)
+      && (GET_CODE (XEXP (x, 0)) == UNSPEC
+         || GET_CODE (XEXP (x, 1)) == UNSPEC))
+    return true;
+
   return false;
 }
 \f
index aa7984789eef0c1723606f57c609512281db03d3..9a7dfc26dfa3b65c99a03aaa7248fecae8950eae 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-09  Alexandre Oliva <aoliva@redhat.com>
+
+       PR target/87793
+       * gcc.dg/pr87793.c: New.
+
 2018-11-09  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 
        * gcc.target/arm/neon-vect-div-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr87793.c b/gcc/testsuite/gcc.dg/pr87793.c
new file mode 100644 (file)
index 0000000..3194313
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-fpic -Os -g" } */
+
+struct fit_loadable_tbl {
+       int type;
+       void (*handler)(int data, int size);
+};
+
+#define ll_entry_start(_type, _list)                                   \
+({                                                                     \
+       static char start[0] __attribute__((aligned(4)))                \
+               __attribute__((unused, section(".u_boot_list_2_"#_list"_1")));  \
+       (_type *)&start;                                                \
+})
+
+#define ll_entry_end(_type, _list)                                     \
+({                                                                     \
+       static char end[0] __attribute__((aligned(4)))                  \
+               __attribute__((unused, section(".u_boot_list_2_"#_list"_3")));  \
+       (_type *)&end;                                                  \
+})
+
+#define ll_entry_count(_type, _list)                                   \
+       ({                                                              \
+               _type *start = ll_entry_start(_type, _list);            \
+               _type *end = ll_entry_end(_type, _list);                \
+               unsigned int _ll_result = end - start;                  \
+               _ll_result;                                             \
+       })
+
+void test(int img_type, int img_data, int img_len)
+{
+       int i;
+       const unsigned int count =
+               ll_entry_count(struct fit_loadable_tbl, fit_loadable);
+       struct fit_loadable_tbl *fit_loadable_handler =
+               ll_entry_start(struct fit_loadable_tbl, fit_loadable);
+
+       for (i = 0; i < count; i++, fit_loadable_handler++)
+               if (fit_loadable_handler->type == img_type)
+                       fit_loadable_handler->handler(img_data, img_len);
+}