From 40bd4bf95e68e252afdf863f1c3d5f22e30f819e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 12 May 2016 10:30:25 +0200 Subject: [PATCH] constraints.md (Yv): New constraint. * config/i386/constraints.md (Yv): New constraint. * config/i386/i386.h (VALID_AVX512VL_128_REG_MODE): Allow TFmode and V1TImode in xmm16+ registers for TARGET_AVX512VL. * config/i386/i386.md (avx512fvecmode): New mode attr. (*pushtf): Use v constraint instead of x. (*movtf_internal): Likewise. For TARGET_AVX512VL and xmm16+ registers, use vmovdqu64 or vmovdqa64 instructions. (*absneg2): Use Yv constraint instead of x constraint. (*absnegtf2_sse): Likewise. (copysign3_const, copysign3_var): Likewise. * config/i386/sse.md (*andnot3): Add avx512vl and avx512f alternatives. (*andnottf3, *3, *tf3): Likewise. * gcc.target/i386/avx512dq-abs-copysign-1.c: New test. * gcc.target/i386/avx512vl-abs-copysign-1.c: New test. * gcc.target/i386/avx512vl-abs-copysign-2.c: New test. From-SVN: r236161 --- gcc/ChangeLog | 16 +++ gcc/config/i386/constraints.md | 4 + gcc/config/i386/i386.h | 3 +- gcc/config/i386/i386.md | 50 +++++--- gcc/config/i386/sse.md | 121 ++++++++++++++---- gcc/testsuite/ChangeLog | 6 + .../gcc.target/i386/avx512dq-abs-copysign-1.c | 71 ++++++++++ .../gcc.target/i386/avx512vl-abs-copysign-1.c | 71 ++++++++++ .../gcc.target/i386/avx512vl-abs-copysign-2.c | 49 +++++++ 9 files changed, 346 insertions(+), 45 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx512dq-abs-copysign-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6b3ca4b4782..b053bfd717e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2016-05-12 Jakub Jelinek + + * config/i386/constraints.md (Yv): New constraint. + * config/i386/i386.h (VALID_AVX512VL_128_REG_MODE): Allow + TFmode and V1TImode in xmm16+ registers for TARGET_AVX512VL. + * config/i386/i386.md (avx512fvecmode): New mode attr. + (*pushtf): Use v constraint instead of x. + (*movtf_internal): Likewise. For TARGET_AVX512VL and + xmm16+ registers, use vmovdqu64 or vmovdqa64 instructions. + (*absneg2): Use Yv constraint instead of x constraint. + (*absnegtf2_sse): Likewise. + (copysign3_const, copysign3_var): Likewise. + * config/i386/sse.md (*andnot3): Add avx512vl and + avx512f alternatives. + (*andnottf3, *3, *tf3): Likewise. + 2016-05-12 Richard Biener PR tree-optimization/71060 diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index ccebee775e1..44f2d33fc42 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -145,6 +145,10 @@ "TARGET_SSE ? (X86_TUNE_AVOID_4BYTE_PREFIXES ? NO_REX_SSE_REGS : ALL_SSE_REGS) : NO_REGS" "@internal Lower SSE register when avoiding REX prefix and all SSE registers otherwise.") +(define_register_constraint "Yv" + "TARGET_AVX512VL ? ALL_SSE_REGS : TARGET_SSE ? SSE_REGS : NO_REGS" + "@internal For AVX512VL, any EVEX encodable SSE register (@code{%xmm0-%xmm31}), otherwise any SSE register.") + ;; We use the B prefix to denote any number of internal operands: ;; f FLAGS_REG ;; g GOT memory operand. diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index d0b418b0fd9..b70a8c653e0 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1126,7 +1126,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define VALID_AVX512VL_128_REG_MODE(MODE) \ ((MODE) == V2DImode || (MODE) == V2DFmode || (MODE) == V16QImode \ - || (MODE) == V4SImode || (MODE) == V4SFmode || (MODE) == V8HImode) + || (MODE) == V4SImode || (MODE) == V4SFmode || (MODE) == V8HImode \ + || (MODE) == TFmode || (MODE) == V1TImode) #define VALID_SSE2_REG_MODE(MODE) \ ((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9bd19ab04be..9e0b47d3b8b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1168,6 +1168,10 @@ (define_mode_attr ssevecmodelower [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")]) +;; AVX512F vector mode corresponding to a scalar mode +(define_mode_attr avx512fvecmode + [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")]) + ;; Instruction suffix for REX 64bit operators. (define_mode_attr rex64suffix [(SI "") (DI "{q}")]) @@ -2928,7 +2932,7 @@ (define_insn "*pushtf" [(set (match_operand:TF 0 "push_operand" "=<,<") - (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))] + (match_operand:TF 1 "general_no_elim_operand" "v,*roF"))] "TARGET_64BIT || TARGET_SSE" { /* This insn should be already split before reg-stack. */ @@ -3103,8 +3107,8 @@ "ix86_expand_move (mode, operands); DONE;") (define_insn "*movtf_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o") - (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o") + (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))] "(TARGET_64BIT || TARGET_SSE) && !(MEM_P (operands[0]) && MEM_P (operands[1])) && (!can_create_pseudo_p () @@ -3129,6 +3133,10 @@ { if (get_attr_mode (insn) == MODE_V4SF) return "%vmovups\t{%1, %0|%0, %1}"; + else if (TARGET_AVX512VL + && (EXT_REX_SSE_REG_P (operands[0]) + || EXT_REX_SSE_REG_P (operands[1]))) + return "vmovdqu64\t{%1, %0|%0, %1}"; else return "%vmovdqu\t{%1, %0|%0, %1}"; } @@ -3136,6 +3144,10 @@ { if (get_attr_mode (insn) == MODE_V4SF) return "%vmovaps\t{%1, %0|%0, %1}"; + else if (TARGET_AVX512VL + && (EXT_REX_SSE_REG_P (operands[0]) + || EXT_REX_SSE_REG_P (operands[1]))) + return "vmovdqa64\t{%1, %0|%0, %1}"; else return "%vmovdqa\t{%1, %0|%0, %1}"; } @@ -9228,10 +9240,10 @@ "ix86_expand_fp_absneg_operator (, mode, operands); DONE;") (define_insn "*absneg2" - [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r") + [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r") (match_operator:MODEF 3 "absneg_operator" - [(match_operand:MODEF 1 "register_operand" "0,x,0,0")])) - (use (match_operand: 2 "nonimmediate_operand" "xm,0,X,X")) + [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")])) + (use (match_operand: 2 "nonimmediate_operand" "Yvm,0,X,X")) (clobber (reg:CC FLAGS_REG))] "TARGET_80387 || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)" "#" @@ -9263,10 +9275,10 @@ "ix86_expand_fp_absneg_operator (, TFmode, operands); DONE;") (define_insn "*absnegtf2_sse" - [(set (match_operand:TF 0 "register_operand" "=x,x") + [(set (match_operand:TF 0 "register_operand" "=Yv,Yv") (match_operator:TF 3 "absneg_operator" - [(match_operand:TF 1 "register_operand" "0,x")])) - (use (match_operand:TF 2 "nonimmediate_operand" "xm,0")) + [(match_operand:TF 1 "register_operand" "0,Yv")])) + (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0")) (clobber (reg:CC FLAGS_REG))] "TARGET_SSE" "#") @@ -9446,11 +9458,11 @@ "ix86_expand_copysign (operands); DONE;") (define_insn_and_split "copysign3_const" - [(set (match_operand:CSGNMODE 0 "register_operand" "=x") + [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv") (unspec:CSGNMODE - [(match_operand: 1 "vector_move_operand" "xmC") + [(match_operand: 1 "vector_move_operand" "YvmC") (match_operand:CSGNMODE 2 "register_operand" "0") - (match_operand: 3 "nonimmediate_operand" "xm")] + (match_operand: 3 "nonimmediate_operand" "Yvm")] UNSPEC_COPYSIGN))] "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) || (TARGET_SSE && (mode == TFmode))" @@ -9460,14 +9472,16 @@ "ix86_split_copysign_const (operands); DONE;") (define_insn "copysign3_var" - [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x") + [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv") (unspec:CSGNMODE - [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x") - (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x") - (match_operand: 4 "nonimmediate_operand" "X,xm,xm,0,0") - (match_operand: 5 "nonimmediate_operand" "0,xm,1,xm,1")] + [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv") + (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv") + (match_operand: 4 + "nonimmediate_operand" "X,Yvm,Yvm,0,0") + (match_operand: 5 + "nonimmediate_operand" "0,Yvm,1,Yvm,1")] UNSPEC_COPYSIGN)) - (clobber (match_scratch: 1 "=x,x,x,x,x"))] + (clobber (match_scratch: 1 "=Yv,Yv,Yv,Yv,Yv"))] "(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) || (TARGET_SSE && (mode == TFmode))" "#") diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index dd1ff960f53..a8092cb0500 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -3020,11 +3020,11 @@ ;; because the native instructions read the full 128-bits. (define_insn "*andnot3" - [(set (match_operand:MODEF 0 "register_operand" "=x,x") + [(set (match_operand:MODEF 0 "register_operand" "=x,x,v,v") (and:MODEF (not:MODEF - (match_operand:MODEF 1 "register_operand" "0,x")) - (match_operand:MODEF 2 "register_operand" "x,x")))] + (match_operand:MODEF 1 "register_operand" "0,x,v,v")) + (match_operand:MODEF 2 "register_operand" "x,x,v,v")))] "SSE_FLOAT_MODE_P (mode)" { static char buf[32]; @@ -3040,6 +3040,24 @@ case 1: ops = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; break; + case 2: + if (TARGET_AVX512DQ) + ops = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; + else + { + suffix = mode == DFmode ? "q" : "d"; + ops = "vpandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; + } + break; + case 3: + if (TARGET_AVX512DQ) + ops = "vandn%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}"; + else + { + suffix = mode == DFmode ? "q" : "d"; + ops = "vpandn%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}"; + } + break; default: gcc_unreachable (); } @@ -3047,11 +3065,19 @@ snprintf (buf, sizeof (buf), ops, suffix); return buf; } - [(set_attr "isa" "noavx,avx") + [(set_attr "isa" "noavx,avx,avx512vl,avx512f") (set_attr "type" "sselog") - (set_attr "prefix" "orig,vex") + (set_attr "prefix" "orig,vex,evex,evex") (set (attr "mode") - (cond [(and (match_test " == 16") + (cond [(eq_attr "alternative" "2") + (if_then_else (match_test "TARGET_AVX512DQ") + (const_string "") + (const_string "TI")) + (eq_attr "alternative" "3") + (if_then_else (match_test "TARGET_AVX512DQ") + (const_string "") + (const_string "XI")) + (and (match_test " == 16") (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) (const_string "V4SF") (match_test "TARGET_AVX") @@ -3062,16 +3088,17 @@ (const_string "")))]) (define_insn "*andnottf3" - [(set (match_operand:TF 0 "register_operand" "=x,x") + [(set (match_operand:TF 0 "register_operand" "=x,x,v,v") (and:TF - (not:TF (match_operand:TF 1 "register_operand" "0,x")) - (match_operand:TF 2 "vector_operand" "xBm,xm")))] + (not:TF (match_operand:TF 1 "register_operand" "0,x,v,v")) + (match_operand:TF 2 "vector_operand" "xBm,xm,vm,v")))] "TARGET_SSE" { static char buf[32]; const char *ops; const char *tmp - = (get_attr_mode (insn) == MODE_V4SF) ? "andnps" : "pandn"; + = (which_alternative >= 2 ? "pandnq" + : get_attr_mode (insn) == MODE_V4SF ? "andnps" : "pandn"); switch (which_alternative) { @@ -3079,8 +3106,12 @@ ops = "%s\t{%%2, %%0|%%0, %%2}"; break; case 1: + case 2: ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; break; + case 3: + ops = "v%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}"; + break; default: gcc_unreachable (); } @@ -3088,7 +3119,7 @@ snprintf (buf, sizeof (buf), ops, tmp); return buf; } - [(set_attr "isa" "noavx,avx") + [(set_attr "isa" "noavx,avx,avx512vl,avx512f") (set_attr "type" "sselog") (set (attr "prefix_data16") (if_then_else @@ -3096,9 +3127,13 @@ (eq_attr "mode" "TI")) (const_string "1") (const_string "*"))) - (set_attr "prefix" "orig,vex") + (set_attr "prefix" "orig,vex,evex,evex") (set (attr "mode") - (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") + (cond [(eq_attr "alternative" "2") + (const_string "TI") + (eq_attr "alternative" "3") + (const_string "XI") + (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") (const_string "V4SF") (match_test "TARGET_AVX") (const_string "TI") @@ -3109,10 +3144,10 @@ (const_string "TI")))]) (define_insn "*3" - [(set (match_operand:MODEF 0 "register_operand" "=x,x") + [(set (match_operand:MODEF 0 "register_operand" "=x,x,v,v") (any_logic:MODEF - (match_operand:MODEF 1 "register_operand" "%0,x") - (match_operand:MODEF 2 "register_operand" "x,x")))] + (match_operand:MODEF 1 "register_operand" "%0,x,v,v") + (match_operand:MODEF 2 "register_operand" "x,x,v,v")))] "SSE_FLOAT_MODE_P (mode)" { static char buf[32]; @@ -3125,9 +3160,26 @@ case 0: ops = "%s\t{%%2, %%0|%%0, %%2}"; break; + case 2: + if (!TARGET_AVX512DQ) + { + suffix = mode == DFmode ? "q" : "d"; + ops = "vp%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; + break; + } + /* FALLTHRU */ case 1: ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; break; + case 3: + if (TARGET_AVX512DQ) + ops = "v%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}"; + else + { + suffix = mode == DFmode ? "q" : "d"; + ops = "vp%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}"; + } + break; default: gcc_unreachable (); } @@ -3135,11 +3187,19 @@ snprintf (buf, sizeof (buf), ops, suffix); return buf; } - [(set_attr "isa" "noavx,avx") + [(set_attr "isa" "noavx,avx,avx512vl,avx512f") (set_attr "type" "sselog") - (set_attr "prefix" "orig,vex") + (set_attr "prefix" "orig,vex,evex,evex") (set (attr "mode") - (cond [(and (match_test " == 16") + (cond [(eq_attr "alternative" "2") + (if_then_else (match_test "TARGET_AVX512DQ") + (const_string "") + (const_string "TI")) + (eq_attr "alternative" "3") + (if_then_else (match_test "TARGET_AVX512DQ") + (const_string "") + (const_string "XI")) + (and (match_test " == 16") (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) (const_string "V4SF") (match_test "TARGET_AVX") @@ -3158,17 +3218,18 @@ "ix86_fixup_binary_operands_no_copy (, TFmode, operands);") (define_insn "*tf3" - [(set (match_operand:TF 0 "register_operand" "=x,x") + [(set (match_operand:TF 0 "register_operand" "=x,x,v,v") (any_logic:TF - (match_operand:TF 1 "vector_operand" "%0,x") - (match_operand:TF 2 "vector_operand" "xBm,xm")))] + (match_operand:TF 1 "vector_operand" "%0,x,v,v") + (match_operand:TF 2 "vector_operand" "xBm,xm,vm,v")))] "TARGET_SSE && ix86_binary_operator_ok (, TFmode, operands)" { static char buf[32]; const char *ops; const char *tmp - = (get_attr_mode (insn) == MODE_V4SF) ? "ps" : "p"; + = (which_alternative >= 2 ? "pq" + : get_attr_mode (insn) == MODE_V4SF ? "ps" : "p"); switch (which_alternative) { @@ -3176,8 +3237,12 @@ ops = "%s\t{%%2, %%0|%%0, %%2}"; break; case 1: + case 2: ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; break; + case 3: + ops = "v%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}"; + break; default: gcc_unreachable (); } @@ -3185,7 +3250,7 @@ snprintf (buf, sizeof (buf), ops, tmp); return buf; } - [(set_attr "isa" "noavx,avx") + [(set_attr "isa" "noavx,avx,avx512vl,avx512f") (set_attr "type" "sselog") (set (attr "prefix_data16") (if_then_else @@ -3193,9 +3258,13 @@ (eq_attr "mode" "TI")) (const_string "1") (const_string "*"))) - (set_attr "prefix" "orig,vex") + (set_attr "prefix" "orig,vex,evex,evex") (set (attr "mode") - (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") + (cond [(eq_attr "alternative" "2") + (const_string "TI") + (eq_attr "alternative" "3") + (const_string "QI") + (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") (const_string "V4SF") (match_test "TARGET_AVX") (const_string "TI") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ce5dfea8cba..fa2c1231a70 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-05-12 Jakub Jelinek + + * gcc.target/i386/avx512dq-abs-copysign-1.c: New test. + * gcc.target/i386/avx512vl-abs-copysign-1.c: New test. + * gcc.target/i386/avx512vl-abs-copysign-2.c: New test. + 2016-05-12 Richard Biener PR tree-optimization/70986 diff --git a/gcc/testsuite/gcc.target/i386/avx512dq-abs-copysign-1.c b/gcc/testsuite/gcc.target/i386/avx512dq-abs-copysign-1.c new file mode 100644 index 00000000000..cb542d09058 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512dq-abs-copysign-1.c @@ -0,0 +1,71 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-Ofast -mavx512vl -mavx512dq" } */ + +void +f1 (float x) +{ + register float a __asm ("xmm16"); + a = x; + asm volatile ("" : "+v" (a)); + a = __builtin_fabsf (a); + asm volatile ("" : "+v" (a)); +} + +void +f2 (float x, float y) +{ + register float a __asm ("xmm16"), b __asm ("xmm17"); + a = x; + b = y; + asm volatile ("" : "+v" (a), "+v" (b)); + a = __builtin_copysignf (a, b); + asm volatile ("" : "+v" (a)); +} + +void +f3 (float x) +{ + register float a __asm ("xmm16"); + a = x; + asm volatile ("" : "+v" (a)); + a = -a; + asm volatile ("" : "+v" (a)); +} + +void +f4 (double x) +{ + register double a __asm ("xmm18"); + a = x; + asm volatile ("" : "+v" (a)); + a = __builtin_fabs (a); + asm volatile ("" : "+v" (a)); +} + +void +f5 (double x, double y) +{ + register double a __asm ("xmm18"), b __asm ("xmm19"); + a = x; + b = y; + asm volatile ("" : "+v" (a), "+v" (b)); + a = __builtin_copysign (a, b); + asm volatile ("" : "+v" (a)); +} + +void +f6 (double x) +{ + register double a __asm ("xmm18"); + a = x; + asm volatile ("" : "+v" (a)); + a = -a; + asm volatile ("" : "+v" (a)); +} + +/* { dg-final { scan-assembler "vandps\[^\n\r\]*xmm16" } } */ +/* { dg-final { scan-assembler "vorps\[^\n\r\]*xmm16" } } */ +/* { dg-final { scan-assembler "vxorps\[^\n\r\]*xmm16" } } */ +/* { dg-final { scan-assembler "vandpd\[^\n\r\]*xmm18" } } */ +/* { dg-final { scan-assembler "vorpd\[^\n\r\]*xmm18" } } */ +/* { dg-final { scan-assembler "vxorpd\[^\n\r\]*xmm18" } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-1.c new file mode 100644 index 00000000000..b375c5fad80 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-1.c @@ -0,0 +1,71 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-Ofast -mavx512vl -mno-avx512dq" } */ + +void +f1 (float x) +{ + register float a __asm ("xmm16"); + a = x; + asm volatile ("" : "+v" (a)); + a = __builtin_fabsf (a); + asm volatile ("" : "+v" (a)); +} + +void +f2 (float x, float y) +{ + register float a __asm ("xmm16"), b __asm ("xmm17"); + a = x; + b = y; + asm volatile ("" : "+v" (a), "+v" (b)); + a = __builtin_copysignf (a, b); + asm volatile ("" : "+v" (a)); +} + +void +f3 (float x) +{ + register float a __asm ("xmm16"); + a = x; + asm volatile ("" : "+v" (a)); + a = -a; + asm volatile ("" : "+v" (a)); +} + +void +f4 (double x) +{ + register double a __asm ("xmm18"); + a = x; + asm volatile ("" : "+v" (a)); + a = __builtin_fabs (a); + asm volatile ("" : "+v" (a)); +} + +void +f5 (double x, double y) +{ + register double a __asm ("xmm18"), b __asm ("xmm19"); + a = x; + b = y; + asm volatile ("" : "+v" (a), "+v" (b)); + a = __builtin_copysign (a, b); + asm volatile ("" : "+v" (a)); +} + +void +f6 (double x) +{ + register double a __asm ("xmm18"); + a = x; + asm volatile ("" : "+v" (a)); + a = -a; + asm volatile ("" : "+v" (a)); +} + +/* { dg-final { scan-assembler "vpandd\[^\n\r\]*xmm16" } } */ +/* { dg-final { scan-assembler "vpord\[^\n\r\]*xmm16" } } */ +/* { dg-final { scan-assembler "vpxord\[^\n\r\]*xmm16" } } */ +/* { dg-final { scan-assembler "vpandq\[^\n\r\]*xmm18" } } */ +/* { dg-final { scan-assembler "vporq\[^\n\r\]*xmm18" } } */ +/* { dg-final { scan-assembler "vpxorq\[^\n\r\]*xmm18" } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-2.c new file mode 100644 index 00000000000..9082cdb5dba --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-2.c @@ -0,0 +1,49 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-Ofast -mavx512vl" } */ + +void +f1 (__float128 x) +{ + register __float128 a __asm ("xmm16"); + a = x; + asm volatile ("" : "+v" (a)); + a = __builtin_fabsq (a); + asm volatile ("" : "+v" (a)); +} + +void +f2 (__float128 x, __float128 y) +{ + register __float128 a __asm ("xmm16"), b __asm ("xmm17"); + a = x; + b = y; + asm volatile ("" : "+v" (a), "+v" (b)); + a = __builtin_copysignq (a, b); + asm volatile ("" : "+v" (a)); +} + +void +f3 (__float128 x) +{ + register __float128 a __asm ("xmm16"); + a = x; + asm volatile ("" : "+v" (a)); + a = -a; + asm volatile ("" : "+v" (a)); +} + +__int128_t +f4 (void) +{ + register __int128_t a __asm ("xmm16"); + register __int128_t __attribute__((vector_size (16))) b __asm ("xmm17"); + a = 1; + asm volatile ("" : "+v" (a)); + b[0] = a; + asm volatile ("" : "+v" (b)); + return b[0]; +} + +/* { dg-final { scan-assembler "vpandq\[^\n\r\]*xmm16" } } */ +/* { dg-final { scan-assembler "vporq\[^\n\r\]*xmm16" } } */ +/* { dg-final { scan-assembler "vpxorq\[^\n\r\]*xmm16" } } */ -- 2.30.2