On Tue, Aug 12, 2014 at 12:31 PM, Kyrill Tkachov <kyrylo.tkac...@arm.com> wrote:
>
> On 12/08/14 10:39, Richard Biener wrote:
>>
>> On Mon, Aug 11, 2014 at 9:56 PM, Jeff Law <l...@redhat.com> wrote:
>>>
>>> On 08/11/14 07:41, Kyrill Tkachov wrote:
>>>>
>>>>
>>>> I haven't been able to get combine to match the comparison+xor+neg+plus
>>>> RTL and it seems like it would be just a workaround to undo the
>>>> tree-level transformation.
>>>
>>> Yea, it'd just be a workaround, but it's probably the easiest way to deal
>>> with this problem.  Can you describe in further detail why you weren't
>>> able
>>> to get this to work?
>>
>> Too many instructions to combine I guess.  You might want to add
>> intermediate "combine" insn-and-splits.  If that's still a no-go then
>> read on.
>
>
> From the combine dump I can see that it tried to combine up to:
> (set (reg/i:SI 0 x0)
>     (plus:SI (xor:SI (neg:SI (reg:SI 84 [ D.2565 ]))
>             (reg:SI 73 [ D.2564 ]))
>         (reg:SI 84 [ D.2565 ])))
>
> What I need is for that reg 84 to be the result of the comparison, something
> like:
> (ne (cc_reg) (const_int 0)) which I couldn't get combine to shove in there.
>
>
> On the other hand, I did manage to write a peephole2 that detected the
> sequence of compare+neg+xor+plus and transformed it into the if_then_else
> form that our current conditional negation pattern has, although I'm not
> sure how flexible this is.
>
>
>>
>> OTOH a suitable place to "undo" would be smarter RTL expansion
>> that detects this pattern (and hope for TER to still apply - thus
>> no CSE opportunities going in your way).  For your testcase TER
>> allows
>>
>> r_5 replace with --> r_5 = (int) _4;
>>
>> _8 replace with --> _8 = _4 != 0;
>>
>> _10 replace with --> _10 = -_9;
>>
>> _11 replace with --> _11 = _10 ^ r_5;
>>
>> _12 replace with --> _12 = _11 + _9;
>>
>> which unfortunately already "breaks" because of the multi-use _9
>> and _4.
>>
>> Now - the way out here is a GIMPLE pass right before expansion
>> that performs pattern detection and generates target specific code
>> suitable
>> for optimal expand.  Fortunately we already have that with
>> pass_optimize_widening_mul (which does widen-mul and fma detection).
>
>
> Maybe we can piggyback on this pass then? (probably renaming it to something
> more generic in the process...)
>
>
>>
>> This is the place where you'd deal with such pattern, generating
>> a suitable compound operation (or two, dependent on expansion
>> and insn pattern details).  This of course usually requires new
>> tree codes or internal functions.  For more arcane stuff like
>> your conditional negate I'd prefer an internal function.
>
>
> What is an internal function in this context? Is that like a target-specific
> builtin?
>
>
>>
>> Of course you then have to add an optab or a target hook to
>> do custom internal function expansion.  I suppose for internal
>> functions a target hook would be nicer than a generic optab?
>
>
> So something like TARGET_EXPAND_CONDITIONAL_NEGATION that gets called from
> the aforementioned GIMPLE pass when it finds a an appropriate sequence of
> compare+neg+xor+plus ?

More like TARGET_CAN_EXPAND_IFN with the new GIMPLE internal-fn
and a TARGET_EXPAND_IFN to actually perform the expansion.

Richard.

> Thanks for the pointers,
> Kyrill
>
>
>>
>> Thanks,
>> Richard.
>>
>>
>>
>>>> What is the most acceptable way of disabling this transformation for a
>>>> target that has a conditional negation instruction?
>>>
>>> In general, we don't want target dependencies in the gimple/ssa
>>> optimizers.
>>>
>>> Jeff
>
>
>

Reply via email to