re PR target/65505 ([SH] ICE in sh_disp_addr_displacement)
authorOleg Endo <olegendo@gcc.gnu.org>
Mon, 23 Mar 2015 18:57:58 +0000 (18:57 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Mon, 23 Mar 2015 18:57:58 +0000 (18:57 +0000)
gcc/
PR target/65505
* config/sh/predicates.md (simple_mem_operand,
displacement_mem_operand): Add test for reg.
(short_displacement_mem_operand): Test for displacement_mem_operand
before invoking sh_disp_addr_displacement.
* config/sh/constraints.md (Sdd, Sra): Simplify.
* config/sh/sync.md (atomic_mem_operand_0, atomic_mem_operand_1):
Remove redundant displacement_mem_operand tests.

gcc/testsuite/
PR target/65505
* gcc.target/sh/torture/pr65505.c: New.

From-SVN: r221604

gcc/ChangeLog
gcc/config/sh/constraints.md
gcc/config/sh/predicates.md
gcc/config/sh/sync.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/torture/pr65505.c [new file with mode: 0644]

index ad9ca05bd29673311d2ebe55718593c6c637f010..2df46f56d6c98f79bf78d3e1f76c3bc31e1261cf 100644 (file)
@@ -1,3 +1,14 @@
+2015-03-23  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/65505
+       * config/sh/predicates.md (simple_mem_operand,
+       displacement_mem_operand): Add test for reg.
+       (short_displacement_mem_operand): Test for displacement_mem_operand
+       before invoking sh_disp_addr_displacement.
+       * config/sh/constraints.md (Sdd, Sra): Simplify.
+       * config/sh/sync.md (atomic_mem_operand_0, atomic_mem_operand_1):
+       Remove redundant displacement_mem_operand tests.
+
 2015-03-23  Georg-Johann Lay  <avr@gjlay.de>
 
        PR target/65296
index 0ac5db5173c562f5458d5a392764397c24319f99..bd059a439d8d28bfe7f26ff4c13d9c76bc47cb1b 100644 (file)
 (define_memory_constraint "Sdd"
   "A memory reference that uses displacement addressing."
   (and (match_code "mem")
-       (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
-       (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
-       (match_test "CONST_INT_P (XEXP (XEXP (op, 0), 1))")))
+       (match_code "plus" "0")
+       (match_code "reg" "00")
+       (match_code "const_int" "01")))
 
 (define_memory_constraint "Snd"
   "A memory reference that excludes displacement addressing."
 
 (define_memory_constraint "Sra"
   "A memory reference that uses simple register addressing."
-  (and (match_test "MEM_P (op)")
-       (match_test "REG_P (XEXP (op, 0))")))
+  (and (match_code "mem")
+       (match_code "reg" "0")))
 
 (define_memory_constraint "Ara"
   "A memory reference that uses simple register addressing suitable for
index 8d876b65d4b669683b76e824d14a530d42887d78..6f0d89e1f196463470809d2ba4b24322b0cb80b8 100644 (file)
 ;; Returns 1 if OP is a simple register address.
 (define_predicate "simple_mem_operand"
   (and (match_code "mem")
+       (match_code "reg" "0")
        (match_test "arith_reg_operand (XEXP (op, 0), SImode)")))
 
 ;; Returns 1 if OP is a valid displacement address.
 (define_predicate "displacement_mem_operand"
   (and (match_code "mem")
-       (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
+       (match_code "plus" "0")
+       (match_code "reg" "00")
        (match_test "arith_reg_operand (XEXP (XEXP (op, 0), 0), SImode)")
        (match_test "sh_legitimate_index_p (GET_MODE (op),
                                           XEXP (XEXP (op, 0), 1),
 ;; Returns true if OP is a displacement address that can fit into a
 ;; 16 bit (non-SH2A) memory load / store insn.
 (define_predicate "short_displacement_mem_operand"
-  (match_test "sh_disp_addr_displacement (op)
-              <= sh_max_mov_insn_displacement (GET_MODE (op), false)"))
+  (and (match_code "mem")
+       (match_operand 0 "displacement_mem_operand")
+       (match_test "sh_disp_addr_displacement (op)
+                   <= sh_max_mov_insn_displacement (GET_MODE (op), false)")))
 
 ;; Returns 1 if the operand can be used in an SH2A movu.{b|w} insn.
 (define_predicate "zero_extend_movu_operand"
index 6e890a737a990b595b9daef5e3e8a39759dece34..6e054e6f39ae1d4ebe74e60d89957d1c37b0879f 100644 (file)
            (and (match_test "mode == SImode")
                 (and (match_test "!TARGET_ATOMIC_HARD_LLCS")
                      (match_test "!TARGET_SH4A || TARGET_ATOMIC_STRICT"))
-                (match_operand 0 "displacement_mem_operand")
                 (match_operand 0 "short_displacement_mem_operand")))))
 
 (define_expand "atomic_compare_and_swap<mode>"
            (and (match_test "mode == SImode")
                 (match_test "TARGET_ATOMIC_SOFT_GUSA
                              && (!TARGET_SH4A || TARGET_ATOMIC_STRICT)")
-                (match_operand 0 "displacement_mem_operand")
                 (match_operand 0 "short_displacement_mem_operand"))
            (and (ior (match_test "(TARGET_ATOMIC_SOFT_TCB
                                    || TARGET_ATOMIC_SOFT_IMASK)
                                    || TARGET_ATOMIC_SOFT_IMASK)
                                   && TARGET_SH4A && !TARGET_ATOMIC_STRICT
                                   && mode != SImode"))
-                (ior (and (match_operand 0 "displacement_mem_operand")
-                          (match_operand 0 "short_displacement_mem_operand"))
+                (ior (match_operand 0 "short_displacement_mem_operand")
                      (match_operand 0 "gbr_address_mem"))))))
 
 (define_expand "atomic_fetch_<fetchop_name><mode>"
index dc2f3f4baea220d30682c1cdb6bedf061396b1ad..d0db874f219891bd106684b1a9a8a28e4086aad8 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-23  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/65505
+       * gcc.target/sh/torture/pr65505.c: New.
+
 2015-03-23  Martin Sebor  <msebor@redhat.com>
 
        PR testsuite/63175
diff --git a/gcc/testsuite/gcc.target/sh/torture/pr65505.c b/gcc/testsuite/gcc.target/sh/torture/pr65505.c
new file mode 100644 (file)
index 0000000..3e93002
--- /dev/null
@@ -0,0 +1,122 @@
+/* { dg-do compile }  */
+/* { dg-additional-options "-std=gnu99" }  */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } }  */
+
+struct thread_info {
+ struct task_struct *task;
+};
+
+static inline __attribute__((always_inline))
+              __attribute__((no_instrument_function))
+struct thread_info *current_thread_info(void)
+{
+ struct thread_info *ti;
+
+ unsigned long __dummy;
+
+ __asm__ __volatile__ (
+  "mov r15, %0\n\t"
+  "and %1, %0\n\t"
+  : "=&r" (ti), "=r" (__dummy)
+  : "1" (~((1 << 13) - 1))
+  : "memory");
+
+ return ti;
+}
+
+typedef struct seqcount {
+ unsigned sequence;
+} seqcount_t;
+
+struct inode;
+
+struct dentry {
+ seqcount_t d_seq;
+ struct inode *d_inode;
+};
+
+struct path {
+ struct vfsmount *mnt;
+ struct dentry *dentry;
+};
+
+struct file {
+ struct path f_path;
+} __attribute__((aligned(4)));
+
+struct task_struct
+{
+ int link_count, total_link_count;
+ struct fs_struct *fs;
+};
+
+struct fd {
+ struct file *file;
+ unsigned int flags;
+};
+
+static inline __attribute__((always_inline))
+              __attribute__((no_instrument_function))
+struct fd
+fdget_raw(unsigned int fd)
+{
+  return (struct fd){(struct file *)(fd & ~3),fd & 3};
+}
+
+
+struct fs_struct;
+
+struct nameidata {
+ struct path path;
+ struct path root;
+ struct inode *inode;
+ unsigned int flags;
+ unsigned seq, m_seq;
+ struct file *base;
+};
+
+int read_seqcount_retry(const seqcount_t *s, unsigned start);
+
+int
+path_init(int dfd, const char *name, unsigned int flags,
+          struct nameidata *nd)
+{
+ int retval = 0;
+
+ if (*name=='/') {
+  nd->path = nd->root;
+ } else if (dfd == -100) {
+
+  if (flags & 0x0040) {
+   struct fs_struct *fs = (current_thread_info()->task)->fs;
+  }
+ } else {
+
+  struct fd f = fdget_raw(dfd);
+  struct dentry *dentry;
+
+  if (!f.file)
+   return -9;
+
+  dentry = f.file->f_path.dentry;
+
+  nd->path = f.file->f_path;
+  if (flags & 0x0040) {
+   if (f.flags & 1)
+    nd->base = f.file;
+  }
+ }
+
+ nd->inode = nd->path.dentry->d_inode;
+ if (!(flags & 0x0040))
+  goto done;
+ if (__builtin_expect(!!(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)), 1))
+  goto done;
+ if (!(nd->flags & 0x2000))
+  nd->root.mnt = ((void *)0);
+
+ return -10;
+done:
+ (current_thread_info()->task)->total_link_count = 0;
+ return 0;
+}