This is the mail archive of the 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]

Re: Handle fabs(x) UNGE 0.0

On Monday, May 5, 2003, at 01:20 PM, Roger Sayle wrote:

On Mon, 5 May 2003, Geoffrey Keating wrote:
A related unreviewed patch (that correctly uses const_true_rtx now
that I'm older, wiser and more more fluent in GCC's incantations) is:
This patch has the nice habit of defensively fixing const1_rtx into
const_true_rtx in many of the RTL optimizers.

What happens if you write this instead as

if (x == const0_rtx)
   return const0_rtx;

The code will abort when we try to CSE a true condition, of course :> The related "return (x == const0_rtx)? const0_rtx : NULL_RTX;" would atleast allow us to propagate condition codes that are false.

I don't understand how a true condition corresponds to a nonzero CCmode constant. Can you explain?

I don't think it makes sense to be forcing non-zero values into CCmode,
and if it is possible then it's certainly machine-specific as to what
it might mean. Note that CCmode values are *not* single bits, that's
BImode; the only way you can have a CCmode constant is in an expression

(eq (reg:CC 123) (const_int 0))

which really means 'test the EQ bit of register 123'; no comparison is

Yes, the only thing that is important to CCmode is whether the value
is zero or not. But it is still important that we're able to record the
"not". This is slightly different from BImode, where the values are
const0_rtx and const1_rtx, based on the least significant bit. For
CCmodes, all non-zero values are equivalent and are canonicalized to

To extend your example consider:

  (set (reg:CC 123) (unge:CC (abs:DF ...) (const_double 0.0))
  ... (eq (reg:CC 123) (const_int 0))

Um, the compiler shouldn't do that. It does

(set (reg:CC 123) (compare:DF (abs:DF ...) (const_double 0.0)))
... (eq (reg:CC 123) (const_int 0))

or it does

(set (reg:DI 123) (unge:DI (abs:DF ...) (const_double 0.0)))

it doesn't use a sCC operation that has a result of CCmode, any more than it would use an add operation that has a result of CCmode.

we can now simplify the first insn, thanks to your patch to:

  (set (reg:CC 123) (const_int 1))       /* or (const_int -1) */
  ... (eq (reg:CC 123) (const_int 0))

The problem now is that CSE is unable to propagate this new assignment into the next expression because CSE calls for gen_lowpart_common on all integer constants to truncate them to the mode being CSE'd, which in this case is CCmode.

Ultimately, on some architectures include PA-Risc with current CVS, we
end up with an instruction that always sets the condition code to true
or false, followed immediately by a conditional jump.  Fortunately, my
patches to combine clean this up, but it would greatly improve the RTL
optimizations if this could be done by CSE/GCSE.

I hope this helps explain the motivation for the patch.

-- Geoff Keating <>

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