i386: Generate standard floating point scalar operation patterns
Standard floating point scalar operation patterns for combiner, which preserve the rest of the vector, look like (vec_merge:V2DF (vec_duplicate:V2DF (reg:DF 87)) (reg/v:V2DF 85 [ x ]) (const_int 1 [0x1])])) and (vec_merge:V2DF (vec_duplicate:V2DF (op:DF (vec_select:DF (reg/v:V2DF 85 [ x ]) (parallel [ (const_int 0 [0])])) (reg:DF 87)) (reg/v:V2DF 85 [ x ]) (const_int 1 [0x1])])) This patch adds and generates such standard floating point scalar operation patterns for +, -, *, /, > and <. Tested on x86-64. gcc/ PR target/54855 * config/i386/i386-expand.c (ix86_expand_vector_set): Generate standard scalar operation pattern for V2DF. * config/i386/sse.md (*<sse>_vm<plusminus_insn><mode>3): New. (*<sse>_vm<multdiv_mnemonic><mode>3): Likewise. (*ieee_<ieee_maxmin><mode>3): Likewise. (vec_setv2df_0): Likewise. gcc/testsuite/ PR target/54855 * gcc.target/i386/pr54855-1.c: New test. * gcc.target/i386/pr54855-2.c: Likewise. * gcc.target/i386/pr54855-3.c: Likewise. * gcc.target/i386/pr54855-4.c: Likewise. * gcc.target/i386/pr54855-5.c: Likewise. * gcc.target/i386/pr54855-6.c: Likewise. * gcc.target/i386/pr54855-7.c: Likewise. * gcc.target/i386/pr54855-8.c: Likewise. * gcc.target/i386/pr54855-9.c: Likewise. * gcc.target/i386/pr54855-10.c: Likewise. From-SVN: r272511
This commit is contained in:
parent
d1a7d8de46
commit
ac17302495
|
@ -1,3 +1,13 @@
|
|||
2019-06-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/54855
|
||||
* config/i386/i386-expand.c (ix86_expand_vector_set): Generate
|
||||
standard scalar operation pattern for V2DF.
|
||||
* config/i386/sse.md (*<sse>_vm<plusminus_insn><mode>3): New.
|
||||
(*<sse>_vm<multdiv_mnemonic><mode>3): Likewise.
|
||||
(*ieee_<ieee_maxmin><mode>3): Likewise.
|
||||
(vec_setv2df_0): Likewise.
|
||||
|
||||
2019-06-20 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree-ssa-alias.c (aliasing_component_refs_p): Remove ref2_is_decl
|
||||
|
|
|
@ -14214,6 +14214,17 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt)
|
|||
return;
|
||||
|
||||
case E_V2DFmode:
|
||||
/* NB: For ELT == 0, use standard scalar operation patterns which
|
||||
preserve the rest of the vector for combiner:
|
||||
|
||||
(vec_merge:V2DF
|
||||
(vec_duplicate:V2DF (reg:DF))
|
||||
(reg:V2DF)
|
||||
(const_int 1))
|
||||
*/
|
||||
if (elt == 0)
|
||||
goto do_vec_merge;
|
||||
|
||||
{
|
||||
rtx op0, op1;
|
||||
|
||||
|
@ -14511,6 +14522,7 @@ quarter:
|
|||
}
|
||||
else if (use_vec_merge)
|
||||
{
|
||||
do_vec_merge:
|
||||
tmp = gen_rtx_VEC_DUPLICATE (mode, val);
|
||||
tmp = gen_rtx_VEC_MERGE (mode, tmp, target,
|
||||
GEN_INT (HOST_WIDE_INT_1U << elt));
|
||||
|
|
|
@ -1826,6 +1826,28 @@
|
|||
(set_attr "type" "sseadd")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
;; Standard scalar operation patterns which preserve the rest of the
|
||||
;; vector for combiner.
|
||||
(define_insn "*<sse>_vm<plusminus_insn><mode>3"
|
||||
[(set (match_operand:VF_128 0 "register_operand" "=x,v")
|
||||
(vec_merge:VF_128
|
||||
(vec_duplicate:VF_128
|
||||
(plusminus:<ssescalarmode>
|
||||
(vec_select:<ssescalarmode>
|
||||
(match_operand:VF_128 1 "register_operand" "0,v")
|
||||
(parallel [(const_int 0)]))
|
||||
(match_operand:<ssescalarmode> 2 "nonimmediate_operand" "xm,vm")))
|
||||
(match_dup 1)
|
||||
(const_int 1)))]
|
||||
"TARGET_SSE"
|
||||
"@
|
||||
<plusminus_mnemonic><ssescalarmodesuffix>\t{%2, %0|%0, %<iptr>2}
|
||||
v<plusminus_mnemonic><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %<iptr>2}"
|
||||
[(set_attr "isa" "noavx,avx")
|
||||
(set_attr "type" "sseadd")
|
||||
(set_attr "prefix" "orig,vex")
|
||||
(set_attr "mode" "<ssescalarmode>")])
|
||||
|
||||
(define_insn "<sse>_vm<plusminus_insn><mode>3<mask_scalar_name><round_scalar_name>"
|
||||
[(set (match_operand:VF_128 0 "register_operand" "=x,v")
|
||||
(vec_merge:VF_128
|
||||
|
@ -1880,6 +1902,29 @@
|
|||
(set_attr "type" "ssemul")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
;; Standard scalar operation patterns which preserve the rest of the
|
||||
;; vector for combiner.
|
||||
(define_insn "*<sse>_vm<multdiv_mnemonic><mode>3"
|
||||
[(set (match_operand:VF_128 0 "register_operand" "=x,v")
|
||||
(vec_merge:VF_128
|
||||
(vec_duplicate:VF_128
|
||||
(multdiv:<ssescalarmode>
|
||||
(vec_select:<ssescalarmode>
|
||||
(match_operand:VF_128 1 "register_operand" "0,v")
|
||||
(parallel [(const_int 0)]))
|
||||
(match_operand:<ssescalarmode> 2 "nonimmediate_operand" "xm,vm")))
|
||||
(match_dup 1)
|
||||
(const_int 1)))]
|
||||
"TARGET_SSE"
|
||||
"@
|
||||
<multdiv_mnemonic><ssescalarmodesuffix>\t{%2, %0|%0, %<iptr>2}
|
||||
v<multdiv_mnemonic><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %<iptr>2}"
|
||||
[(set_attr "isa" "noavx,avx")
|
||||
(set_attr "type" "sse<multdiv_mnemonic>")
|
||||
(set_attr "prefix" "orig,vex")
|
||||
(set_attr "btver2_decode" "direct,double")
|
||||
(set_attr "mode" "<ssescalarmode>")])
|
||||
|
||||
(define_insn "<sse>_vm<multdiv_mnemonic><mode>3<mask_scalar_name><round_scalar_name>"
|
||||
[(set (match_operand:VF_128 0 "register_operand" "=x,v")
|
||||
(vec_merge:VF_128
|
||||
|
@ -2229,6 +2274,30 @@
|
|||
(set_attr "prefix" "<mask_prefix3>")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
;; Standard scalar operation patterns which preserve the rest of the
|
||||
;; vector for combiner.
|
||||
(define_insn "*ieee_<ieee_maxmin><mode>3"
|
||||
[(set (match_operand:VF_128 0 "register_operand" "=x,v")
|
||||
(vec_merge:VF_128
|
||||
(vec_duplicate:VF_128
|
||||
(unspec:<ssescalarmode>
|
||||
[(vec_select:<ssescalarmode>
|
||||
(match_operand:VF_128 1 "register_operand" "0,v")
|
||||
(parallel [(const_int 0)]))
|
||||
(match_operand:<ssescalarmode> 2 "nonimmediate_operand" "xm,vm")]
|
||||
IEEE_MAXMIN))
|
||||
(match_dup 1)
|
||||
(const_int 1)))]
|
||||
"TARGET_SSE"
|
||||
"@
|
||||
<ieee_maxmin><ssescalarmodesuffix>\t{%2, %0|%0, %2}
|
||||
v<ieee_maxmin><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
|
||||
[(set_attr "isa" "noavx,avx")
|
||||
(set_attr "type" "sseadd")
|
||||
(set_attr "btver2_sse_attr" "maxmin")
|
||||
(set_attr "prefix" "orig,vex")
|
||||
(set_attr "mode" "<ssescalarmode>")])
|
||||
|
||||
(define_insn "<sse>_vm<code><mode>3<mask_scalar_name><round_saeonly_scalar_name>"
|
||||
[(set (match_operand:VF_128 0 "register_operand" "=x,v")
|
||||
(vec_merge:VF_128
|
||||
|
@ -7911,6 +7980,25 @@
|
|||
[(set (match_dup 0) (match_dup 1))]
|
||||
"operands[0] = adjust_address (operands[0], <ssescalarmode>mode, 0);")
|
||||
|
||||
;; Standard scalar operation patterns which preserve the rest of the
|
||||
;; vector for combiner.
|
||||
(define_insn "vec_setv2df_0"
|
||||
[(set (match_operand:V2DF 0 "register_operand" "=x,v,x,v")
|
||||
(vec_merge:V2DF
|
||||
(vec_duplicate:V2DF
|
||||
(match_operand:DF 2 "nonimmediate_operand" " x,v,m,m"))
|
||||
(match_operand:V2DF 1 "register_operand" " 0,v,0,v")
|
||||
(const_int 1)))]
|
||||
"TARGET_SSE2"
|
||||
"@
|
||||
movsd\t{%2, %0|%0, %2}
|
||||
vmovsd\t{%2, %1, %0|%0, %1, %2}
|
||||
movlpd\t{%2, %0|%0, %2}
|
||||
vmovlpd\t{%2, %1, %0|%0, %1, %2}"
|
||||
[(set_attr "isa" "noavx,avx,noavx,avx")
|
||||
(set_attr "type" "ssemov")
|
||||
(set_attr "mode" "DF")])
|
||||
|
||||
(define_expand "vec_set<mode>"
|
||||
[(match_operand:V 0 "register_operand")
|
||||
(match_operand:<ssescalarmode> 1 "register_operand")
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
2019-06-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/54855
|
||||
* gcc.target/i386/pr54855-1.c: New test.
|
||||
* gcc.target/i386/pr54855-2.c: Likewise.
|
||||
* gcc.target/i386/pr54855-3.c: Likewise.
|
||||
* gcc.target/i386/pr54855-4.c: Likewise.
|
||||
* gcc.target/i386/pr54855-5.c: Likewise.
|
||||
* gcc.target/i386/pr54855-6.c: Likewise.
|
||||
* gcc.target/i386/pr54855-7.c: Likewise.
|
||||
* gcc.target/i386/pr54855-8.c: Likewise.
|
||||
* gcc.target/i386/pr54855-9.c: Likewise.
|
||||
* gcc.target/i386/pr54855-10.c: Likewise.
|
||||
|
||||
2019-06-20 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* gcc.c-torture/execute/alias-access-path-1.c: New testcase.
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "addsd" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movapd" } } */
|
||||
/* { dg-final { scan-assembler-not "movsd" } } */
|
||||
|
||||
typedef double __v2df __attribute__ ((__vector_size__ (16)));
|
||||
typedef double __m128d __attribute__ ((__vector_size__ (16), __may_alias__));
|
||||
|
||||
__m128d
|
||||
_mm_add_sd (__m128d x, __m128d y)
|
||||
{
|
||||
__m128d z = __extension__ (__m128d)(__v2df)
|
||||
{ (((__v2df) x)[0] + ((__v2df) y)[0]), ((__v2df) x)[1] };
|
||||
return z;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "movlpd" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movsd" } } */
|
||||
|
||||
typedef double vec __attribute__((vector_size(16)));
|
||||
|
||||
vec
|
||||
foo (vec x, double *a)
|
||||
{
|
||||
x[0] = *a;
|
||||
return x;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "mulsd" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movapd" } } */
|
||||
/* { dg-final { scan-assembler-not "movsd" } } */
|
||||
|
||||
typedef double __v2df __attribute__ ((__vector_size__ (16)));
|
||||
|
||||
__v2df
|
||||
_mm_mul_sd (__v2df x, __v2df y)
|
||||
{
|
||||
__v2df z = x;
|
||||
z[0] = x[0] * y[0];
|
||||
return z;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "subsd" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movapd" } } */
|
||||
/* { dg-final { scan-assembler-not "movsd" } } */
|
||||
|
||||
typedef double vec __attribute__((vector_size(16)));
|
||||
|
||||
vec
|
||||
foo (vec x)
|
||||
{
|
||||
x[0] -= 1.;
|
||||
return x;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "subsd" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movapd" } } */
|
||||
/* { dg-final { scan-assembler-not "movsd" } } */
|
||||
|
||||
typedef double vec __attribute__((vector_size(16)));
|
||||
|
||||
vec
|
||||
foo (vec x, double a)
|
||||
{
|
||||
x[0] -= a;
|
||||
return x;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "subsd" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "mulpd" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movapd" } } */
|
||||
/* { dg-final { scan-assembler-not "movsd" } } */
|
||||
|
||||
typedef double __v2df __attribute__ ((__vector_size__ (16)));
|
||||
|
||||
__v2df
|
||||
foo (__v2df x, __v2df y)
|
||||
{
|
||||
x[0] -= y[0];
|
||||
x *= y;
|
||||
return x;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "divss" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movaps" } } */
|
||||
/* { dg-final { scan-assembler-not "movss" } } */
|
||||
|
||||
typedef float vec __attribute__((vector_size(16)));
|
||||
|
||||
vec
|
||||
foo (vec x, float f)
|
||||
{
|
||||
x[0] /= f;
|
||||
return x;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "divss" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movaps" } } */
|
||||
/* { dg-final { scan-assembler-not "movss" } } */
|
||||
|
||||
typedef float vec __attribute__((vector_size(16)));
|
||||
|
||||
vec
|
||||
foo (vec x)
|
||||
{
|
||||
x[0] /= 2.1f;
|
||||
return x;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "maxsd" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movapd" } } */
|
||||
/* { dg-final { scan-assembler-not "movsd" } } */
|
||||
|
||||
typedef double vec __attribute__((vector_size(16)));
|
||||
|
||||
vec
|
||||
foo (vec x, double a)
|
||||
{
|
||||
x[0] = x[0] > a ? x[0] : a;
|
||||
return x;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
/* { dg-final { scan-assembler-times "minss" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "movaps" } } */
|
||||
/* { dg-final { scan-assembler-not "movss" } } */
|
||||
|
||||
typedef float vec __attribute__((vector_size(16)));
|
||||
|
||||
vec
|
||||
foo (vec x, float a)
|
||||
{
|
||||
x[0] = x[0] < a ? x[0] : a;
|
||||
return x;
|
||||
}
|
Loading…
Reference in New Issue