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

Question about setting of fuller_mask in force_to_mode()


Can anybody explain these lines in force_to_mode() in combine.c?  In
the current sources, they are at line 6835.

  /* When we have an arithmetic operation, or a shift whose count we
     do not know, we need to assume that all bit the up to the highest-order
     bit in MASK will be needed.  This is how we form such a mask.  */
  if (op_mode)
    fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
		   ? GET_MODE_MASK (op_mode)
		   : (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1))
		      - 1));
  else
    fuller_mask = ~(HOST_WIDE_INT) 0;

I have a test case where the code is converting to HImode with a mask
of 0xffff, which seems fairly normal to me.  I'm looking at both ARM
and MIPS systems.  I'm compiling on a 32 bit system.  The instruction
in question is a `plus:SI'.

For both MIPS and ARM, op_mode gets set to SImode at line 6821, since
there is no addhi3 insn.

When compiling for MIPS, HOST_BITS_PER_WIDE_INT is 64.  This is
because need_64bit_hwint=yes is set for all MIPS targets.  In this
case, the above code sees that GET_MODE_BITSIZE (SImode) is not >=
HOST_BITS_PER_WIDE_INT, so it sets fuller_mask based on mask (0xffff)
and gets a value of 0xffff.

When compiling for ARM, HOST_BITS_PER_WIDE_INT is 32.  In this case,
the above code sets fuller_mask to GET_MODE_MASK (SImode), which is
0xffffffff.

It seems to me that the setting of fuller_mask should not depend upon
HOST_BITS_PER_WIDE_INT in this way.

This code hasn't been changed since egcs was started.  I don't know if
there is any older RCS history anywhere these days.

Based on the comment above the setting of fuller_mask, and the fact
that mask is unsigned HOST_WIDE_INT, it seems to me that this code can
simply become something like this:

  if (mask & ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)))
    fuller_mask = ~(unsigned HOST_WIDE_INT) 0;
  else
    fuller_mask = (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1)) - 1);

I don't see the relevance of checking op_mode at all.

Before I really dig into this, does anybody quickly see why this
argument is wrong?

Ian


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