Commit 7351d8da by Jakub Jelinek Committed by Jakub Jelinek

re PR target/48688 ([x64]: shift/or instead of lea)

	PR target/48688
	* config/i386/i386.md (*lea_general_4): New define_insn_and_split.

	* gcc.target/i386/pr48688.c: New test.

From-SVN: r174507
parent ff771454
2011-05-31 Jakub Jelinek <jakub@redhat.com>
PR target/48688
* config/i386/i386.md (*lea_general_4): New define_insn_and_split.
2011-05-31 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md: Use SWI248x instead of X87MODEI, SWI24 instead
......
......@@ -6413,6 +6413,40 @@
}
[(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
......
2011-05-31 Jakub Jelinek <jakub@redhat.com>
PR target/48688
* gcc.target/i386/pr48688.c: New test.
2010-11-15 Fabien Chêne <fabien@gcc.gnu.org>
PR c++/48010
......
/* PR target/48688 */
/* { dg-do compile } */
/* { dg-options "-O2" } */
int fn1 (int x) { return (x << 3) | 5; }
int fn2 (int x) { return (x * 8) | 5; }
int fn3 (int x) { return (x << 3) + 5; }
int fn4 (int x) { return (x * 8) + 5; }
int fn5 (int x) { return (x << 3) ^ 5; }
int fn6 (int x) { return (x * 8) ^ 5; }
long fn7 (long x) { return (x << 3) | 5; }
long fn8 (long x) { return (x * 8) | 5; }
long fn9 (long x) { return (x << 3) + 5; }
long fn10 (long x) { return (x * 8) + 5; }
long fn11 (long x) { return (x << 3) ^ 5; }
long fn12 (long x) { return (x * 8) ^ 5; }
long fn13 (unsigned x) { return (x << 3) | 5; }
long fn14 (unsigned x) { return (x * 8) | 5; }
long fn15 (unsigned x) { return (x << 3) + 5; }
long fn16 (unsigned x) { return (x * 8) + 5; }
long fn17 (unsigned x) { return (x << 3) ^ 5; }
long fn18 (unsigned x) { return (x * 8) ^ 5; }
/* { dg-final { scan-assembler-not "\[ \t\]x?or\[bwlq\]\[ \t\]" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment