This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix to ARM problem without pessimizing RS/6000
- To: gcc-patches at gcc dot gnu dot org
- Subject: Fix to ARM problem without pessimizing RS/6000
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- Date: Wed, 21 Mar 01 15:31:24 EST
Mark and RTH and I have been working on this patch, which I committed to
both the mainline and branch. I tested on the mainline on Alpha and
on the branch with x86.
Wed Mar 21 14:27:11 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* cse.c (find_comparison_args): Remove previous change.
* ifcvt.c (noce_process_if_block): When moving an insn, remove any
REG_EQUAL notes.
*** cse.c 2001/03/19 18:53:03 1.179
--- cse.c 2001/03/21 19:07:43
*************** find_best_addr (insn, loc, mode)
*** 3087,3109 ****
}
! /* This routine accepts a comparison as input and attempts to return a
! comparision that is cheaper to compute.
! On input, *PARG1 and *PARG2 should be set to the first and second
! arguments to the comparison, respectively. CODE is the comparision
! code. For example, if the comparison is:
!
! (ne:SI (reg:CC 24 cc)
! (const_int 0 [0x0])))
!
! The CODE should be NE, *PARG1 should be `(reg:CC 24 cc)' and
! *PARG2 should be `(const_int 0)'.
!
! Upon return, *PARG1 and and *PARG2 may have new values, indicating
! arguments to a cheaper comparison. *PMODE1 and *PMODE2 will be the
! modes that should be used for those arguments. The return value
! itself will be the comparison code that should be used to compare
! *PARG1 and *PARG2 in order to obtain a value equivalent to that
! given by the original comparison. */
static enum rtx_code
--- 3087,3101 ----
}
! /* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison
! operation (EQ, NE, GT, etc.), follow it back through the hash table and
! what values are being compared.
!
! *PARG1 and *PARG2 are updated to contain the rtx representing the values
! actually being compared. For example, if *PARG1 was (cc0) and *PARG2
! was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were
! compared to produce cc0.
! The return value is the comparison operator and is either the code of
! A or the code corresponding to the inverse of the comparison. */
static enum rtx_code
*************** find_comparison_args (code, parg1, parg2
*** 3196,3231 ****
continue;
! /* `(COMPARE A B) != 0)' is equivalent to `(COMPARE A B)'.
! If CODE is EQ, rather than NE, then we are out of luck;
! there is no way to reverse the sense of a COMPARE. */
! if (code == NE && GET_CODE (p->exp) == COMPARE)
! {
! x = p->exp;
! break;
! }
! /* Another possibility is that this machine has a compare
! insn that includes the comparison code. In that case,
! ARG1 would be equivalent to a comparison operation that
! would set ARG1 to either STORE_FLAG_VALUE or zero. If
! this is an NE operation, ORIG_CODE is the actual
! comparison being done; if it is an EQ, we must reverse
! ORIG_CODE. On machine with a negative value for
! STORE_FLAG_VALUE, also look at LT and GE operations. */
! else if ((code == NE
! || (code == LT
! && GET_MODE_CLASS (inner_mode) == MODE_INT
! && (GET_MODE_BITSIZE (inner_mode)
! <= HOST_BITS_PER_WIDE_INT)
! && (STORE_FLAG_VALUE
! & ((HOST_WIDE_INT) 1
! << (GET_MODE_BITSIZE (inner_mode) - 1))))
#ifdef FLOAT_STORE_FLAG_VALUE
! || (code == LT
! && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
! && (REAL_VALUE_NEGATIVE
! (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)))))
#endif
! )
! && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')
{
x = p->exp;
--- 3188,3215 ----
continue;
! if (GET_CODE (p->exp) == COMPARE
! /* Another possibility is that this machine has a compare insn
! that includes the comparison code. In that case, ARG1 would
! be equivalent to a comparison operation that would set ARG1 to
! either STORE_FLAG_VALUE or zero. If this is an NE operation,
! ORIG_CODE is the actual comparison being done; if it is an EQ,
! we must reverse ORIG_CODE. On machine with a negative value
! for STORE_FLAG_VALUE, also look at LT and GE operations. */
! || ((code == NE
! || (code == LT
! && GET_MODE_CLASS (inner_mode) == MODE_INT
! && (GET_MODE_BITSIZE (inner_mode)
! <= HOST_BITS_PER_WIDE_INT)
! && (STORE_FLAG_VALUE
! & ((HOST_WIDE_INT) 1
! << (GET_MODE_BITSIZE (inner_mode) - 1))))
#ifdef FLOAT_STORE_FLAG_VALUE
! || (code == LT
! && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
! && (REAL_VALUE_NEGATIVE
! (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)))))
#endif
! )
! && GET_RTX_CLASS (GET_CODE (p->exp)) == '<'))
{
x = p->exp;
*** ifcvt.c 2001/03/07 19:29:36 1.42
--- ifcvt.c 2001/03/21 19:08:05
*************** noce_process_if_block (test_bb, then_bb,
*** 1564,1570 ****
--- 1564,1578 ----
if (insn_b && else_bb)
{
+ rtx note;
+
if (else_bb && insn_b == else_bb->end)
else_bb->end = PREV_INSN (insn_b);
reorder_insns (insn_b, insn_b, PREV_INSN (if_info.cond_earliest));
+
+ /* If there was a REG_EQUAL note, delete it since it may have been
+ true due to this insn being after a jump. */
+ if ((note = find_reg_note (insn_b, REG_EQUAL, NULL_RTX)) != 0)
+ remove_note (insn_b, note);
+
insn_b = NULL_RTX;
}