OSDN Git Service

* gcc.c-torture/compile/20021120-1.c: New test.
[pf3gnuchains/gcc-fork.git] / gcc / gcse.c
index fbe3fcb..9e4cccb 100644 (file)
@@ -4054,7 +4054,9 @@ cprop_jump (bb, setcc, jump, from, src)
 
   /* First substitute in the INSN condition as the SET_SRC of the JUMP,
      then substitute that given values in this expanded JUMP.  */
-  if (setcc != NULL)
+  if (setcc != NULL
+      && !modified_between_p (from, setcc, jump)
+      && !modified_between_p (src, setcc, jump))
     {
       rtx setcc_set = single_set (setcc);
       new_set = simplify_replace_rtx (SET_SRC (set),
@@ -4068,7 +4070,7 @@ cprop_jump (bb, setcc, jump, from, src)
 
   /* If no simplification can be made, then try the next
      register.  */
-  if (rtx_equal_p (new, new_set))
+  if (rtx_equal_p (new, new_set) || rtx_equal_p (new, SET_SRC (set)))
     return 0;
 
   /* If this is now a no-op delete it, otherwise this must be a valid insn.  */
@@ -4076,6 +4078,11 @@ cprop_jump (bb, setcc, jump, from, src)
     delete_insn (jump);
   else
     {
+      /* Ensure the value computed inside the jump insn to be equivalent
+         to one computed by setcc.  */
+      if (setcc 
+         && modified_in_p (new, setcc))
+       return 0;
       if (! validate_change (jump, &SET_SRC (set), new, 0))
        return 0;
 
@@ -4244,6 +4251,7 @@ cprop_insn (insn, alter_jumps)
 
 /* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall;
    their REG_EQUAL notes need updating.  */
+
 static bool
 do_local_cprop (x, insn, alter_jumps, libcall_sp)
      rtx x;
@@ -4253,10 +4261,12 @@ do_local_cprop (x, insn, alter_jumps, libcall_sp)
 {
   rtx newreg = NULL, newcnst = NULL;
 
-  /* Rule out USE instructions and ASM statements as we don't want to change the hard registers mentioned.  */
+  /* Rule out USE instructions and ASM statements as we don't want to
+     change the hard registers mentioned.  */
   if (GET_CODE (x) == REG
       && (REGNO (x) >= FIRST_PSEUDO_REGISTER
-          || (GET_CODE (PATTERN (insn)) != USE && asm_noperands (PATTERN (insn)) < 0)))
+          || (GET_CODE (PATTERN (insn)) != USE
+             && asm_noperands (PATTERN (insn)) < 0)))
     {
       cselib_val *val = cselib_lookup (x, GET_MODE (x), 0);
       struct elt_loc_list *l;
@@ -5284,7 +5294,7 @@ gcse_emit_move_after (src, dest, insn)
   else
     eqv = SET_SRC (set);
 
-  set_unique_reg_note (new, REG_EQUAL, copy_insn_1 (src));
+  set_unique_reg_note (new, REG_EQUAL, copy_insn_1 (eqv));
 
   return new;
 }