On Wed, Oct 14, 2020 at 03:17:03PM +0200, Uros Bizjak wrote: > > +(define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>" > > + [(set (reg:CCC FLAGS_REG) > > + (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))) > > + (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))] > > + "ix86_pre_reload_split ()" > > + "#" > > + "&& 1" > > + [(const_int 0)]) > > > > Hmm... does the above really represent a NOP?
It is just what combine.c + simplify-rtx.c make out of this. We have: (insn 10 9 11 2 (set (reg:QI 88 [ _31 ]) (ltu:QI (reg:CCC 17 flags) (const_int 0 [0]))) "include/adxintrin.h":69:10 785 {*setcc_qi} (expr_list:REG_DEAD (reg:CCC 17 flags) (nil))) and (insn 17 15 18 2 (parallel [ (set (reg:CCC 17 flags) (compare:CCC (plus:QI (reg:QI 88 [ _31 ]) (const_int -1 [0xffffffffffffffff])) (reg:QI 88 [ _31 ]))) (clobber (scratch:QI)) ]) "include/adxintrin.h":69:10 350 {*addqi3_cconly_overflow_1} (expr_list:REG_DEAD (reg:QI 88 [ _31 ]) (nil))) So when substituting (reg:QI 88) for (ltu:QI flags 0), we initially get: (compare:CCC (plus:QI (ltu:QI (reg:CCC 17 flags) (const_int [0])) (const_int -1 [0xffffffffffffffff])) (ltu:QI (reg:CCC 17 flags) (const_int [0]))) On this triggers simplify_binary_operation_1 rule: /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE is 1. */ if (COMPARISON_P (op0) && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx) || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx)) && (reversed = reversed_comparison (op0, mode))) return simplify_gen_unary (NEG, mode, reversed, mode); As STORE_FLAG_VALUE is 1 on i386, it triggers for that -1. Now, in CCCmode we have just 2 possible values, 0 and 1, CF clear and CF set. So, either (ltu:QI (reg:CCC 17 flags) (const_int 0 [0])) is 0, in that case (geu:QI (reg:CCC 17 flags) (const_int 0 [0])) is 1 and so (compare:CCC (neg:QI (geu:QI (reg:CCC FLAGS_REG) (const_int 0))) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))) is (compare:CCC (neg:QI (const_int 1 [0x1])) (const_int 0 [0])) which is (compare:CCC (const_int -1 [0xffffffffffffffff]) (const_int 0 [0])) Or (ltu:QI (reg:CCC 17 flags) (const_int 0 [0])) is 1, in that case (geu:QI (reg:CCC 17 flags) (const_int 0 [0])) is 0 and so (compare:CCC (neg:QI (geu:QI (reg:CCC FLAGS_REG) (const_int 0))) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))) is (compare:CCC (neg:QI (const_int 0 [0x0])) (const_int 1 [0x1])) which is (compare:CCC (const_int 0 [0]) (const_int 1 [0x1])) As CCCmode flags can be only used in LTU or GEU comparisons, we are asking if 0xffU < 0 (false, CF clear) or 0 < 1 (true, CF set). So I think the pattern is meaningful and is really a nop. Jakub