From ed392e9db434898eccec81edd85323d21d555fe9 Mon Sep 17 00:00:00 2001 From: liuhongt Date: Mon, 28 Jun 2021 19:27:23 +0800 Subject: [PATCH] The upper bits of FIXUPIMMS{S,D} should come from src1 not dest. gcc/ChangeLog: PR target/101248 * config/i386/sse.md (avx512f_sfixupimm): Refined to .. (avx512f_sfixupimm): this. (avx512f_sfixupimm_mask"): 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. --- gcc/config/i386/sse.md | 8 +- gcc/config/i386/subst.md | 21 ++++ gcc/testsuite/gcc.target/i386/pr101248.c | 123 +++++++++++++++++++++++ 3 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr101248.c diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index ffcc0c81964..d3f5a74f763 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -9942,7 +9942,7 @@ DONE; }) -(define_insn "avx512f_sfixupimm" +(define_insn "avx512f_sfixupimm" [(set (match_operand:VF_128 0 "register_operand" "=v") (vec_merge:VF_128 (unspec:VF_128 @@ -9951,10 +9951,10 @@ (match_operand: 3 "" "") (match_operand:SI 4 "const_0_to_255_operand")] UNSPEC_FIXUPIMM) - (match_dup 1) + (match_dup 2) (const_int 1)))] "TARGET_AVX512F" - "vfixupimm\t{%4, %3, %2, %0|%0, %2, %3, %4}"; + "vfixupimm\t{%4, %3, %2, %0|%0, %2, %3, %4}"; [(set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -9968,7 +9968,7 @@ (match_operand: 3 "" "") (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: 5 "register_operand" "Yk")))] diff --git a/gcc/config/i386/subst.md b/gcc/config/i386/subst.md index 477a89803fa..6614e044857 100644 --- a/gcc/config/i386/subst.md +++ b/gcc/config/i386/subst.md @@ -117,6 +117,25 @@ (match_operand: 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: 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" "" "") (define_subst_attr "round_saeonly_mask_scalar_merge_op4" "round_saeonly" "" "") (define_subst_attr "round_saeonly_sd_mask_op5" "round_saeonly" "" "") +(define_subst_attr "round_saeonly_maskz_scalar_op5" "round_saeonly" "" "") (define_subst_attr "round_saeonly_mask_arg3" "round_saeonly" "" ", operands[]") (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 00000000000..f5ac94f5769 --- /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) +{}