aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingling Kong <lingling.kong@intel.com>2024-08-14 16:42:29 +0800
committerLingling Kong <lingling.kong@intel.com>2024-08-14 17:00:48 +0800
commitd08a5f211135374b3ad700780c46a198cd320328 (patch)
treefa06e3f3d7e53967256a0db8fc1bc03e5434f89c
parent1b761744dc3ea6f3d66a9c48f16719ad1c92d5ad (diff)
downloadgcc-d08a5f211135374b3ad700780c46a198cd320328.zip
gcc-d08a5f211135374b3ad700780c46a198cd320328.tar.gz
gcc-d08a5f211135374b3ad700780c46a198cd320328.tar.bz2
i386: Optimization for APX NDD is always zero-uppered for logic
gcc/ChangeLog: PR target/113729 * config/i386/i386.md (*andqi_1_zext<mode><nf_name>): New define_insn. (*andhi_1_zext<mode><nf_name>): Ditto. (*<code>qi_1_zext<mode><nf_name>): Ditto. (*<code>hi_1_zext<mode><nf_name>): Ditto. (*negqi_1_zext<mode><nf_name>): Ditto. (*neghi_1_zext<mode><nf_name>): Ditto. (*one_cmplqi2_1_zext<mode>): Ditto. (*one_cmplhi2_1_zext<mode>): Ditto. gcc/testsuite/ChangeLog: * gcc.target/i386/pr113729.c: Add more tests.
-rw-r--r--gcc/config/i386/i386.md94
-rw-r--r--gcc/testsuite/gcc.target/i386/pr113729.c40
2 files changed, 134 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index e267b33..9f933e9 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12478,6 +12478,34 @@
operands[2] = gen_lowpart (SImode, operands[2]);
})
+(define_insn "*andqi_1_zext<mode><nf_name>"
+ [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
+ (zero_extend:SWI248x
+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%rm,r")
+ (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))]
+ "TARGET_APX_NDD && <nf_condition>
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ "@
+ <nf_prefix>and{b}\t{%2, %1, %b0|%b0, %1, %2}
+ <nf_prefix>and{b}\t{%2, %1, %b0|%b0, %1, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "has_nf" "1")
+ (set_attr "mode" "QI")])
+
+(define_insn "*andhi_1_zext<mode><nf_name>"
+ [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
+ (zero_extend:SWI48x
+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,r")
+ (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))]
+ "TARGET_APX_NDD && <nf_condition>
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ "@
+ <nf_prefix>and{w}\t{%2, %1, %w0|%w0, %1, %2}
+ <nf_prefix>and{w}\t{%2, %1, %w0|%w0, %1, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "has_nf" "1")
+ (set_attr "mode" "HI")])
+
;; See comment for addsi_1_zext why we do use nonimmediate_operand
(define_insn "*andsi_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
@@ -13539,6 +13567,34 @@
operands[5] = gen_reg_rtx (<MODE>mode);
})
+(define_insn "*<code>qi_1_zext<mode><nf_name>"
+ [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
+ (zero_extend:SWI248x
+ (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%rm,r")
+ (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))]
+ "TARGET_APX_NDD && <nf_condition>
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ "@
+ <nf_prefix><logic>{b}\t{%2, %1, %b0|%b0, %1, %2}
+ <nf_prefix><logic>{b}\t{%2, %1, %b0|%b0, %1, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "has_nf" "1")
+ (set_attr "mode" "QI")])
+
+(define_insn "*<code>hi_1_zext<mode><nf_name>"
+ [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
+ (zero_extend:SWI48x
+ (any_or:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,r")
+ (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))]
+ "TARGET_APX_NDD && <nf_condition>
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ "@
+ <nf_prefix><logic>{w}\t{%2, %1, %w0|%w0, %1, %2}
+ <nf_prefix><logic>{w}\t{%2, %1, %w0|%w0, %1, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "has_nf" "1")
+ (set_attr "mode" "HI")])
+
;; See comment for addsi_1_zext why we do use nonimmediate_operand
(define_insn "*<code>si_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
@@ -14157,6 +14213,26 @@
(set_attr "has_nf" "1")
(set_attr "mode" "<MODE>")])
+(define_insn "*negqi_1_zext<mode><nf_name>"
+ [(set (match_operand:SWI248x 0 "register_operand" "=r")
+ (zero_extend:SWI248x
+ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "rm"))))]
+ "TARGET_APX_NDD && <nf_condition>"
+ "<nf_prefix>neg{b}\t{%b1, %b0|%b0, %b1}"
+ [(set_attr "type" "negnot")
+ (set_attr "has_nf" "1")
+ (set_attr "mode" "QI")])
+
+(define_insn "*neghi_1_zext<mode><nf_name>"
+ [(set (match_operand:SWI48x 0 "register_operand" "=r")
+ (zero_extend:SWI48x
+ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))]
+ "TARGET_APX_NDD && <nf_condition>"
+ "<nf_prefix>neg{w}\t{%w1, %w0|%w0, %w1}"
+ [(set_attr "type" "negnot")
+ (set_attr "has_nf" "1")
+ (set_attr "mode" "HI")])
+
(define_insn "*negsi_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI
@@ -14779,6 +14855,24 @@
(set_attr "type" "negnot,negnot,msklog")
(set_attr "mode" "<MODE>")])
+(define_insn "*one_cmplqi2_1_zext<mode>"
+ [(set (match_operand:SWI248x 0 "register_operand" "=r")
+ (zero_extend:SWI248x
+ (not:QI (match_operand:QI 1 "nonimmediate_operand" "rm"))))]
+ "TARGET_APX_NDD"
+ "not{b}\t{%1, %b0|%b0, %1}"
+ [(set_attr "type" "negnot")
+ (set_attr "mode" "QI")])
+
+(define_insn "*one_cmplhi2_1_zext<mode>"
+ [(set (match_operand:SWI48x 0 "register_operand" "=r")
+ (zero_extend:SWI48x
+ (not:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))]
+ "TARGET_APX_NDD"
+ "not{w}\t{%1, %w0|%w0, %1}"
+ [(set_attr "type" "negnot")
+ (set_attr "mode" "HI")])
+
(define_insn "*one_cmplsi2_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r,r,?k")
(zero_extend:DI
diff --git a/gcc/testsuite/gcc.target/i386/pr113729.c b/gcc/testsuite/gcc.target/i386/pr113729.c
index b24cb0e..d17e099 100644
--- a/gcc/testsuite/gcc.target/i386/pr113729.c
+++ b/gcc/testsuite/gcc.target/i386/pr113729.c
@@ -31,3 +31,43 @@ F (int, char, sub, -)
F (int64_t, char, sub, -)
F (int, short, sub, -)
F (int64_t, short, sub, -)
+
+#define F1(TYPE1, TYPE2, OP_NAME, OP) \
+TYPE1 \
+__attribute__ ((noipa)) \
+f3_##OP_NAME##_##TYPE2##_##TYPE1 (unsigned TYPE2 *a) \
+{ \
+ unsigned TYPE2 b = OP*a; \
+ return b; \
+}
+/* neghi_1_zext<mode> */
+F1 (short, char, neg, -)
+F1 (int, char, neg, -)
+F1 (int64_t, char, neg, -)
+F1 (int, short, neg, -)
+F1 (int64_t, short, neg, -)
+/* one_cmplqi2_1_zext<mode> */
+F1 (short, char, not, ~)
+F1 (int, char, not, ~)
+F1 (int64_t, char, not, ~)
+F1 (int, short, not, ~)
+F1 (int64_t, short, not, ~)
+
+/* andqi_1_zext<mode> */
+F (short, char, and, &)
+F (int, char, and, &)
+F (int64_t, char, and, &)
+F (int, short, and, &)
+F (int64_t, short, and, &)
+/* iorqi_1_zext<mode> */
+F (short, char, or, |)
+F (int, char, or, |)
+F (int64_t, char, or, |)
+F (int, short, or, |)
+F (int64_t, short, or, |)
+/* xorqi_1_zext<mode> */
+F (short, char, xor, ^)
+F (int, char, xor, ^)
+F (int64_t, char, xor, ^)
+F (int, short, xor, ^)
+F (int64_t, short, xor, ^)