aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/i386/i386-expand.c59
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.md14
-rw-r--r--gcc/testsuite/gcc.dg/pr89984.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-pr102224.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-pr89984.c23
6 files changed, 51 insertions, 68 deletions
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 0cc572c..badbacc 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -2270,7 +2270,7 @@ void
ix86_expand_xorsign (rtx operands[])
{
machine_mode mode, vmode;
- rtx dest, op0, op1, mask;
+ rtx dest, op0, op1, mask, x, temp;
dest = operands[0];
op0 = operands[1];
@@ -2285,60 +2285,15 @@ ix86_expand_xorsign (rtx operands[])
else
gcc_unreachable ();
+ temp = gen_reg_rtx (vmode);
mask = ix86_build_signbit_mask (vmode, 0, 0);
- emit_insn (gen_xorsign3_1 (mode, dest, op0, op1, mask));
-}
-
-/* Deconstruct an xorsign operation into bit masks. */
-
-void
-ix86_split_xorsign (rtx operands[])
-{
- machine_mode mode, vmode;
- rtx dest, op0, op1, mask, x;
-
- dest = operands[0];
- op0 = operands[1];
- op1 = operands[2];
- mask = operands[3];
-
- mode = GET_MODE (dest);
- vmode = GET_MODE (mask);
+ op1 = lowpart_subreg (vmode, op1, mode);
+ x = gen_rtx_AND (vmode, op1, mask);
+ emit_insn (gen_rtx_SET (temp, x));
- /* The constraints ensure that for non-AVX dest == op1 is
- different from op0, and for AVX that at most two of
- dest, op0 and op1 are the same register but the third one
- is different. */
- if (rtx_equal_p (op0, op1))
- {
- gcc_assert (TARGET_AVX && !rtx_equal_p (op0, dest));
- if (vmode == V4SFmode)
- vmode = V4SImode;
- else
- {
- gcc_assert (vmode == V2DFmode);
- vmode = V2DImode;
- }
- mask = lowpart_subreg (vmode, mask, GET_MODE (mask));
- if (MEM_P (mask))
- {
- rtx msk = lowpart_subreg (vmode, dest, mode);
- emit_insn (gen_rtx_SET (msk, mask));
- mask = msk;
- }
- op0 = lowpart_subreg (vmode, op0, mode);
- x = gen_rtx_AND (vmode, gen_rtx_NOT (vmode, mask), op0);
- }
- else
- {
- op1 = lowpart_subreg (vmode, op1, mode);
- x = gen_rtx_AND (vmode, op1, mask);
- emit_insn (gen_rtx_SET (op1, x));
-
- op0 = lowpart_subreg (vmode, op0, mode);
- x = gen_rtx_XOR (vmode, op1, op0);
- }
+ op0 = lowpart_subreg (vmode, op0, mode);
+ x = gen_rtx_XOR (vmode, temp, op0);
dest = lowpart_subreg (vmode, dest, mode);
emit_insn (gen_rtx_SET (dest, x));
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 355df11..72644e3 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -138,7 +138,6 @@ extern void ix86_expand_copysign (rtx []);
extern void ix86_split_copysign_const (rtx []);
extern void ix86_split_copysign_var (rtx []);
extern void ix86_expand_xorsign (rtx []);
-extern void ix86_split_xorsign (rtx []);
extern bool ix86_unary_operator_ok (enum rtx_code, machine_mode, rtx[]);
extern bool ix86_match_ccmode (rtx, machine_mode);
extern void ix86_expand_branch (enum rtx_code, rtx, rtx, rtx);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 0414f24..6b4ceb2 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10917,20 +10917,6 @@
ix86_expand_xorsign (operands);
DONE;
})
-
-(define_insn_and_split "@xorsign<mode>3_1"
- [(set (match_operand:MODEF 0 "register_operand" "=&Yv,&Yv,&Yv")
- (unspec:MODEF
- [(match_operand:MODEF 1 "register_operand" "Yv,0,Yv")
- (match_operand:MODEF 2 "register_operand" "0,Yv,Yv")
- (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm,Yvm,Yvm")]
- UNSPEC_XORSIGN))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_xorsign (operands); DONE;"
- [(set_attr "isa" "*,avx,avx")])
;; One complement instructions
diff --git a/gcc/testsuite/gcc.dg/pr89984.c b/gcc/testsuite/gcc.dg/pr89984.c
new file mode 100644
index 0000000..471fe92
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr89984.c
@@ -0,0 +1,20 @@
+/* PR target/89984 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+__attribute__((noipa)) float
+foo (float x, float y)
+{
+ return x * __builtin_copysignf (1.0f, y) + y;
+}
+
+int
+main ()
+{
+ if (foo (1.25f, 7.25f) != 1.25f + 7.25f
+ || foo (1.75f, -3.25f) != -1.75f + -3.25f
+ || foo (-2.25f, 7.5f) != -2.25f + 7.5f
+ || foo (-3.0f, -4.0f) != 3.0f + -4.0f)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-pr102224.c b/gcc/testsuite/gcc.target/i386/avx-pr102224.c
index be6b88c..7cb8b4c 100644
--- a/gcc/testsuite/gcc.target/i386/avx-pr102224.c
+++ b/gcc/testsuite/gcc.target/i386/avx-pr102224.c
@@ -1,4 +1,4 @@
-/* PR tree-optimization/51581 */
+/* PR target/102224 */
/* { dg-do run } */
/* { dg-options "-O2 -mavx" } */
/* { dg-require-effective-target avx } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-pr89984.c b/gcc/testsuite/gcc.target/i386/avx-pr89984.c
new file mode 100644
index 0000000..3409ade
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-pr89984.c
@@ -0,0 +1,23 @@
+/* PR target/89984 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-require-effective-target avx } */
+
+#ifndef CHECK_H
+#define CHECK_H "avx-check.h"
+#endif
+#ifndef TEST
+#define TEST avx_test
+#endif
+
+#define main main1
+#include "../../gcc.dg/pr89984.c"
+#undef main
+
+#include CHECK_H
+
+static void
+TEST (void)
+{
+ main1 ();
+}