This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, rtl-optimization]: Enhance post-reload compare elimination pass to handle arithmetic operations with implicit extensions


Hello!

Back to converting x86 to post-reload compare elimination pass.

Arithmetic operations in x86_64 can implicitly zero extend the result,
and set flags according to the non-extended result. Following testcase
should exercise both features:

--cut here--
void foo (long int, int);

void test (unsigned int a, unsigned int b)
{
  long int x = a + b;
  int f = a + b > 0;

  foo (x, f);
}
--cut here--

However, with pre-reload implementation, gcc was able to merge
operation + compare, while ignoring implicit extension:

test:
        addl    %esi, %edi      # 8     *addsi_2/3
        setne   %sil    # 19    *setcc_qi
        movl    %edi, %edi      # 11    *zero_extendsidi2_rex64/1
        movzbl  %sil, %esi      # 20    *zero_extendqisi2
        jmp     foo     # 14    *sibcall

Unpatched post-reload compare elimination was able to merge operation
+ zero extension (please note that attached WIP target patch is
needed):

test:
        addl    %esi, %edi      # 7     addsi_1_zext/2
        xorl    %esi, %esi      # 22    *movsi_xor
        testl   %edi, %edi      # 23    *cmpsi_ccno_1/1
        setne   %sil    # 24    *setcc_qi_slp
        jmp     foo     # 14    *sibcall

And patched post-reload compare finally produces optimal code:

test:
        addl    %esi, %edi      # 7     *addsi_2_zext/2
        setne   %sil    # 19    *setcc_qi
        movzbl  %sil, %esi      # 20    *zero_extendqisi2
        jmp     foo     # 14    *sibcall

Where the operation looks like:

#(insn:TI 7 9 19 2 (parallel [
#            (set (reg:DI 5 di)
#                (zero_extend:DI (plus:SI (reg/v:SI 4 si [orig:64 b ] [64])
#                        (reg/v:SI 5 di [orig:63 a ] [63]))))
#            (set (reg:CCZ 17 flags)
#                (compare:CCZ (plus:SI (reg/v:SI 4 si [orig:64 b ] [64])
#                        (reg/v:SI 5 di [orig:63 a ] [63]))
#                    (const_int 0 [0])))
#        ]) cmpadd.c:5 261 {*addsi_2_zext}
#     (expr_list:REG_DEAD (reg/v:SI 4 si [orig:64 b ] [64])
#        (nil)))
        addl    %esi, %edi      # 7     *addsi_2_zext/2 [length = 2]

Attached patch teaches post-reload compare optimization how to handle
arithmetic operations with implicit extensions. The input is:

(insn 7 4 8 2 (parallel [
            (set (reg:DI 5 di)
                (zero_extend:DI (plus:SI (reg/v:SI 4 si [orig:64 b ] [64])
                        (reg/v:SI 5 di [orig:63 a ] [63]))))
            (clobber (reg:CC 17 flags))
        ]) cmpadd.c:5 253 {addsi_1_zext}
     (nil))

(insn 8 7 9 2 (set (reg:CCZ 17 flags)
        (compare:CCZ (reg:SI 5 di [orig:59 D.1714 ] [59])
            (const_int 0 [0]))) cmpadd.c:6 2 {*cmpsi_ccno_1}
     (nil))

It simply checks if REGNOs of registers are the same, the mode of the
compared register (against zero!) is checked to the mode of the inner
part of the extension instruction.

2012-04-24  Uros Bizjak  <ubizjak@gmail.com>

	* compare-elim.c (try_eliminate_compare): Also handle operands with
	implicit extensions.

Patch is lightly tested on x86_64-pc-linux-gnu, together with attached
WIP patch.

Opinions? Since it looks quite safe, is it OK for mainline?

Uros.

Attachment: p.diff.txt
Description: Text document

Attachment: x86-wip.diff.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]