https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94037
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #2) > The > setge %sil > movzbl %sil, %esi > to > xorl %esi, %esi > setge %sil > transformation is something GCC does too with the > ;; Convert setcc + movzbl to xor + setcc if operands don't overlap. > peephole2s. > The reason it doesn't trigger here is that the single comparison has 3 uses > (why not 2 and something didn't CSE those?). > So, at least for the two setcc quite long after cmp case, we might need to > either not have the comparison in the peephole2 and instead walk backwards, > looking for the FLAGS_REG setter (or stopping on something that clobbers it) > and stopping on if the register we'd want to xor first is mentioned by any > insn in between. > We have at the start of peephole2: > (insn 37 36 38 5 (set (reg:CCGC 17 flags) > (compare:CCGC (reg/v:SI 1 dx [orig:86 pivot ] [86]) > (reg:SI 0 ax [orig:242 pretmp_404 ] [242]))) "pr94037.C":6:19 11 > {*cmpsi_1} > (expr_list:REG_DEAD (reg:SI 0 ax [orig:242 pretmp_404 ] [242]) > (nil))) > (note 38 37 39 5 NOTE_INSN_DELETED) > (note 39 38 1178 5 NOTE_INSN_DELETED) > (insn 1178 39 1179 5 (set (reg:QI 2 cx [288]) > (lt:QI (reg:CCGC 17 flags) > (const_int 0 [0]))) "pr94037.C":6:21 732 {*setcc_qi} > (nil)) > (insn 1179 1178 41 5 (set (reg:DI 2 cx [288]) > (zero_extend:DI (reg:QI 2 cx [288]))) "pr94037.C":6:21 115 > {zero_extendqidi2} > (nil)) > (insn 41 1179 42 5 (set (reg:SI 2 cx [289]) > (mem:SI (plus:DI (plus:DI (mult:DI (reg:DI 2 cx [288]) > (const_int 4 [0x4])) > (reg/f:DI 7 sp)) > (const_int 120 [0x78])) [1 MEM[(int[2] *)_213] S4 A32])) > "pr94037.C":6:15 67 {*movsi_internal} > (expr_list:REG_EQUIV (mem:SI (reg/v/f:DI 36 r8 [orig:283 begin ] [283]) > [1 *begin_329+0 S4 A32]) > (nil))) > (insn 42 41 45 5 (set (mem:SI (reg/v/f:DI 36 r8 [orig:283 begin ] [283]) [1 > *begin_329+0 S4 A32]) > (reg:SI 2 cx [289])) "pr94037.C":6:15 67 {*movsi_internal} > (expr_list:REG_DEAD (reg:SI 2 cx [289]) > (nil))) > (note 45 42 1180 5 NOTE_INSN_DELETED) > (insn 1180 45 1181 5 (set (reg:QI 0 ax [290]) > (ge:QI (reg:CCGC 17 flags) > (const_int 0 [0]))) "pr94037.C":15:10 732 {*setcc_qi} > (expr_list:REG_DEAD (reg:CCGC 17 flags) > (nil))) > (insn 1181 1180 47 5 (set (reg:DI 0 ax [290]) > (zero_extend:DI (reg:QI 0 ax [290]))) "pr94037.C":15:10 115 > {zero_extendqidi2} > (nil)) > and current peephole2 manages to handle the first setcc+movzbl. The second > one actually isn't doable because of the RA decisions, as the comparison > uses ax and we'd need to clear rax before the comparison. > Similarly, in partition we have 3 setcc+movzbls, but the first one has the > movzbl not adjacent to the setcc, second one would be doable if the > peephole2 pattern didn't include the FLAGS_REG setter and walked back and > the third one isn't doable because the comparison uses cx, i.e. the register > that's set by setcc and extended by movzbl. > > Now, on the GIMPLE level, we have e.g. in partition: > _2 = MEM[base: right_35, offset: 0B]; > _3 = _2 <= pivot_12; > _4 = (int) _3; > _19 = *left_31; > _7 = {_19, _2}; > MEM <vector(2) int> [(int *)&v] = _7; > _21 = v[_4]; > *left_31 = _21; > _22 = _2 > pivot_12; > _23 = (int) _22; > _24 = v[_23]; > MEM[base: right_35, offset: 0] = _24; > v ={v} {CLOBBER}; > _5 = _2 <= pivot_12 ? 4 : 0; > so I wonder why sccvn has not at least replaced the last _2 <= pivot_12 with > _3. > And, if SCCVN could be taught that if we have _3 = _2 <= pivot_12 and later > _22 = _2 > pivot_12, we can simplify the latter to _22 = 1 - _3; > 1 - VN has a hard time hee because _2 <= pivot_12 has no def and thus isn't value-numbered independently (IIRC I had some local hacks trying to fix this but thought we should fix GIMPLE isntead). VN also does not open-code the GENERIC compare which makes the special-casing even more ugly... That said, it _could_ be fixed during elimination by looking up the condition operand but then IIRC at least for VEC_COND_EXPR we don't really like CSEing the conditions even if they are available in a SSA name.