From 21f65dc872f5b746181d6e78f8be9f7ecb625292 Mon Sep 17 00:00:00 2001 From: Oleg Endo Date: Mon, 23 Mar 2015 18:57:58 +0000 Subject: [PATCH] re PR target/65505 ([SH] ICE in sh_disp_addr_displacement) 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 | 11 ++ gcc/config/sh/constraints.md | 10 +- gcc/config/sh/predicates.md | 10 +- gcc/config/sh/sync.md | 5 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.target/sh/torture/pr65505.c | 122 ++++++++++++++++++ 6 files changed, 151 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.target/sh/torture/pr65505.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad9ca05bd29..2df46f56d6c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2015-03-23 Oleg Endo + + 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 PR target/65296 diff --git a/gcc/config/sh/constraints.md b/gcc/config/sh/constraints.md index 0ac5db5173c..bd059a439d8 100644 --- a/gcc/config/sh/constraints.md +++ b/gcc/config/sh/constraints.md @@ -300,9 +300,9 @@ (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." @@ -322,8 +322,8 @@ (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 diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md index 8d876b65d4b..6f0d89e1f19 100644 --- a/gcc/config/sh/predicates.md +++ b/gcc/config/sh/predicates.md @@ -437,12 +437,14 @@ ;; 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), @@ -451,8 +453,10 @@ ;; 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" diff --git a/gcc/config/sh/sync.md b/gcc/config/sh/sync.md index 6e890a737a9..6e054e6f39a 100644 --- a/gcc/config/sh/sync.md +++ b/gcc/config/sh/sync.md @@ -217,7 +217,6 @@ (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" @@ -707,7 +706,6 @@ (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) @@ -716,8 +714,7 @@ || 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_" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dc2f3f4baea..d0db874f219 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-03-23 Oleg Endo + + PR target/65505 + * gcc.target/sh/torture/pr65505.c: New. + 2015-03-23 Martin Sebor 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 index 00000000000..3e930027094 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/torture/pr65505.c @@ -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; +} -- 2.30.2