This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On ev56 we would miscompile build_unary_op. Irritatingly, this miscompilation would not show up in a bootstrap of the compiler; I found it via an abort building linux kernel source. Reduced test case attached. The deal is that we'd create (insn 79 12 80 (set (subreg:DI (reg:SI 79) 0) (ne:DI (reg/v:DI 70) (const_int 0 [0x0]))) 152 {*setne_internal} (insn_list 12 (nil)) (expr_list:REG_DEAD (reg/v:DI 70) (nil))) (insn 80 79 16 (set (subreg:DI (reg:SI 79) 0) (plus:DI (subreg:DI (reg:SI 79) 0) (const_int 6 [0x6]))) 6 {*adddi_internal} (insn_list 79 (nil)) (nil)) where all the subregs are shared. When reload runs, it fixes up r79 in insn 79, which makes insn 80 look proper. Except that since this is a set of a paradoxical subreg, reload created an output reload for insn 79, which means that insn 80 is horked. Which leaves us with 0 or 1 in the spill slot instead of 6 or 7. Oops. r~ * config/alpha/alpha.c (alpha_split_conditional_move): Call copy_rtx as needed to avoid shared structure. Index: config/alpha/alpha.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v retrieving revision 1.221 diff -c -p -d -u -r1.221 alpha.c --- alpha.c 2002/01/04 08:15:21 1.221 +++ alpha.c 2002/01/08 23:39:57 @@ -3166,6 +3166,9 @@ alpha_split_conditional_move (code, dest else subtarget = target; } + /* Below, we must be careful to use copy_rtx on target and subtarget + in intermediate insns, as they may be a subreg rtx, which may not + be shared. */ if (f == 0 && exact_log2 (diff) > 0 /* On EV6, we've got enough shifters to make non-arithmatic shifts @@ -3174,33 +3177,35 @@ alpha_split_conditional_move (code, dest && (diff <= 8 || alpha_cpu == PROCESSOR_EV6)) { tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx); - emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp)); + emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp)); - tmp = gen_rtx_ASHIFT (DImode, subtarget, GEN_INT (exact_log2 (t))); + tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget), + GEN_INT (exact_log2 (t))); emit_insn (gen_rtx_SET (VOIDmode, target, tmp)); } else if (f == 0 && t == -1) { tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx); - emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp)); + emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp)); - emit_insn (gen_negdi2 (target, subtarget)); + emit_insn (gen_negdi2 (target, copy_rtx (subtarget))); } else if (diff == 1 || diff == 4 || diff == 8) { rtx add_op; tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx); - emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp)); + emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp)); if (diff == 1) - emit_insn (gen_adddi3 (target, subtarget, GEN_INT (f))); + emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f))); else { add_op = GEN_INT (f); if (sext_add_operand (add_op, mode)) { - tmp = gen_rtx_MULT (DImode, subtarget, GEN_INT (diff)); + tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget), + GEN_INT (diff)); tmp = gen_rtx_PLUS (DImode, tmp, add_op); emit_insn (gen_rtx_SET (VOIDmode, target, tmp)); }
Attachment:
z.c
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |