Canonicalization of compares performed as side-effect operations

Richard Earnshaw (lists) Richard.Earnshaw@arm.com
Tue Aug 6 15:43:00 GMT 2019


Arm has an instruction that performs the following operation:

(parallel [
         (set (reg:CC 100 cc)
             (compare:CC (const_int 0 [0])
                 (reg:SI 121)))
         (set (reg:SI 113)
             (neg:SI (reg:SI 121)))
     ])

This is simply a reverse subtract from the constant zero, and setting 
the condition flags.  It's the low part of a negdi2 expansion.

However, combine will rip this up and try to transform the compare into 
'canonical' form, ie

(parallel [
         (set (reg:CC 100 cc)
             (compare:CC (reg:SI 121)
                 (const_int 0 [0])))
         (set (reg:SI 113)
             (neg:SI (reg:SI 121)))
     ])

(and obviously swapping the condition on the instruction that uses the 
comparison result).

This, of course, doesn't match the behaviour of the instruction and 
no-longer matches the pattern in the md file.

SELECT_CC_MODE won't help me: the compare looks just like a simple 
comparison that the machine supports, so it can't return a different 
mode to allow me to fix things up.

I can't just stop the canonicalization: it's done in simplify_set and 
the wider context of the instruction simply isn't available.  If there 
is no wider context (ie the comparison is not part of a parallel), then 
the simplification is probably the right thing to do.

There are comments in combine.c (see for example just above the call to 
target_canonicalize_comparison in try_combine) that suggest that this 
sort of simplification should not be done, but it's clearly not being 
done consistently.

So is there a way to describe this instruction within the compiler, or a 
way to stop simplify_set from making this sort of simplification?  I was 
wondering if we might somehow annotate the compare (perhaps by setting 
the volatile bit) to indicate that the comparison was being done as a 
side-effect of another operation and that therefore swapping was not 
permitted.

R.



More information about the Gcc-patches mailing list