extend fwprop optimization

Uros Bizjak ubizjak@gmail.com
Tue Mar 26 18:23:00 GMT 2013


On Tue, Mar 26, 2013 at 10:14 AM, Richard Biener
<richard.guenther@gmail.com> wrote:
>>> I am trying to figure out a way not to lose the opportunity when shift
>>> truncation is not combined in a bit test pattern. Can we keep the
>>> explicit truncation in RTL, but generate truncation code in assembly?
>>> Then only shift truncation which not combined in a bit test
>>> pattershift truncationn will happen.
>>>
>>> (define_insn "*<shift_insn_and><mode>"
>>>   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
>>>         (any_shiftrt:SWI48
>>>           (match_operand:SWI48 1 "nonimmediate_operand" "0")
>>>           (subreg:QI
>>>             (and:SI
>>>               (match_operand:SI 2 "nonimmediate_operand" "c")
>>>               (match_operand:SI 3 "const_int_operand" "n")) 0)))
>>>    (clobber (reg:CC FLAGS_REG))]
>>>   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
>>> {
>>>    if ((INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
>>>       == GET_MODE_BITSIZE (<MODE>mode)-1)
>>>       return "and\t{%3, %2|%2, %3}\n\r shift\t{%b2, %0|%0, %b2}";
>>>    else
>>>       "shift\t{%2, %0|%0, %2}";
>>> }
>>
>> Sorry, rectify a mistake:
>>
>> {
>>    if ((INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
>>       == GET_MODE_BITSIZE (<MODE>mode)-1)
>>       return "shift\t{%2, %0|%0, %2}";
>>    else
>>       return "and\t{%3, %2|%2, %3}\n\r shift\t{%b2, %0|%0, %b2}";
>> }
>
> I'm not sure the existing patterns are wrong because SHIFT_COUNT_TRUNCATED
> is false for x86 AFAIK, exactly because of the bit-test vs. shift instruction
> differences.  So there is no inconsistency.  The i386 backend seems to
> try to follow my suggestion as if SHIFT_COUNT_TRUNCATED didn't exist
> (well, it's false, so it technically doesn't exist for i386) and recognizes
> the shift with truncate with the *<shift_insn><mode>3_mask splitter.
> But I'm not sure why it bothers to do it with a splitter instead of just
> with a define_insn?  Because the split code,
>
>   [(parallel [(set (match_dup 0)
>                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
>               (clobber (reg:CC FLAGS_REG))])]
>
> is wrong and could be combined into a bit-test instruction.  No?
>
> That is, why not have define_insn variants for shift instructions with
> explicit truncation?

You are right, the split is harmful in this case.

It looks to me, that explicit truncation can be added to split
patterns in the most elegant way using proposed "define_subst"
infrastructure.

Uros.



More information about the Gcc-patches mailing list