Hi all, Some ISAs have instructions to perform a bitwise AND operation with an immediate and compare the result with zero. For example, the aarch64 TST instruction. This is represented naturally in the MD file as:
(define_insn "*and<mode>3nr_compare0" [(set (reg:CC_NZ CC_REGNUM) (compare:CC_NZ (and:GPI (match_operand:GPI 0 "register_operand" "%r,r") (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>")) (const_int 0)))] "" "tst\\t%<w>0, %<w>1" [(set_attr "type" "logics_reg,logics_imm")] ) However, when the immediate operand of the AND is all ones, combine transforms that into a zero_extract. For example, the testcase is on aarch64: void g (); void f1 (int x) { if (x & 15) g (); } We're trying to combine the insns: (insn 6 3 7 2 (set (reg:SI 75) (and:SI (reg/v:SI 74 [ x ]) (const_int 15 [0xf]))) cbz.c:7 460 {andsi3} (expr_list:REG_DEAD (reg/v:SI 74 [ x ]) (nil))) (insn 7 6 8 2 (set (reg:CC 66 cc) (compare:CC (reg:SI 75) (const_int 0 [0]))) cbz.c:7 385 {*cmpsi} (expr_list:REG_DEAD (reg:SI 75) (nil))) followed by a conditional branch: (jump_insn 8 7 9 2 (set (pc) (if_then_else (eq (reg:CC 66 cc) (const_int 0 [0])) (label_ref:DI 14) (pc))) cbz.c:7 7 {condjump} combine attempts to match the pattern: (set (reg:CC 66 cc) (compare:CC (zero_extract:DI (reg:DI 0 x0 [ x ]) (const_int 4 [0x4]) (const_int 0 [0])) (const_int 0 [0]))) and fails. This fails, first because our pattern matches the and-immediate form, not the zero_extract form. The change_zero_ext step at the end of combine can't fix the damage because earlier in simplify_set when we called SELECT_CC_MODE on the COMPARE and its use in the conditional branch the aarch64 implementation of SELECT_CC_MODE doesn't handle the ZERO_EXTRACT form to return the CC_NZ form that the pattern needs, so the change_zero_ext code can transform the zero_extract back into the AND-immediate but it doesn't have the context to fix the CC mode. Is there a good way to fix this? It would seem rather weird to have extra MD patterns to match the zero_extract forms explicitly. Maybe teaching the aarch64 implementation of SELECT_CC_MODE to handle ZERO_EXTRACTS the same as AND-immediates? Or is there something that can be done in combine itself? Thanks, Kyrill