On Wed, Apr 20, 2011 at 9:09 AM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > This splitter allows us to optimize (x {* {2,4,8},<< {1,2,3}}) {|,^} y > for constant integer y <= {1ULL,3ULL,7ULL} using lea{l,q} (| or ^ in > that case, when the low bits are known to be all 0, is like plus). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2011-04-20 Jakub Jelinek <ja...@redhat.com> > > PR target/48688 > * config/i386/i386.md (*lea_general_4): New define_insn_and_split. > > * gcc.target/i386/pr48688.c: New test. > > --- gcc/config/i386/i386.md.jj 2011-04-19 14:08:55.000000000 +0200 > +++ gcc/config/i386/i386.md 2011-04-20 14:34:50.000000000 +0200 > @@ -6646,6 +6646,40 @@ (define_insn_and_split "*lea_general_3_z > } > [(set_attr "type" "lea") > (set_attr "mode" "SI")]) > + > +(define_insn_and_split "*lea_general_4" > + [(set (match_operand:SWI 0 "register_operand" "=r") > + (any_or:SWI (ashift:SWI (match_operand:SWI 1 "index_register_operand" > "l") > + (match_operand:SWI 2 "const_int_operand" "n")) > + (match_operand 3 "const_int_operand" "n")))] > + "(<MODE>mode == DImode > + || <MODE>mode == SImode > + || !TARGET_PARTIAL_REG_STALL > + || optimize_function_for_size_p (cfun)) > + && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3 > + && ((unsigned HOST_WIDE_INT) INTVAL (operands[3]) > + <= ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))" > + "#" > + "&& reload_completed" > + [(const_int 0)] > +{ > + rtx pat; > + if (<MODE>mode != DImode) > + operands[0] = gen_lowpart (SImode, operands[0]); > + operands[1] = gen_lowpart (Pmode, operands[1]); > + operands[2] = GEN_INT (1 << INTVAL (operands[2])); > + pat = plus_constant (gen_rtx_MULT (Pmode, operands[1], operands[2]), > + INTVAL (operands[3])); > + if (Pmode != SImode && <MODE>mode != DImode) > + pat = gen_rtx_SUBREG (SImode, pat, 0); > + emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); > + DONE; > +} > + [(set_attr "type" "lea") > + (set (attr "mode") > + (if_then_else (eq (symbol_ref "<MODE>mode == DImode") (const_int 0)) > + (const_string "SI") > + (const_string "DI")))]) > > ;; Subtract instructions
I don't think this pattern is correct. See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49281 H.J.