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 latent bug in cprop


Hi,
I've run into misscompilation of binutils that unfortunately reproduces only on
Hammer branch compiling for i686.  The problem is libcall containing something like:
(set (reg) (mem (symbol_ref "foo")))
(set (stack) (reg))
(call_insn ...)
Repeated several times.   Copy propagation using cselib notices that reg is
actually set to same value and "copy propagate" it.  Later the first occurence
of libcall is removed as dead and we get wrong value passed to the other calls.

I've fixed that by avoiding coprop to registers set in libcalls.
Regtested/bootstrapped mainline, installed to hammer branch.  OK for mainline?
Honza

Mon Dec  2 22:13:49 CET 2002  Jan Hubicka  <jh@suse.cz>
	* cselib.c (cselib_current_insn_in_libcall): New static variable.
	(new_elt_loc_list, cselib_process_insn, cselib_init): Keep track on whether
	we are inside libcall.
	* cselib.h (elt_loc_list): Add in_libcall.
	* gcse.c (do_local_cprop): Do not copy propagate using insns
	in libcalls.
Index: cselib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cselib.c,v
retrieving revision 1.22
diff -c -3 -p -r1.22 cselib.c
*** cselib.c	9 Oct 2002 17:26:27 -0000	1.22
--- cselib.c	2 Dec 2002 21:12:00 -0000
*************** static GTY((param_is (cselib_val))) htab
*** 83,88 ****
--- 83,89 ----
  /* This is a global so we don't have to pass this through every function.
     It is used in new_elt_loc_list to set SETTING_INSN.  */
  static rtx cselib_current_insn;
+ static bool cselib_current_insn_in_libcall;
  
  /* Every new unknown value gets a unique number.  */
  static unsigned int next_unknown_value;
*************** new_elt_loc_list (next, loc)
*** 163,168 ****
--- 164,170 ----
    el->next = next;
    el->loc = loc;
    el->setting_insn = cselib_current_insn;
+   el->in_libcall = cselib_current_insn_in_libcall;
    return el;
  }
  
*************** cselib_process_insn (insn)
*** 1308,1313 ****
--- 1310,1319 ----
    int i;
    rtx x;
  
+   if (find_reg_note (insn, REG_LIBCALL, NULL))
+     cselib_current_insn_in_libcall = true;
+   if (find_reg_note (insn, REG_RETVAL, NULL))
+     cselib_current_insn_in_libcall = false;
    cselib_current_insn = insn;
  
    /* Forget everything at a CODE_LABEL, a volatile asm, or a setjmp.  */
*************** cselib_init ()
*** 1407,1412 ****
--- 1413,1419 ----
    hash_table = htab_create_ggc (31, get_value_hash, entry_and_rtx_equal_p, 
  				NULL);
    clear_table (1);
+   cselib_current_insn_in_libcall = false;
  }
  
  /* Called when the current user is done with cselib.  */
Index: cselib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cselib.h,v
retrieving revision 1.5
diff -c -3 -p -r1.5 cselib.h
*** cselib.h	4 Jun 2002 07:07:21 -0000	1.5
--- cselib.h	2 Dec 2002 21:12:00 -0000
*************** struct elt_loc_list GTY(())
*** 49,54 ****
--- 49,56 ----
    rtx loc;
    /* The insn that made the equivalence.  */
    rtx setting_insn;
+   /* True when setting insn is inside libcall.  */
+   bool in_libcall;
  };
  
  /* A list of cselib_val structures.  */
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.223
diff -c -3 -p -r1.223 gcse.c
*** gcse.c	19 Nov 2002 19:26:53 -0000	1.223
--- gcse.c	2 Dec 2002 21:12:03 -0000
*************** do_local_cprop (x, insn, alter_jumps, li
*** 4278,4283 ****
--- 4278,4286 ----
  	  rtx this_rtx = l->loc;
  	  rtx note;
  
+ 	  if (l->in_libcall)
+ 	    continue;
+ 
  	  if (CONSTANT_P (this_rtx))
  	    newcnst = this_rtx;
  	  if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]