]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
arm.md (minmax_arithsi_non_canon): New pattern.
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Tue, 9 Apr 2013 16:08:47 +0000 (16:08 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Tue, 9 Apr 2013 16:08:47 +0000 (16:08 +0000)
2013-04-09  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

* config/arm/arm.md (minmax_arithsi_non_canon): New pattern.

* gcc.target/arm/minmax_minus.c: New test.

From-SVN: r197642

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/minmax_minus.c [new file with mode: 0644]

index 6181c6741ae946e3eaa63692942a12c272b599a8..dddf37eb21ddf8471c9858c6e2cb98abb55e7754 100644 (file)
@@ -1,3 +1,7 @@
+2013-04-09  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/arm/arm.md (minmax_arithsi_non_canon): New pattern.
+
 2013-04-09  Steven Bosscher  <steven@gcc.gnu.org>
 
        * sched-vis.c (print_pattern): Print SEQUENCE of insns as insns.
index b631e9e73416a371ba24d7961686269f59465c2b..073ee6b6fa3420932fd0ed077e50fbf4663ed90e 100644 (file)
                      (const_int 12)))]
 )
 
+; Reject the frame pointer in operand[1], since reloading this after
+; it has been eliminated can cause carnage.
+(define_insn_and_split "*minmax_arithsi_non_canon"
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+       (minus:SI
+        (match_operand:SI 1 "s_register_operand" "0,?r")
+         (match_operator:SI 4 "minmax_operator"
+          [(match_operand:SI 2 "s_register_operand" "r,r")
+           (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_32BIT && !arm_eliminable_register (operands[1])"
+  "#"
+  "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
+  [(set (reg:CC CC_REGNUM)
+        (compare:CC (match_dup 2) (match_dup 3)))
+
+   (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
+              (set (match_dup 0)
+                   (minus:SI (match_dup 1)
+                             (match_dup 2))))
+   (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
+              (set (match_dup 0)
+                   (minus:SI (match_dup 1)
+                             (match_dup 3))))]
+  {
+  enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
+                                           operands[2], operands[3]);
+  enum rtx_code rc = minmax_code (operands[4]);
+  operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
+                                operands[2], operands[3]);
+
+  if (mode == CCFPmode || mode == CCFPEmode)
+    rc = reverse_condition_maybe_unordered (rc);
+  else
+    rc = reverse_condition (rc);
+  operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
+  }
+  [(set_attr "conds" "clob")
+   (set (attr "length")
+       (if_then_else (eq_attr "is_thumb" "yes")
+                     (const_int 14)
+                     (const_int 12)))]
+)
+
 (define_code_iterator SAT [smin smax])
 (define_code_iterator SATrev [smin smax])
 (define_code_attr SATlo [(smin "1") (smax "2")])
index f53c0d322c4511a52f5649fdda298741d24008bb..3f2b55b389855bb1cde5f5929f58c11638d090a2 100644 (file)
@@ -1,3 +1,7 @@
+2013-04-09  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gcc.target/arm/minmax_minus.c: New test.
+
 2013-04-09  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/56883
diff --git a/gcc/testsuite/gcc.target/arm/minmax_minus.c b/gcc/testsuite/gcc.target/arm/minmax_minus.c
new file mode 100644 (file)
index 0000000..050c847
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#define MAX(a, b) (a > b ? a : b)
+int
+foo (int a, int b, int c)
+{
+  return c - MAX (a, b);
+}
+
+/* { dg-final { scan-assembler "rsbge" } } */
+/* { dg-final { scan-assembler "rsblt" } } */