aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-05-31 21:12:25 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-05-31 21:12:25 +0200
commit7351d8da1bdd94d04d276ce75e11897bbc8e3832 (patch)
tree32335e82377d6b6140801eee20c711d3e0bf2ef4
parentff7714547ff7aaaac44011e2184fc876945ad0a5 (diff)
downloadgcc-7351d8da1bdd94d04d276ce75e11897bbc8e3832.zip
gcc-7351d8da1bdd94d04d276ce75e11897bbc8e3832.tar.gz
gcc-7351d8da1bdd94d04d276ce75e11897bbc8e3832.tar.bz2
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
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/i386/i386.md34
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr48688.c24
4 files changed, 68 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2ddaf65..0c64540 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 056d3c9..6032924 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 10a41bd..dea7162 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/gcc.target/i386/pr48688.c b/gcc/testsuite/gcc.target/i386/pr48688.c
new file mode 100644
index 0000000..f4d663a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr48688.c
@@ -0,0 +1,24 @@
+/* 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\]" } } */