[RTL] canonical form of AND-immediate within COMPARE?

Kyrill Tkachov kyrylo.tkachov@arm.com
Thu Dec 3 14:49:00 GMT 2015


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





More information about the Gcc-patches mailing list