aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorliuhongt <hongtao.liu@intel.com>2021-06-28 19:27:23 +0800
committerliuhongt <hongtao.liu@intel.com>2021-06-30 09:07:46 +0800
commited392e9db434898eccec81edd85323d21d555fe9 (patch)
treeddd6233e01166f13b02024ad1ec9e74e361513a0 /gcc
parent652abe22205f268c90b3b15f28c56c030ef68a34 (diff)
downloadgcc-ed392e9db434898eccec81edd85323d21d555fe9.zip
gcc-ed392e9db434898eccec81edd85323d21d555fe9.tar.gz
gcc-ed392e9db434898eccec81edd85323d21d555fe9.tar.bz2
The upper bits of FIXUPIMMS{S,D} should come from src1 not dest.
gcc/ChangeLog: PR target/101248 * config/i386/sse.md (avx512f_sfixupimm<mode><sd_maskz_name><round_saeonly_name>): Refined to .. (avx512f_sfixupimm<mode><maskz_scalar_name><round_saeonly_name>): this. (avx512f_sfixupimm<mode>_mask<round_saeonly_name>"): Refined. * config/i386/subst.md (maskz_scalar): New define_subst. (maskz_scalar_name): New subst_attr. (maskz_scalar_op5): Ditto. (round_saeonly_maskz_scalar_op5): Ditto. (round_saeonly_maskz_scalar_operand5): Ditto. gcc/testsuite/ChangeLog PR target/101248 * gcc.target/i386/pr101248.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i386/sse.md8
-rw-r--r--gcc/config/i386/subst.md21
-rw-r--r--gcc/testsuite/gcc.target/i386/pr101248.c123
3 files changed, 148 insertions, 4 deletions
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index ffcc0c8..d3f5a74 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -9942,7 +9942,7 @@
DONE;
})
-(define_insn "avx512f_sfixupimm<mode><sd_maskz_name><round_saeonly_name>"
+(define_insn "avx512f_sfixupimm<mode><maskz_scalar_name><round_saeonly_name>"
[(set (match_operand:VF_128 0 "register_operand" "=v")
(vec_merge:VF_128
(unspec:VF_128
@@ -9951,10 +9951,10 @@
(match_operand:<sseintvecmode> 3 "<round_saeonly_nimm_scalar_predicate>" "<round_saeonly_constraint>")
(match_operand:SI 4 "const_0_to_255_operand")]
UNSPEC_FIXUPIMM)
- (match_dup 1)
+ (match_dup 2)
(const_int 1)))]
"TARGET_AVX512F"
- "vfixupimm<ssescalarmodesuffix>\t{%4, <round_saeonly_sd_mask_op5>%3, %2, %0<sd_mask_op5>|%0<sd_mask_op5>, %2, %<iptr>3<round_saeonly_sd_mask_op5>, %4}";
+ "vfixupimm<ssescalarmodesuffix>\t{%4, <round_saeonly_maskz_scalar_op5>%3, %2, %0<maskz_scalar_op5>|%0<maskz_scalar_op5>, %2, %<iptr>3<round_saeonly_maskz_scalar_op5>, %4}";
[(set_attr "prefix" "evex")
(set_attr "mode" "<ssescalarmode>")])
@@ -9968,7 +9968,7 @@
(match_operand:<sseintvecmode> 3 "<round_saeonly_nimm_scalar_predicate>" "<round_saeonly_constraint>")
(match_operand:SI 4 "const_0_to_255_operand")]
UNSPEC_FIXUPIMM)
- (match_dup 1)
+ (match_dup 2)
(const_int 1))
(match_dup 1)
(match_operand:<avx512fmaskmode> 5 "register_operand" "Yk")))]
diff --git a/gcc/config/i386/subst.md b/gcc/config/i386/subst.md
index 477a898..6614e04 100644
--- a/gcc/config/i386/subst.md
+++ b/gcc/config/i386/subst.md
@@ -117,6 +117,25 @@
(match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))
])
+(define_subst_attr "maskz_scalar_name" "maskz_scalar" "" "_maskz_1")
+(define_subst_attr "maskz_scalar_op5" "maskz_scalar" "" "%{%6%}%N5")
+
+(define_subst "maskz_scalar"
+ [(set (match_operand:SUBST_V 0)
+ (vec_merge:SUBST_V
+ (match_operand:SUBST_V 1)
+ (match_operand:SUBST_V 2)
+ (const_int 1)))]
+ "TARGET_AVX512F"
+ [(set (match_dup 0)
+ (vec_merge:SUBST_V
+ (vec_merge:SUBST_V
+ (match_dup 1)
+ (match_operand:SUBST_V 3 "const0_operand" "C")
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "Yk"))
+ (match_dup 2)
+ (const_int 1)))])
+
(define_subst_attr "round_name" "round" "" "_round")
(define_subst_attr "round_mask_operand2" "mask" "%R2" "%R4")
(define_subst_attr "round_mask_operand3" "mask" "%R3" "%R5")
@@ -163,6 +182,7 @@
(define_subst_attr "round_saeonly_mask_operand3" "mask" "%r3" "%r5")
(define_subst_attr "round_saeonly_mask_operand4" "mask" "%r4" "%r6")
(define_subst_attr "round_saeonly_mask_scalar_merge_operand4" "mask_scalar_merge" "%r4" "%r5")
+(define_subst_attr "round_saeonly_maskz_scalar_operand5" "maskz_scalar" "%r5" "%r7")
(define_subst_attr "round_saeonly_sd_mask_operand5" "sd" "%r5" "%r7")
(define_subst_attr "round_saeonly_op2" "round_saeonly" "" "%r2")
(define_subst_attr "round_saeonly_op3" "round_saeonly" "" "%r3")
@@ -175,6 +195,7 @@
(define_subst_attr "round_saeonly_mask_op4" "round_saeonly" "" "<round_saeonly_mask_operand4>")
(define_subst_attr "round_saeonly_mask_scalar_merge_op4" "round_saeonly" "" "<round_saeonly_mask_scalar_merge_operand4>")
(define_subst_attr "round_saeonly_sd_mask_op5" "round_saeonly" "" "<round_saeonly_sd_mask_operand5>")
+(define_subst_attr "round_saeonly_maskz_scalar_op5" "round_saeonly" "" "<round_saeonly_maskz_scalar_operand5>")
(define_subst_attr "round_saeonly_mask_arg3" "round_saeonly" "" ", operands[<mask_expand_op3>]")
(define_subst_attr "round_saeonly_constraint" "round_saeonly" "vm" "v")
(define_subst_attr "round_saeonly_constraint2" "round_saeonly" "m" "v")
diff --git a/gcc/testsuite/gcc.target/i386/pr101248.c b/gcc/testsuite/gcc.target/i386/pr101248.c
new file mode 100644
index 0000000..f5ac94f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101248.c
@@ -0,0 +1,123 @@
+/* PR target/101248 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx512vl -std=gnu99" } */
+/* { dg-require-effective-target avx512vl } */
+/* { dg-require-effective-target c99_runtime } */
+
+#define AVX512VL
+#define AVX512F_LEN 128
+#define AVX512F_LEN_HALF 128
+
+#include "avx512f-helper.h"
+
+#define SIZE (AVX512F_LEN / 64)
+#include "avx512f-mask-type.h"
+#include "math_m_pi.h"
+#include "float.h"
+
+
+static void
+CALC (double *r, double dest, double src, long long tbl)
+{
+ switch (tbl & 0xf)
+ {
+ case 0:
+ *r = dest;
+ break;
+ case 1:
+ *r = src;
+ break;
+ case 2:
+ *r = signbit (src) ? -NAN : NAN;
+ break;
+ case 3:
+ *r = -NAN;
+ break;
+ case 4:
+ *r = -INFINITY;
+ break;
+ case 5:
+ *r = INFINITY;
+ break;
+ case 6:
+ *r = signbit (src) ? -INFINITY : INFINITY;
+ break;
+ case 7:
+ *r = 1.0 / -INFINITY;
+ break;
+ case 8:
+ *r = 0.0;
+ break;
+ case 9:
+ *r = -1.0;
+ break;
+ case 10:
+ *r = 1.0;
+ break;
+ case 11:
+ *r = 1.0 / 2.0;
+ break;
+ case 12:
+ *r = 90.0;
+ break;
+ case 13:
+ *r = M_PI_2;
+ break;
+ case 14:
+ *r = DBL_MAX;
+ break;
+ case 15:
+ *r = -DBL_MAX;
+ break;
+ default:
+ abort ();
+ }
+}
+
+void
+TEST (void)
+{
+ int i, j;
+ UNION_TYPE (AVX512F_LEN, d) res1, res2, res3, s1;
+ UNION_TYPE (AVX512F_LEN, i_q) s2;
+ double res_ref[SIZE];
+
+
+ float vals[2] = { -10, 10 };
+ int controls[8] = {0, 0x11111111, 0x77777777, 0x88888888,
+ 0x99999999, 0xaaaaaaaa, 0xbbbbbbbb, 0xcccccccc};
+
+ MASK_TYPE mask = 1;
+
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < SIZE; j++)
+ {
+ s1.a[j] = vals[i];
+ s2.a[j] = controls[j];
+ res1.a[j] = DEFAULT_VALUE;
+ res2.a[j] = DEFAULT_VALUE;
+ res3.a[j] = DEFAULT_VALUE;
+
+ CALC (&res_ref[j], res1.a[j], s1.a[j], s2.a[j]);
+ }
+
+ res1.x = INTRINSIC (_fixupimm_pd) (res1.x, s1.x, s2.x, 0);
+ res2.x = INTRINSIC (_mask_fixupimm_pd) (res2.x, mask, s1.x, s2.x, 0);
+ res3.x = INTRINSIC (_maskz_fixupimm_pd) (mask, res3.x, s1.x, s2.x, 0);
+
+ if (UNION_CHECK (AVX512F_LEN, d) (res1, res_ref))
+ abort ();
+
+ MASK_MERGE(d) (res_ref, mask, SIZE);
+ if (UNION_CHECK (AVX512F_LEN, d) (res2, res_ref))
+ abort ();
+ MASK_ZERO(d) (res_ref, mask, SIZE);
+ if (UNION_CHECK (AVX512F_LEN, d) (res3, res_ref))
+ abort ();
+ }
+}
+
+void
+test_256 (void)
+{}