mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 17:21:03 +08:00
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
This commit is contained in:
parent
ed137300ca
commit
21f65dc872
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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<mode>"
|
||||
@ -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_<fetchop_name><mode>"
|
||||
|
@ -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
|
||||
|
122
gcc/testsuite/gcc.target/sh/torture/pr65505.c
Normal file
122
gcc/testsuite/gcc.target/sh/torture/pr65505.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user