Hello All,

    I compiled a very simple code on a Intel targets:

int a, b, c, d;

void func1(void)
{
  a = a & b;

  if(a)
   c = d;
}

The assembler generated was (on cygwin 32-bit):

        movl    _b, %eax
        andl    _a, %eax
        testl   %eax, %eax
        movl    %eax, _a
        je      L1
        movl    _d, %eax
        movl    %eax, _c
L1:
        ...

The result is similar for 64-bit code.

I understand we could optimize this to (hope not missing anything):

        movl    _b, %eax
        andl    %eax, _a
        je      L1
        movl    _d, %eax
        movl    %eax, _c
L1:
        ...

   I took a look at the insns just before "combine" pass and we have:

------------------------------------
(insn 5 2 6 2 (set (reg:SI 63 [ a ])
(mem/c/i:SI (symbol_ref:SI ("a") [flags 0x2] <var_decl 0x7ff6e760 a>) [2 a+0 S4 A32])) test.c:6 50 {*movsi_internal}
     (nil))

(insn 6 5 7 2 (set (reg:SI 64 [ b ])
(mem/c/i:SI (symbol_ref:SI ("b") [flags 0x2] <var_decl 0x7ff6e7c0 b>) [2 b+0 S4 A32])) test.c:6 50 {*movsi_internal}
     (nil))

(insn 7 6 8 2 (parallel [
            (set (reg:SI 61 [ a.2 ])
                (and:SI (reg:SI 64 [ b ])
                    (reg:SI 63 [ a ])))
            (clobber (reg:CC 17 flags))
        ]) test.c:6 290 {*andsi_1}
     (expr_list:REG_DEAD (reg:SI 64 [ b ])
        (expr_list:REG_DEAD (reg:SI 63 [ a ])
            (expr_list:REG_UNUSED (reg:CC 17 flags)
(expr_list:REG_EQUAL (and:SI (mem/c/i:SI (symbol_ref:SI ("b") [flags 0x2] <var_decl 0x7ff6e7c0 b>) [2 b+0 S4 A32]) (mem/c/i:SI (symbol_ref:SI ("a") [flags 0x2] <var_decl 0x7ff6e760 a>) [2 a+0 S4 A32]))
                    (nil))))))

(insn 8 7 9 2 (set (mem/c/i:SI (symbol_ref:SI ("a") [flags 0x2] <var_decl 0x7ff6e760 a>) [2 a+0 S4 A32])
        (reg:SI 61 [ a.2 ])) test.c:6 50 {*movsi_internal}
     (nil))

(insn 9 8 10 2 (set (reg:CCZ 17 flags)
        (compare:CCZ (reg:SI 61 [ a.2 ])
            (const_int 0 [0]))) test.c:8 2 {*cmpsi_ccno_1}
     (expr_list:REG_DEAD (reg:SI 61 [ a.2 ])
        (nil)))
-------------------------------------------

If I understood correct, gcc could replace insns 5, 7, 8 and 9 by the insn defined as "*and<mode>_2", but it seems "combine" did not tried that.

How gcc could perform such optimization (and similar ones) ? Is a peephole the most indicated to do that ?

  Well, I am new on gcc, so sorry if I am missing something.

best regards,
Alex Rocha Prado

Reply via email to