aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/sse.md46
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr23816-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr23816-2.c9
4 files changed, 70 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dc690dd..39345c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-09-13 Uros Bizjak <uros@kss-loka.si>
+
+ PR target/23816
+ * config/i386/sse.md (*ieee_sminv4sf3, *ieee_smaxv4sf3)
+ (*ieee_sminv2df3, *ieee_smaxv2df3): New insn patterns.
+
2005-09-13 Ian Lance Taylor <ian@airs.com>
* loop-doloop.c (doloop_modify): Use GEN_INT to pass an rtx rather
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 95cb797..19f91ed 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -589,6 +589,52 @@
[(set_attr "type" "sse")
(set_attr "mode" "SF")])
+;; These versions of the min/max patterns implement exactly the operations
+;; min = (op1 < op2 ? op1 : op2)
+;; max = (!(op1 < op2) ? op1 : op2)
+;; Their operands are not commutative, and thus they may be used in the
+;; presence of -0.0 and NaN.
+
+(define_insn "*ieee_sminv4sf3"
+ [(set (match_operand:V4SF 0 "register_operand" "=x")
+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
+ (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
+ UNSPEC_IEEE_MIN))]
+ "TARGET_SSE"
+ "minps\t{%2, %0|%0, %2}"
+ [(set_attr "type" "sseadd")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "*ieee_smaxv4sf3"
+ [(set (match_operand:V4SF 0 "register_operand" "=x")
+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
+ (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
+ UNSPEC_IEEE_MAX))]
+ "TARGET_SSE"
+ "maxps\t{%2, %0|%0, %2}"
+ [(set_attr "type" "sseadd")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "*ieee_sminv2df3"
+ [(set (match_operand:V2DF 0 "register_operand" "=x")
+ (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
+ (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
+ UNSPEC_IEEE_MIN))]
+ "TARGET_SSE2"
+ "minpd\t{%2, %0|%0, %2}"
+ [(set_attr "type" "sseadd")
+ (set_attr "mode" "V2DF")])
+
+(define_insn "*ieee_smaxv2df3"
+ [(set (match_operand:V2DF 0 "register_operand" "=x")
+ (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
+ (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
+ UNSPEC_IEEE_MAX))]
+ "TARGET_SSE2"
+ "maxpd\t{%2, %0|%0, %2}"
+ [(set_attr "type" "sseadd")
+ (set_attr "mode" "V2DF")])
+
(define_insn "sse3_addsubv4sf3"
[(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF
diff --git a/gcc/testsuite/gcc.dg/vect/pr23816-1.c b/gcc/testsuite/gcc.dg/vect/pr23816-1.c
new file mode 100644
index 0000000..9ee9892
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr23816-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+void
+foo (float a[32], float b[2][32])
+{
+ int i;
+ for (i = 0; i < 32; i++)
+ a[i] = (b[0][i] > b[1][i]) ? b[0][i] : b[1][i];
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr23816-2.c b/gcc/testsuite/gcc.dg/vect/pr23816-2.c
new file mode 100644
index 0000000..c3ef734
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr23816-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+void
+foo (double a[32], double b[2][32])
+{
+ int i;
+ for (i = 0; i < 32; i++)
+ a[i] = (b[0][i] > b[1][i]) ? b[0][i] : b[1][i];
+}