re PR rtl-optimization/67756 (ICE compiling Linux Kernel fs/namei.c on ARM)
2015-10-02 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/67756 * lra-constraints.c (match_reload): Add a new parameter. Use it for creating a pseudo with the same value. (curr_insn_transform): Pass a new argument to match_reload. 2015-10-02 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/67756 * gcc.target/arm/pr67756.c: New. From-SVN: r228396
This commit is contained in:
parent
0ff3ac5f44
commit
599e1cf8b1
@ -1,3 +1,10 @@
|
||||
2015-10-02 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
PR rtl-optimization/67756
|
||||
* lra-constraints.c (match_reload): Add a new parameter. Use it
|
||||
for creating a pseudo with the same value.
|
||||
(curr_insn_transform): Pass a new argument to match_reload.
|
||||
|
||||
2015-10-02 Kirill Yukhin <kirill.yukhin@intel.com>
|
||||
|
||||
* config/i386/i386.c (expand_vec_perm_even_odd_trunc): New.
|
||||
|
@ -855,10 +855,11 @@ narrow_reload_pseudo_class (rtx reg, enum reg_class cl)
|
||||
numbers with end marker -1) with reg class GOAL_CLASS. Add input
|
||||
and output reloads correspondingly to the lists *BEFORE and *AFTER.
|
||||
OUT might be negative. In this case we generate input reloads for
|
||||
matched input operands INS. */
|
||||
matched input operands INS. EARLY_CLOBBER_P is a flag that the
|
||||
output operand is early clobbered for chosen alternative. */
|
||||
static void
|
||||
match_reload (signed char out, signed char *ins, enum reg_class goal_class,
|
||||
rtx_insn **before, rtx_insn **after)
|
||||
rtx_insn **before, rtx_insn **after, bool early_clobber_p)
|
||||
{
|
||||
int i, in;
|
||||
rtx new_in_reg, new_out_reg, reg;
|
||||
@ -939,17 +940,19 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class,
|
||||
have a situation like "a <- a op b", where the constraints
|
||||
force the second input operand ("b") to match the output
|
||||
operand ("a"). "b" must then be copied into a new register
|
||||
so that it doesn't clobber the current value of "a". */
|
||||
so that it doesn't clobber the current value of "a".
|
||||
|
||||
We can not use the same value if the output pseudo is
|
||||
early clobbered or the input pseudo is mentioned in the
|
||||
output, e.g. as an address part in memory, because
|
||||
output reload will actually extend the pseudo liveness.
|
||||
We don't care about eliminable hard regs here as we are
|
||||
interesting only in pseudos. */
|
||||
|
||||
new_in_reg = new_out_reg
|
||||
= (ins[1] < 0 && REG_P (in_rtx)
|
||||
= (! early_clobber_p && ins[1] < 0 && REG_P (in_rtx)
|
||||
&& (int) REGNO (in_rtx) < lra_new_regno_start
|
||||
&& find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx))
|
||||
/* We can not use the same value if the pseudo is mentioned
|
||||
in the output, e.g. as an address part in memory,
|
||||
becuase output reload will actually extend the pseudo
|
||||
liveness. We don't care about eliminable hard regs here
|
||||
as we are interesting only in pseudos. */
|
||||
&& (out < 0 || regno_use_in (REGNO (in_rtx), out_rtx) == NULL_RTX)
|
||||
? lra_create_new_reg (inmode, in_rtx, goal_class, "")
|
||||
: lra_create_new_reg_with_unique_value (outmode, out_rtx,
|
||||
@ -3867,13 +3870,18 @@ curr_insn_transform (bool check_only_p)
|
||||
match_inputs[0] = i;
|
||||
match_inputs[1] = -1;
|
||||
match_reload (goal_alt_matched[i][0], match_inputs,
|
||||
goal_alt[i], &before, &after);
|
||||
goal_alt[i], &before, &after,
|
||||
curr_static_id->operand_alternative
|
||||
[goal_alt_number * n_operands + goal_alt_matched[i][0]]
|
||||
.earlyclobber);
|
||||
}
|
||||
else if (curr_static_id->operand[i].type == OP_OUT
|
||||
&& (curr_static_id->operand[goal_alt_matched[i][0]].type
|
||||
== OP_IN))
|
||||
/* Generate reloads for output and matched inputs. */
|
||||
match_reload (i, goal_alt_matched[i], goal_alt[i], &before, &after);
|
||||
match_reload (i, goal_alt_matched[i], goal_alt[i], &before, &after,
|
||||
curr_static_id->operand_alternative
|
||||
[goal_alt_number * n_operands + i].earlyclobber);
|
||||
else if (curr_static_id->operand[i].type == OP_IN
|
||||
&& (curr_static_id->operand[goal_alt_matched[i][0]].type
|
||||
== OP_IN))
|
||||
@ -3883,7 +3891,7 @@ curr_insn_transform (bool check_only_p)
|
||||
for (j = 0; (k = goal_alt_matched[i][j]) >= 0; j++)
|
||||
match_inputs[j + 1] = k;
|
||||
match_inputs[j + 1] = -1;
|
||||
match_reload (-1, match_inputs, goal_alt[i], &before, &after);
|
||||
match_reload (-1, match_inputs, goal_alt[i], &before, &after, false);
|
||||
}
|
||||
else
|
||||
/* We must generate code in any case when function
|
||||
|
@ -1,3 +1,8 @@
|
||||
2015-10-02 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
PR rtl-optimization/67756
|
||||
* gcc.target/arm/pr67756.c: New.
|
||||
|
||||
2015-10-02 Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
* gcc.target/aarch64/tlsle12_tiny_1.c: New testcase for tiny model.
|
||||
|
62
gcc/testsuite/gcc.target/arm/pr67756.c
Normal file
62
gcc/testsuite/gcc.target/arm/pr67756.c
Normal file
@ -0,0 +1,62 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_hard_vfp_ok } */
|
||||
/* { dg-options "-O2 -mapcs -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16" } */
|
||||
|
||||
struct mutex
|
||||
{
|
||||
};
|
||||
struct dentry
|
||||
{
|
||||
struct inode *d_inode;
|
||||
};
|
||||
struct inode
|
||||
{
|
||||
const struct inode_operations *i_op;
|
||||
struct super_block *i_sb;
|
||||
union
|
||||
{
|
||||
const unsigned int i_nlink;
|
||||
};
|
||||
unsigned long i_state;
|
||||
struct mutex i_mutex;
|
||||
};
|
||||
struct super_block
|
||||
{
|
||||
unsigned int s_max_links;
|
||||
};
|
||||
struct inode_operations
|
||||
{
|
||||
int (*link) (struct dentry *, struct inode *, struct dentry *);
|
||||
} __attribute__ ((__aligned__ ((1 << 6))));
|
||||
static inline __attribute__ ((always_inline))
|
||||
__attribute__ ((no_instrument_function))
|
||||
int may_create (struct inode *dir, struct dentry *child)
|
||||
{
|
||||
if (child->d_inode)
|
||||
return -17;
|
||||
return inode_permission (dir, 0x00000002 | 0x00000001);
|
||||
}
|
||||
|
||||
int
|
||||
vfs_link (struct dentry *old_dentry, struct inode *dir,
|
||||
struct dentry *new_dentry, struct inode **delegated_inode)
|
||||
{
|
||||
struct inode *inode = old_dentry->d_inode;
|
||||
unsigned max_links = dir->i_sb->s_max_links;
|
||||
int error;
|
||||
error = may_create (dir, new_dentry);
|
||||
if (error)
|
||||
return error;
|
||||
mutex_lock (&inode->i_mutex);
|
||||
if (inode->i_nlink == 0 && !(inode->i_state & (1 << 10)))
|
||||
error = -2;
|
||||
else if (max_links && inode->i_nlink >= max_links)
|
||||
error = -31;
|
||||
else
|
||||
{
|
||||
error = try_break_deleg (inode, delegated_inode);
|
||||
error = dir->i_op->link (old_dentry, dir, new_dentry);
|
||||
}
|
||||
mutex_unlock (&inode->i_mutex);
|
||||
return error;
|
||||
}
|
Loading…
Reference in New Issue
Block a user