aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2013-04-09 16:08:47 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2013-04-09 16:08:47 +0000
commit5017f1d2d31655ef19032f7c143bae64c8ae0142 (patch)
treeee14a68be7931b23713baea17406995d381461ac /gcc
parenta949cf1c752e2a711c1794e8f511f118ab927b40 (diff)
downloadgcc-5017f1d2d31655ef19032f7c143bae64c8ae0142.zip
gcc-5017f1d2d31655ef19032f7c143bae64c8ae0142.tar.gz
gcc-5017f1d2d31655ef19032f7c143bae64c8ae0142.tar.bz2
arm.md (minmax_arithsi_non_canon): New pattern.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/arm/arm.md44
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/arm/minmax_minus.c12
4 files changed, 64 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6181c67..dddf37e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index b631e9e..073ee6b 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -3597,6 +3597,50 @@
(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")])
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f53c0d3..3f2b55b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..050c847
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/minmax_minus.c
@@ -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" } } */