diff options
-rw-r--r-- | gcc/config/i386/i386-expand.c | 59 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr89984.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/avx-pr102224.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/avx-pr89984.c | 23 |
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 (); +} |