aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoern Rennecke <joern.rennecke@embecosm.com>2011-12-09 12:57:24 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2011-12-09 12:57:24 +0000
commit7543f91816ec7402e501d2afa09d7f18ac8bee61 (patch)
tree29604d6a37d0c504c6bb80d0d28fbabc827412ab
parentfb5503484f7463c2a523fed993f58e58289ba59b (diff)
downloadgcc-7543f91816ec7402e501d2afa09d7f18ac8bee61.zip
gcc-7543f91816ec7402e501d2afa09d7f18ac8bee61.tar.gz
gcc-7543f91816ec7402e501d2afa09d7f18ac8bee61.tar.bz2
re PR middle-end/40154 (internal compiler error: in do_SUBST, at combine.c:681)
PR middle-end/40154 * emit-rtl.c (set_dst_reg_note): New function. * rtl.h (set_dst_reg_note): Declare. * optabs.c (expand_binop, expand_absneg_bit): Use set_dst_reg_note. (emit_libcall_block, expand_fix): Likewise. * function.c (assign_parm_setup_reg, expand_function_start): Likewise. * expmed.c (expand_mult_const, expand_divmod): Likewise. * reload1.c (gen_reload): Likewise. From-SVN: r182162
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/emit-rtl.c11
-rw-r--r--gcc/expmed.c57
-rw-r--r--gcc/function.c7
-rw-r--r--gcc/optabs.c38
-rw-r--r--gcc/reload1.c4
-rw-r--r--gcc/rtl.h1
7 files changed, 73 insertions, 56 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a5e4afe..8f56fbb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2011-12-09 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ PR middle-end/40154
+ * emit-rtl.c (set_dst_reg_note): New function.
+ * rtl.h (set_dst_reg_note): Declare.
+ * optabs.c (expand_binop, expand_absneg_bit): Use set_dst_reg_note.
+ (emit_libcall_block, expand_fix): Likewise.
+ * function.c (assign_parm_setup_reg, expand_function_start): Likewise.
+ * expmed.c (expand_mult_const, expand_divmod): Likewise.
+ * reload1.c (gen_reload): Likewise.
+
2011-12-09 Kai Tietz <ktietz@redhat.com>
* ira-color.c (print_hard_regs_subforest): Use
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 4a27a05..a537374 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -5004,6 +5004,17 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
return REG_NOTES (insn);
}
+
+/* Like set_unique_reg_note, but don't do anything unless INSN sets DST. */
+rtx
+set_dst_reg_note (rtx insn, enum reg_note kind, rtx datum, rtx dst)
+{
+ rtx set = single_set (insn);
+
+ if (set && SET_DEST (set) == dst)
+ return set_unique_reg_note (insn, kind, datum);
+ return NULL_RTX;
+}
/* Return an indication of which type of insn should have X as a body.
The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN. */
diff --git a/gcc/expmed.c b/gcc/expmed.c
index b3e6d6d..cfa045b 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -2939,6 +2939,7 @@ expand_mult_const (enum machine_mode mode, rtx op0, HOST_WIDE_INT val,
&& !optimize)
? target : 0;
rtx accum_target = optimize ? 0 : accum;
+ rtx accum_inner;
switch (alg->op[opno])
{
@@ -3004,16 +3005,18 @@ expand_mult_const (enum machine_mode mode, rtx op0, HOST_WIDE_INT val,
that. */
tem = op0, nmode = mode;
+ accum_inner = accum;
if (GET_CODE (accum) == SUBREG)
{
- nmode = GET_MODE (SUBREG_REG (accum));
+ accum_inner = SUBREG_REG (accum);
+ nmode = GET_MODE (accum_inner);
tem = gen_lowpart (nmode, op0);
}
insn = get_last_insn ();
- set_unique_reg_note (insn, REG_EQUAL,
- gen_rtx_MULT (nmode, tem,
- GEN_INT (val_so_far)));
+ set_dst_reg_note (insn, REG_EQUAL,
+ gen_rtx_MULT (nmode, tem, GEN_INT (val_so_far)),
+ accum_inner);
}
if (variant == negate_variant)
@@ -3823,7 +3826,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
rtx quotient = 0, remainder = 0;
rtx last;
int size;
- rtx insn, set;
+ rtx insn;
optab optab1, optab2;
int op1_is_constant, op1_is_pow2 = 0;
int max_cost, extra_cost;
@@ -4127,12 +4130,10 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
break;
insn = get_last_insn ();
- if (insn != last
- && (set = single_set (insn)) != 0
- && SET_DEST (set) == quotient)
- set_unique_reg_note (insn,
- REG_EQUAL,
- gen_rtx_UDIV (compute_mode, op0, op1));
+ if (insn != last)
+ set_dst_reg_note (insn, REG_EQUAL,
+ gen_rtx_UDIV (compute_mode, op0, op1),
+ quotient);
}
else /* TRUNC_DIV, signed */
{
@@ -4211,18 +4212,15 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
{
insn = get_last_insn ();
if (insn != last
- && (set = single_set (insn)) != 0
- && SET_DEST (set) == quotient
&& abs_d < ((unsigned HOST_WIDE_INT) 1
<< (HOST_BITS_PER_WIDE_INT - 1)))
- set_unique_reg_note (insn,
- REG_EQUAL,
- gen_rtx_DIV (compute_mode,
- op0,
- GEN_INT
- (trunc_int_for_mode
+ set_dst_reg_note (insn, REG_EQUAL,
+ gen_rtx_DIV (compute_mode, op0,
+ GEN_INT
+ (trunc_int_for_mode
(abs_d,
- compute_mode))));
+ compute_mode))),
+ quotient);
quotient = expand_unop (compute_mode, neg_optab,
quotient, quotient, 0);
@@ -4309,12 +4307,10 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
break;
insn = get_last_insn ();
- if (insn != last
- && (set = single_set (insn)) != 0
- && SET_DEST (set) == quotient)
- set_unique_reg_note (insn,
- REG_EQUAL,
- gen_rtx_DIV (compute_mode, op0, op1));
+ if (insn != last)
+ set_dst_reg_note (insn, REG_EQUAL,
+ gen_rtx_DIV (compute_mode, op0, op1),
+ quotient);
}
break;
}
@@ -4732,11 +4728,10 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
NULL_RTX, 1);
insn = get_last_insn ();
- set_unique_reg_note (insn,
- REG_EQUAL,
- gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
- compute_mode,
- op0, op1));
+ set_dst_reg_note (insn, REG_EQUAL,
+ gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
+ compute_mode, op0, op1),
+ quotient);
}
break;
diff --git a/gcc/function.c b/gcc/function.c
index fa9236c..a081b27 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -3140,9 +3140,8 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
set_unique_reg_note (sinsn, REG_EQUIV, stackr);
}
}
- else if ((set = single_set (linsn)) != 0
- && SET_DEST (set) == parmreg)
- set_unique_reg_note (linsn, REG_EQUIV, equiv_stack_parm);
+ else
+ set_dst_reg_note (linsn, REG_EQUIV, equiv_stack_parm, parmreg);
}
/* For pointer data type, suggest pointer register. */
@@ -4757,7 +4756,7 @@ expand_function_start (tree subr)
/* Mark the register as eliminable, similar to parameters. */
if (MEM_P (chain)
&& reg_mentioned_p (arg_pointer_rtx, XEXP (chain, 0)))
- set_unique_reg_note (insn, REG_EQUIV, chain);
+ set_dst_reg_note (insn, REG_EQUIV, chain, local);
}
/* If the function receives a non-local goto, then store the
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 55cfe8c..3f50177 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -2052,11 +2052,11 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
{
rtx temp = emit_move_insn (target, xtarget);
- set_unique_reg_note (temp,
- REG_EQUAL,
- gen_rtx_fmt_ee (binoptab->code, mode,
- copy_rtx (xop0),
- copy_rtx (xop1)));
+ set_dst_reg_note (temp, REG_EQUAL,
+ gen_rtx_fmt_ee (binoptab->code, mode,
+ copy_rtx (xop0),
+ copy_rtx (xop1)),
+ target);
}
else
target = xtarget;
@@ -2104,11 +2104,12 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
{
temp = emit_move_insn (target ? target : product, product);
- set_unique_reg_note (temp,
- REG_EQUAL,
- gen_rtx_fmt_ee (MULT, mode,
- copy_rtx (op0),
- copy_rtx (op1)));
+ set_dst_reg_note (temp,
+ REG_EQUAL,
+ gen_rtx_fmt_ee (MULT, mode,
+ copy_rtx (op0),
+ copy_rtx (op1)),
+ target ? target : product);
}
return product;
}
@@ -2966,8 +2967,9 @@ expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
target = lowpart_subreg_maybe_copy (mode, temp, imode);
- set_unique_reg_note (get_last_insn (), REG_EQUAL,
- gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
+ set_dst_reg_note (get_last_insn (), REG_EQUAL,
+ gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
+ target);
}
return target;
@@ -3899,8 +3901,7 @@ emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
}
last = emit_move_insn (target, result);
- if (optab_handler (mov_optab, GET_MODE (target)) != CODE_FOR_nothing)
- set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
+ set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
if (final_dest != target)
emit_move_insn (final_dest, target);
@@ -5213,11 +5214,10 @@ expand_fix (rtx to, rtx from, int unsignedp)
{
/* Make a place for a REG_NOTE and add it. */
insn = emit_move_insn (to, to);
- set_unique_reg_note (insn,
- REG_EQUAL,
- gen_rtx_fmt_e (UNSIGNED_FIX,
- GET_MODE (to),
- copy_rtx (from)));
+ set_dst_reg_note (insn, REG_EQUAL,
+ gen_rtx_fmt_e (UNSIGNED_FIX, GET_MODE (to),
+ copy_rtx (from)),
+ to);
}
return;
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 2f783a2..7852566 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -8574,7 +8574,7 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
if (insn)
{
/* Add a REG_EQUIV note so that find_equiv_reg can find it. */
- set_unique_reg_note (insn, REG_EQUIV, in);
+ set_dst_reg_note (insn, REG_EQUIV, in, out);
return insn;
}
@@ -8584,7 +8584,7 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
gcc_assert (!reg_overlap_mentioned_p (out, op0));
gen_reload (out, op1, opnum, type);
insn = emit_insn (gen_add2_insn (out, op0));
- set_unique_reg_note (insn, REG_EQUIV, in);
+ set_dst_reg_note (insn, REG_EQUIV, in, out);
}
#ifdef SECONDARY_MEMORY_NEEDED
diff --git a/gcc/rtl.h b/gcc/rtl.h
index fd3e3ef..bd09cbf 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1893,6 +1893,7 @@ extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
/* In emit-rtl.c */
extern rtx set_unique_reg_note (rtx, enum reg_note, rtx);
+extern rtx set_dst_reg_note (rtx, enum reg_note, rtx, rtx);
extern void set_insn_deleted (rtx);
/* Functions in rtlanal.c */