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]

combine.c handling of SHIFT_COUNT_TRUNCATED


Immediately before combine, I have the following RTL:

(insn/i 41 40 42 (set (reg:DI 177)
        (zero_extend:DI (reg/v:SI 159))) 114 {zero_extendsidi2} (insn_list 6 (nil))
    (expr_list:REG_DEAD (reg/v:SI 159)
        (nil)))

(insn/i 42 41 43 (set (reg:V2SI 178)
        (ashift:V2SI (reg:V2SI 176)
            (reg:DI 177))) 358 {ashlv2si3} (insn_list 40 (insn_list 41 (nil)))
    (expr_list:REG_DEAD (reg:V2SI 176)
        (expr_list:REG_DEAD (reg:DI 177)
            (nil))))

SHIFT_COUNT_TRUNCATED is defined for my target (SH-5),
so I'd like the zero_extend to be removed.
There's code in combine.c to do this, but it is not working
for this case.  I've been trying to figure out why.

The code in combine.c is:

case ASHIFT:
      ...
#ifdef SHIFT_COUNT_TRUNCATED
      else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG)
	SUBST (XEXP (x, 1),
	       force_to_mode (XEXP (x, 1), GET_MODE (x),
			      ((HOST_WIDE_INT) 1
			       << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x))))
			      - 1,
			      NULL_RTX, 0));
#endif

For my example, insn 41 is substituted into insn 42 at the
time this code is reached.  The second argument in the call to
force_to_mode is V2SImode, which is not a very sensible mode
for a shift count (not for my target, anyway).
All the ashift patterns for my target expect a Dimode shift count,
no shift count of V2SImode will ever match, and so the
substitution will fail to match anything.

What I can't understand is why is the mode passed in to
force_to_mode is the mode of the expression being shifted,
surely this will fail to work whenever shift patterns use
different modes for the value being shifted and the shift count?

As an experiment, I changed the second argument to force_to_mode
to be the mode of the shift count rather than the mode of
the expression being shifted, as follows:

*** 4656,4662 ****
  #ifdef SHIFT_COUNT_TRUNCATED
        else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG)
        SUBST (XEXP (x, 1),
!              force_to_mode (XEXP (x, 1), GET_MODE (x),
                              ((HOST_WIDE_INT) 1
                               << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x))))
                              - 1,
--- 4656,4662 ----
  #ifdef SHIFT_COUNT_TRUNCATED
        else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG)
        SUBST (XEXP (x, 1),
!              force_to_mode (XEXP (x, 1), GET_MODE ( XEXP (x, 1)),
                              ((HOST_WIDE_INT) 1
                               << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x))))
                              - 1,

and with this, combine.c does remove the zero-extend.

What is the rationale for the second argument to force_to_mode?

Thanks,
Steve.


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