On 3/31/20 11:34 AM, Richard Sandiford wrote: >> +(define_insn "*<ANY_EXTEND:su>cmp<GPI:mode>3_carryinC" >> + [(set (reg:CC CC_REGNUM) >> + (compare:CC >> + (ANY_EXTEND:<DWI> >> + (match_operand:GPI 0 "register_operand" "r")) >> + (plus:<DWI> >> + (ANY_EXTEND:<DWI> >> + (match_operand:GPI 1 "register_operand" "r")) >> + (match_operand:<DWI> 2 "aarch64_borrow_operation" ""))))] >> + "" >> + "sbcs\\t<w>zr, %<w>0, %<w>1" >> + [(set_attr "type" "adc_reg")] >> +) > > I guess this feeds into your reply to Segher's comment for 7/9, > but I think: > > (compare:CC X Y) > > is always supposed to be the NZCV flags result of X - Y, as computed in > the mode of X and Y. If so, it seems like the type of extension should > matter. E.g. the N flag ought to be set for: > > (compare:CC > (sign_extend 0xf...) > (plus (sign_extend 0x7...) > (ltu ...))) > > but ought to be clear for: > > (compare:CC > (zero_extend 0xf...) > (plus (zero_extend 0x7...) > (ltu ...))) > > If so, I guess this is a bug in the existing code...
The subject of CCmodes is a sticky one. It mostly all depends on what combine is able to do with the patterns. For instance, your choice of example above, even for signed, the N bit cannot be examined by itself, because that would only be valid for a comparison against zero, like (compare (plus (reg) (reg)) (const_int 0)) For this particular bit of rtl, the only valid comparison is N == V, i.e. GE/LT. If we add a new CC mode for this, what would you call it? Probably not CC_NVmode, because to me that implies you can use either N or V, but it doesn't imply you must examine both. If we add more CC modes, does that mean that we have to improve SELECT_CC_MODE to match those patterns? Or do we add new CC modes just so that combine's use of SELECT_CC_MODE *cannot* match them? r~