Hi, For lea + zero_extendsidi insns, if dest of lea and src of zext are the same, combine them with single leal under 64bit target since 32bit register will be automatically zero-extended.
Bootstrapped and regtested on x86_64-linux-gnu{-m32,}. Ok for master? gcc/ChangeLog: PR target/101716 * config/i386/i386.md (*lea<mode>_zext): New define_insn. (define_peephole2): New peephole2 to combine zero_extend with lea. gcc/testsuite/ChangeLog: PR target/101716 * gcc.target/i386/pr101716.c: New test. --- gcc/config/i386/i386.md | 20 ++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr101716.c | 11 +++++++++++ 2 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr101716.c diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 4a8e8fea290..6739dbd799b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -5187,6 +5187,26 @@ (const_string "SI") (const_string "<MODE>")))]) +;; combine zero_extendsidi with lea to use leal. +(define_insn "*lea<mode>_zext" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (match_operand:SWI48 1 "address_no_seg_operand" "Ts")))] + "TARGET_64BIT" + "lea{l}\t{%E1, %k0|%k0,%E1}") + +(define_peephole2 + [(set (match_operand:SWI48 0 "general_reg_operand") + (match_operand:SWI48 1 "address_no_seg_operand")) + (set (match_operand:DI 2 "general_reg_operand") + (zero_extend:DI (match_operand:SI 3 "general_reg_operand")))] + "TARGET_64BIT && ix86_hardreg_mov_ok (operands[2], operands[1]) + && REGNO (operands[0]) == REGNO (operands[3]) + && (REGNO (operands[2]) == REGNO (operands[3]) + || peep2_reg_dead_p (2, operands[3]))" + [(set (match_dup 2) + (zero_extend:DI (match_dup 1)))]) + (define_peephole2 [(set (match_operand:SWI48 0 "register_operand") (match_operand:SWI48 1 "address_no_seg_operand"))] diff --git a/gcc/testsuite/gcc.target/i386/pr101716.c b/gcc/testsuite/gcc.target/i386/pr101716.c new file mode 100644 index 00000000000..0b684755c2f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr101716.c @@ -0,0 +1,11 @@ +/* PR target/101716 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ + +/* { dg-final { scan-assembler "leal\[\\t \]\*eax" } } */ +/* { dg-final { scan-assembler-not "movl\[\\t \]\*eax" } } */ + +unsigned long long sample1(unsigned long long m) { + unsigned int t = -1; + return (m << 1) & t; +} -- 2.18.1