------- Comment #31 from danglin at gcc dot gnu dot org  2006-07-31 18:29 
-------
The bug arises in simplifying this instruction in cse2:

(insn 141 140 142 11 builtin-bitops-2.c:10 (set (reg:SI 176)
        (ashift:SI (reg:SI 139)
            (minus:SI (const_int 31 [0x1f])
                (reg:SI 183)))) 178 {zvdep32} (nil)
    (expr_list:REG_EQUAL (ashift:SI (reg:SI 139)
            (reg:SI 169))

The constant portion of the shift simplifies to "-1":

(gdb) p debug_rtx (const_arg1)
(const_int -1 [0xffffffff])
We have a previous shift of "1":

(gdb) p debug_rtx (inner_const)
(const_int 1 [0x1])

In my opinion, the combined two shifts are larger than the size
of the object (32 bits).  However, the code in cse.c for associating
shifts generates the following new constant:

(gdb) p debug_rtx (new_const)
(const_int 0 [0x0])

The check in cse.c fails to detect this case:

              /* If we are associating shift operations, don't let this
                 produce a shift of the size of the object or larger.
                 This could occur when we follow a sign-extend by a right
                 shift on a machine that does a sign-extend as a pair
                 of shifts.  */

              if (is_shift && GET_CODE (new_const) == CONST_INT
                  && INTVAL (new_const) >= GET_MODE_BITSIZE (mode))
                {
                  /* As an exception, we can turn an ASHIFTRT of this
                     form into a shift of the number of bits - 1.  */
                  if (code == ASHIFTRT)
                    new_const = GEN_INT (GET_MODE_BITSIZE (mode) - 1);
                  else
                    break;
                }

So, the above check would appear to need fixing.  Note that
SHIFT_COUNT_TRUNCATED is defined on this target and the
effect of the two shifts is actually a ASHIFT of 32.

Also, I would think that a ASHIFT larger than the size of the object should
produce a zero result.  This might be considered as an enhancement.  There
are probably some other special cases.

Roger, I added your name to the CC list since I thought that you would be
interested in this bug.


-- 

danglin at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |roger at eyesopen dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26244

Reply via email to