I am not familiar how to use define_subst, so I write a patch that
changes define_insn_and_split to define_insn. bootstrapped and
regression tested on x86_64-unknown-linux-gnu.

A question is: after that change, Is there anyway I can make
targetm.rtx_costs() aware about the truncation, .i.e the cost is only
a "shift" instead of "shift + and".

Thanks,
Wei.

On Tue, Mar 26, 2013 at 11:23 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Tue, Mar 26, 2013 at 10:14 AM, Richard Biener
> <richard.guent...@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.

Attachment: changelog
Description: Binary data

Attachment: patch
Description: Binary data

Reply via email to