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]

fix alpha shared subreg bug


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]