(symbol_ref "true")))])
(define_insn "*movhi_internal"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k")
- (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k,CBC"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,*k,*k ,*r,*m,*k")
+ (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,*r,*km,*k,*k,CBC"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
switch (get_attr_type (insn))
(define_insn "*movqi_internal"
[(set (match_operand:QI 0 "nonimmediate_operand"
- "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k")
+ "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
(match_operand:QI 1 "general_operand"
- "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))]
+ "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
char buf[128];
]
(const_string "QI")))])
+/* Reload dislikes loading 0/-1 directly into mask registers.
+ Try to tidy things up here. */
+(define_peephole2
+ [(set (match_operand:SWI 0 "general_reg_operand")
+ (match_operand:SWI 1 "immediate_operand"))
+ (set (match_operand:SWI 2 "mask_reg_operand")
+ (match_dup 0))]
+ "peep2_reg_dead_p (2, operands[0])
+ && (const0_operand (operands[1], <MODE>mode)
+ || (constm1_operand (operands[1], <MODE>mode)
+ && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
+ [(set (match_dup 2) (match_dup 1))])
+
;; Stores and loads of ax to arbitrary constant address.
;; We fake an second form of instruction to force reload to load address
;; into register when rax is not available
})
(define_insn "*anddi_1"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,k")
(and:DI
- (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
- (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L")))
+ (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
+ (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
"@
and{l}\t{%k2, %k0|%k0, %k2}
and{q}\t{%2, %0|%0, %2}
and{q}\t{%2, %0|%0, %2}
+ #
#"
- [(set_attr "type" "alu,alu,alu,imovx")
- (set_attr "length_immediate" "*,*,*,0")
+ [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
+ (set_attr "type" "alu,alu,alu,imovx,msklog")
+ (set_attr "length_immediate" "*,*,*,0,*")
(set (attr "prefix_rex")
(if_then_else
(and (eq_attr "type" "imovx")
(match_operand 1 "ext_QIreg_operand")))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "SI,DI,DI,SI")])
+ (set_attr "mode" "SI,DI,DI,SI,DI")])
(define_insn_and_split "*anddi_1_btr"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
(set_attr "mode" "SI")])
(define_insn "*and<mode>_1"
- [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
- (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
- (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L")))
+ [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,k")
+ (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
+ (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L,k")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (AND, <MODE>mode, operands)"
"@
and{<imodesuffix>}\t{%2, %0|%0, %2}
and{<imodesuffix>}\t{%2, %0|%0, %2}
+ #
#"
- [(set_attr "type" "alu,alu,imovx")
- (set_attr "length_immediate" "*,*,0")
+ [(set (attr "isa")
+ (cond [(eq_attr "alternative" "3")
+ (if_then_else (eq_attr "mode" "SI")
+ (const_string "avx512bw")
+ (const_string "avx512f"))
+ ]
+ (const_string "*")))
+ (set_attr "type" "alu,alu,imovx,msklog")
+ (set_attr "length_immediate" "*,*,0,*")
(set (attr "prefix_rex")
(if_then_else
(and (eq_attr "type" "imovx")
(match_operand 1 "ext_QIreg_operand")))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "<MODE>,<MODE>,SI")])
+ (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
(define_insn "*andqi_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
- (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qn,m,rn")))
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,k")
+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
+ (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (AND, QImode, operands)"
"@
and{b}\t{%2, %0|%0, %2}
and{b}\t{%2, %0|%0, %2}
- and{l}\t{%k2, %k0|%k0, %k2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "QI,QI,SI")
+ and{l}\t{%k2, %k0|%k0, %k2}
+ #"
+ [(set_attr "type" "alu,alu,alu,msklog")
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "2")
+ (const_string "SI")
+ (and (eq_attr "alternative" "3")
+ (match_test "!TARGET_AVX512DQ"))
+ (const_string "HI")
+ ]
+ (const_string "QI")))
;; Potential partial reg stall on alternative 2.
(set (attr "preferred_for_speed")
(cond [(eq_attr "alternative" "2")
})
(define_insn "*andn<mode>_1"
- [(set (match_operand:SWI48 0 "register_operand" "=r,r")
+ [(set (match_operand:SWI48 0 "register_operand" "=r,r,k")
(and:SWI48
- (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
- (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
+ (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
+ (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "andn\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "bitmanip")
- (set_attr "btver2_decode" "direct, double")
+ "TARGET_BMI || TARGET_AVX512BW"
+ "@
+ andn\t{%2, %1, %0|%0, %1, %2}
+ andn\t{%2, %1, %0|%0, %1, %2}
+ #"
+ [(set_attr "isa" "bmi,bmi,avx512bw")
+ (set_attr "type" "bitmanip,bitmanip,msklog")
+ (set_attr "btver2_decode" "direct, double,*")
(set_attr "mode" "<MODE>")])
(define_insn "*andn<mode>_1"
- [(set (match_operand:SWI12 0 "register_operand" "=r")
+ [(set (match_operand:SWI12 0 "register_operand" "=r,k")
(and:SWI12
- (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
- (match_operand:SWI12 2 "register_operand" "r")))
+ (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
+ (match_operand:SWI12 2 "register_operand" "r,k")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
- [(set_attr "type" "bitmanip")
- (set_attr "btver2_decode" "direct")
- (set_attr "mode" "SI")])
+ "TARGET_BMI || TARGET_AVX512BW"
+ "@
+ andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
+ #"
+ [(set_attr "isa" "bmi,avx512f")
+ (set_attr "type" "bitmanip,msklog")
+ (set_attr "btver2_decode" "direct,*")
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "0")
+ (const_string "SI")
+ (and (eq_attr "alternative" "1")
+ (match_test "!TARGET_AVX512DQ"))
+ (const_string "HI")
+ ]
+ (const_string "<MODE>")))])
(define_insn "*andn_<mode>_ccno"
[(set (reg FLAGS_REG)
})
(define_insn "*<code><mode>_1"
- [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r")
+ [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,k")
(any_or:SWI248
- (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI248 2 "<general_operand>" "r<i>,m")))
+ (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
+ (match_operand:SWI248 2 "<general_operand>" "r<i>,m,k")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
- "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
+ "@
+ <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+ <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+ #"
+ [(set (attr "isa")
+ (cond [(eq_attr "alternative" "2")
+ (if_then_else (eq_attr "mode" "SI,DI")
+ (const_string "avx512bw")
+ (const_string "avx512f"))
+ ]
+ (const_string "*")))
+ (set_attr "type" "alu, alu, msklog")
(set_attr "mode" "<MODE>")])
(define_insn_and_split "*iordi_1_bts"
(set_attr "mode" "SI")])
(define_insn "*<code>qi_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
- (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qn,m,rn")))
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,k")
+ (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
+ (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (<CODE>, QImode, operands)"
"@
<logic>{b}\t{%2, %0|%0, %2}
<logic>{b}\t{%2, %0|%0, %2}
- <logic>{l}\t{%k2, %k0|%k0, %k2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "QI,QI,SI")
+ <logic>{l}\t{%k2, %k0|%k0, %k2}
+ #"
+ [(set_attr "isa" "*,*,*,avx512f")
+ (set_attr "type" "alu,alu,alu,msklog")
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "2")
+ (const_string "SI")
+ (and (eq_attr "alternative" "3")
+ (match_test "!TARGET_AVX512DQ"))
+ (const_string "HI")
+ ]
+ (const_string "QI")))
;; Potential partial reg stall on alternative 2.
(set (attr "preferred_for_speed")
(cond [(eq_attr "alternative" "2")
"split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
(define_insn "*one_cmpl<mode>2_1"
- [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
- (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
+ [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,k")
+ (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
"ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
- "not{<imodesuffix>}\t%0"
- [(set_attr "type" "negnot")
+ "@
+ not{<imodesuffix>}\t%0
+ #"
+ [(set (attr "isa")
+ (cond [(eq_attr "alternative" "2")
+ (if_then_else (eq_attr "mode" "SI,DI")
+ (const_string "avx512bw")
+ (const_string "avx512f"))
+ ]
+ (const_string "*")))
+ (set_attr "type" "negnot,msklog")
(set_attr "mode" "<MODE>")])
(define_insn "*one_cmplsi2_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
+ [(set (match_operand:DI 0 "register_operand" "=r,k")
(zero_extend:DI
- (not:SI (match_operand:SI 1 "register_operand" "0"))))]
+ (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
"TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
- "not{l}\t%k0"
- [(set_attr "type" "negnot")
- (set_attr "mode" "SI")])
+ "@
+ not{l}\t%k0
+ #"
+ [(set_attr "isa" "x64,avx512bw")
+ (set_attr "type" "negnot,msklog")
+ (set_attr "mode" "SI,SI")])
(define_insn "*one_cmplqi2_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
- (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,k")
+ (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
"ix86_unary_operator_ok (NOT, QImode, operands)"
"@
not{b}\t%0
- not{l}\t%k0"
- [(set_attr "type" "negnot")
- (set_attr "mode" "QI,SI")
+ not{l}\t%k0
+ #"
+ [(set_attr "isa" "*,*,avx512f")
+ (set_attr "type" "negnot,negnot,msklog")
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "1")
+ (const_string "SI")
+ (and (eq_attr "alternative" "2")
+ (match_test "!TARGET_AVX512DQ"))
+ (const_string "HI")
+ ]
+ (const_string "QI")))
;; Potential partial reg stall on alternative 1.
(set (attr "preferred_for_speed")
(cond [(eq_attr "alternative" "1")
--- /dev/null
+/* PR target/88808 */
+/* { dg-do compile } */
+/* { dg-options "-mavx512bw -mno-avx512dq -O2" } */
+
+#include <immintrin.h>
+__m512i
+foo_orq (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask64 m1 = _mm512_cmpeq_epi8_mask (a, b);
+ __mmask64 m2 = _mm512_cmpeq_epi8_mask (c, d);
+ return _mm512_mask_add_epi8 (c, m1 | m2, a, d);
+}
+
+/* { dg-final { scan-assembler-times "korq" "1" { target { ! ia32 } } } } */
+
+__m512i
+foo_ord (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask32 m1 = _mm512_cmpeq_epi16_mask (a, b);
+ __mmask32 m2 = _mm512_cmpeq_epi16_mask (c, d);
+ return _mm512_mask_add_epi16 (c, m1 | m2, a, d);
+}
+
+/* { dg-final { scan-assembler-times "kord" "1" } } */
+
+__m512i
+foo_orw (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask16 m1 = _mm512_cmpeq_epi32_mask (a, b);
+ __mmask16 m2 = _mm512_cmpeq_epi32_mask (c, d);
+ return _mm512_mask_add_epi32 (c, m1 | m2, a, d);
+}
+
+__m512i
+foo_orb (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask8 m1 = _mm512_cmpeq_epi64_mask (a, b);
+ __mmask8 m2 = _mm512_cmpeq_epi64_mask (c, d);
+ return _mm512_mask_add_epi64 (c, m1 | m2, a, d);
+}
+
+/* { dg-final { scan-assembler-times "korw" "2" } } */
+
+__m512i
+foo_xorq (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask64 m1 = _mm512_cmpeq_epi8_mask (a, b);
+ __mmask64 m2 = _mm512_cmpeq_epi8_mask (c, d);
+ return _mm512_mask_add_epi8 (c, m1 ^ m2, a, d);
+}
+
+/* { dg-final { scan-assembler-times "kxorq" "1" { target { ! ia32 } } } } */
+
+__m512i
+foo_xord (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask32 m1 = _mm512_cmpeq_epi16_mask (a, b);
+ __mmask32 m2 = _mm512_cmpeq_epi16_mask (c, d);
+ return _mm512_mask_add_epi16 (c, m1 ^ m2, a, d);
+}
+
+/* { dg-final { scan-assembler-times "kxord" "1" } } */
+
+__m512i
+foo_xorw (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask16 m1 = _mm512_cmpeq_epi32_mask (a, b);
+ __mmask16 m2 = _mm512_cmpeq_epi32_mask (c, d);
+ return _mm512_mask_add_epi32 (c, m1 ^ m2, a, d);
+}
+
+__m512i
+foo_xorb (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask8 m1 = _mm512_cmpeq_epi64_mask (a, b);
+ __mmask8 m2 = _mm512_cmpeq_epi64_mask (c, d);
+ return _mm512_mask_add_epi64 (c, m1 ^ m2, a, d);
+}
+
+/* { dg-final { scan-assembler-times "korw" "2" } } */
+
+__m512i
+foo_andq (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask64 m1 = _mm512_cmpeq_epi8_mask (a, b);
+ __mmask64 m2 = _mm512_cmpeq_epi8_mask (c, d);
+ return _mm512_mask_add_epi8 (c, m1 & m2, a, d);
+}
+
+__m512i
+foo_andd (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask32 m1 = _mm512_cmpeq_epi16_mask (a, b);
+ __mmask32 m2 = _mm512_cmpeq_epi16_mask (c, d);
+ return _mm512_mask_add_epi16 (c, m1 & m2, a, d);
+}
+
+__m512i
+foo_andw (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask16 m1 = _mm512_cmpeq_epi32_mask (a, b);
+ __mmask16 m2 = _mm512_cmpeq_epi32_mask (c, d);
+ return _mm512_mask_add_epi32 (c, m1 & m2, a, d);
+}
+
+__m512i
+foo_andb (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask8 m1 = _mm512_cmpeq_epi64_mask (a, b);
+ __mmask8 m2 = _mm512_cmpeq_epi64_mask (c, d);
+ return _mm512_mask_add_epi64 (c, m1 & m2, a, d);
+}
+
+__m512i
+foo_andnq (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask64 m1 = _mm512_cmpeq_epi8_mask (a, b);
+ __mmask64 m2 = _mm512_cmpeq_epi8_mask (c, d);
+ return _mm512_mask_add_epi8 (c, m1 & ~m2, a, d);
+}
+
+__m512i
+foo_andnd (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask32 m1 = _mm512_cmpeq_epi16_mask (a, b);
+ __mmask32 m2 = _mm512_cmpeq_epi16_mask (c, d);
+ return _mm512_mask_add_epi16 (c, m1 & ~m2, a, d);
+}
+
+__m512i
+foo_andnw (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask16 m1 = _mm512_cmpeq_epi32_mask (a, b);
+ __mmask16 m2 = _mm512_cmpeq_epi32_mask (c, d);
+ return _mm512_mask_add_epi32 (c, m1 & ~m2, a, d);
+}
+
+__m512i
+foo_andnb (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask8 m1 = _mm512_cmpeq_epi64_mask (a, b);
+ __mmask8 m2 = _mm512_cmpeq_epi64_mask (c, d);
+ return _mm512_mask_add_epi64 (c, m1 & ~m2, a, d);
+}
+
+__m512i
+foo_notq (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask64 m1 = _mm512_cmpeq_epi8_mask (a, b);
+ return _mm512_mask_add_epi8 (c, ~m1, a, d);
+}
+
+/* { dg-final { scan-assembler-times "knotq" "2" { target { ! ia32 } } } } */
+
+__m512i
+foo_notd (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask32 m1 = _mm512_cmpeq_epi16_mask (a, b);
+ return _mm512_mask_add_epi16 (c, ~m1, a, d);
+}
+
+/* { dg-final { scan-assembler-times "knotd" "2" { target { ! ia32 } } } } */
+
+__m512i
+foo_notw (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask16 m1 = _mm512_cmpeq_epi32_mask (a, b);
+ return _mm512_mask_add_epi32 (c, ~m1, a, d);
+}
+
+__m512i
+foo_notb (__m512i a, __m512i b, __m512i c, __m512i d)
+{
+ __mmask8 m1 = _mm512_cmpeq_epi64_mask (a, b);
+ return _mm512_mask_add_epi64 (c, ~m1, a, d);
+}
+
+/* { dg-final { scan-assembler-times "knotw" "4" } } */