Richard Henderson <richard.hender...@linaro.org> writes: > 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?
Yeah, looks awkward. There isn't AFAICT any way to describe the full NZCV result of SBCS as a compare, in the case where C is possibly zero. So I guess if we're going to continue using compare then we need to cook up a new mode like you say. How important is it to describe the flags operation as a compare though? Could we instead use an unspec with three inputs, and keep it as :CC? That would still allow special-case matching for zero operands. Thanks, Richard