]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386.md: Add two new peephole2 to avoid mov followed by arithmetic with memory operands.
authorPaolo Bonzini <bonzini@gnu.org>
Wed, 11 Feb 2009 08:56:41 +0000 (08:56 +0000)
committerPaolo Bonzini <bonzini@gcc.gnu.org>
Wed, 11 Feb 2009 08:56:41 +0000 (08:56 +0000)
gcc:
2009-02-06  Paolo Bonzini  <bonzini@gnu.org>

* config/i386/i386.md: Add two new peephole2 to avoid mov followed
by arithmetic with memory operands.
* config/i386/predicates.md (commutative_operator): New.

gcc/testsuite:
2009-02-06  Paolo Bonzini  <bonzini@gnu.org>

* gcc.target/i386/pr38824.c: New testcase.

From-SVN: r144098

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/config/i386/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr38824.c [new file with mode: 0644]

index 1d32e094e3ed77155c012fcce356f0860516c211..4dd16725e0f564c24e8c8f3b66473148d8f242b8 100644 (file)
@@ -1,3 +1,9 @@
+2009-02-11  Paolo Bonzini  <bonzini@gnu.org>
+
+       * config/i386/i386.md: Add two new peephole2 to avoid mov followed
+       by arithmetic with memory operands.
+       * config/i386/predicates.md (commutative_operator): New.
+
 2009-02-10  Janis Johnson  <janis187@us.ibm.com>
 
        * doc/extend.texi (Fixed-Point Types): Break long paragraphs into
index 89a3b17607b06e823e28f06acc0f0f0529f42fc4..7a4511fc07faaba1f1b5a2160680a405c9fcf514 100644 (file)
               (clobber (reg:CC FLAGS_REG))])]
   "")
 
+;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
+;; refers to the destination of the load!
+
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+        (match_operand:SI 1 "register_operand" ""))
+   (parallel [(set (match_dup 0)
+                   (match_operator:SI 3 "commutative_operator"
+                     [(match_dup 0)
+                      (match_operand:SI 2 "memory_operand" "")]))
+              (clobber (reg:CC FLAGS_REG))])]
+  "operands[0] != operands[1]"
+  [(set (match_dup 0) (match_dup 4))
+   (parallel [(set (match_dup 0)
+                   (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
+              (clobber (reg:CC FLAGS_REG))])]
+  "operands[4] = simplify_replace_rtx (operands[2], operands[0], operands[1]);")
+
+(define_peephole2
+  [(set (match_operand 0 "register_operand" "")
+        (match_operand 1 "register_operand" ""))
+   (set (match_dup 0)
+                   (match_operator 3 "commutative_operator"
+                     [(match_dup 0)
+                      (match_operand 2 "memory_operand" "")]))]
+  "operands[0] != operands[1]
+   && (MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
+  [(set (match_dup 0) (match_dup 2))
+   (set (match_dup 0)
+        (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
+  "")
+
 ; Don't do logical operations with memory outputs
 ;
 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
index bdac21026171450ffe541a58083b6ad0d0dbb32c..a8c01ad8005bad76d4f3b2f28fb2cf8488967fe4 100644 (file)
   (match_code "plus,mult,and,ior,xor,smin,smax,umin,umax,compare,minus,div,
               mod,udiv,umod,ashift,rotate,ashiftrt,lshiftrt,rotatert"))
 
+;; Return true for COMMUTATIVE_P.
+(define_predicate "commutative_operator"
+  (match_code "plus,mult,and,ior,xor,smin,smax,umin,umax"))
+
 ;; Return 1 if OP is a binary operator that can be promoted to wider mode.
 (define_predicate "promotable_binary_operator"
   (ior (match_code "plus,and,ior,xor,ashift")
index 52817fad5b86e491f60c72f72eccbcfe2edd70fd..9b64184478a20077b0e88753679f864748844a9d 100644 (file)
@@ -1,3 +1,7 @@
+2009-02-11  Paolo Bonzini  <bonzini@gnu.org>
+
+       * gcc.target/i386/pr38824.c: New testcase.
+
 2009-02-11  Jason Merrill  <jason@redhat.com>
 
        PR c++/38649
diff --git a/gcc/testsuite/gcc.target/i386/pr38824.c b/gcc/testsuite/gcc.target/i386/pr38824.c
new file mode 100644 (file)
index 0000000..637abfd
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+void bench_1(float * out, float * in, float f, unsigned int n)
+{
+    n /= 4;
+    v4sf scalar = { f, f, f, f };
+    do
+    {
+        v4sf arg = *(v4sf *)in;
+        v4sf result = arg + scalar;
+        *(v4sf *) out = result;
+        in += 4;
+        out += 4;
+    }
+    while (--n);
+}
+
+/* { dg-final { scan-assembler-not "addps\[^\\n\]*%\[er\]" } } */