From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) by sourceware.org (Postfix) with ESMTPS id 28129385840B for ; Wed, 6 Dec 2023 08:08:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 28129385840B Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 28129385840B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701850125; cv=none; b=s/0ZDZy+zDjQhgV0giFAHdNuGUwL//fFLX2TUcOKERKvZ/j+ZBIgChG7j1bF5SxcB1glgyZ996OvrRPPRv/vC9jqoowEeezVlsR2o4UV/67prZa+vSEUDmchkbGOFdw2Cu9ypEy6B1KAEdYEO1RluSrRnS1aB6HwInGM/oRvouM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701850125; c=relaxed/simple; bh=udrlvmQVVVndr2ELdEFi/x9GSbQg0R+X5RbtpTEkUJE=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=WfRbxFNGhZNR1g2u9wyo5mYRoOFa8a1J7nU7biSg/DVvJ0ZCaj/9nkpo2eBGDhCzms6Yjiro8PokPEJNiRa+O5GaFmB8SgIpnQ2uMSOgsO0TC3TJQkPzudSETDjZVkCtldiOKXjlvx3clMA/61MG7RyjiOyEAgJwP5Va0crec/Q= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701850124; x=1733386124; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=udrlvmQVVVndr2ELdEFi/x9GSbQg0R+X5RbtpTEkUJE=; b=bApej/F6Eb5jZZKVffWEuWG20cf0xRP6EvoDuYJrS5rvj5c9Am4gquZv q1nlLHYyf4GsYHH8v7KHsGRL83JU9O3ZkXt4LVppolD5EfdvSFDc/PGap 8TfJS/V/UD1P8POrFfztmFympvCmfExJfVwszkWo1kDsFcLtOqxrL6yq3 6+yrvpS+vaW+IVrbQU/ApBf3DV/oSHB1xiZz6sCDL+3ZA6+JqkpJZMI61 H+OAO+cflsN6CU0WNNAsEIWoPuh4tG6UEh81/kdCUM9CjzSX1zXbuSvCy x3PXp/WVjWwxe/DDYWEokVUBaCQx5P8QZEGgkv3znSvl3a7YN6ymrBKd4 A==; X-IronPort-AV: E=McAfee;i="6600,9927,10915"; a="1085455" X-IronPort-AV: E=Sophos;i="6.04,254,1695711600"; d="scan'208";a="1085455" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Dec 2023 00:08:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10915"; a="1102737740" X-IronPort-AV: E=Sophos;i="6.04,254,1695711600"; d="scan'208";a="1102737740" Received: from shvmail03.sh.intel.com ([10.239.245.20]) by fmsmga005.fm.intel.com with ESMTP; 06 Dec 2023 00:08:37 -0800 Received: from shliclel4217.sh.intel.com (shliclel4217.sh.intel.com [10.239.240.127]) by shvmail03.sh.intel.com (Postfix) with ESMTP id 86FBD10056EF; Wed, 6 Dec 2023 16:08:36 +0800 (CST) From: Hongyu Wang To: gcc-patches@gcc.gnu.org Cc: ubizjak@gmail.com, hongtao.liu@intel.com, Kong Lingling Subject: [PATCH 01/16] [APX NDD] Support Intel APX NDD for legacy add insn Date: Wed, 6 Dec 2023 16:06:21 +0800 Message-Id: <20231206080636.178863-2-hongyu.wang@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20231206080636.178863-1-hongyu.wang@intel.com> References: <20231206080636.178863-1-hongyu.wang@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,KAM_SHORT,SPF_HELO_NONE,SPF_SOFTFAIL,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Kong Lingling APX NDD provides an extra destination register operand for several gpr related legacy insns, so a new alternative can be adopted to operand1 with "r" constraint. This first patch supports NDD for add instruction, and keeps to use lea when all operands are registers since lea have shorter encoding. For add operations containing mem NDD will be adopted to save an extra move. In legacy x86 binary operation expand it will force operands[0] and operands[1] to be the same so add a helper function to allow NDD form pattern that operands[0] and operands[1] can be different. gcc/ChangeLog: * config/i386/i386-expand.cc (ix86_fixup_binary_operands): Add new use_ndd flag to check whether ndd can be used for this binop and adjust operand emit. (ix86_binary_operator_ok): Likewise. (ix86_expand_binary_operator): Likewise, and void postreload expand generate lea pattern when use_ndd is explicit parsed. * config/i386/i386-options.cc (ix86_option_override_internal): Prohibit apx subfeatures when not in 64bit mode. * config/i386/i386-protos.h (ix86_binary_operator_ok): Add use_ndd flag. (ix86_fixup_binary_operand): Likewise. (ix86_expand_binary_operand): Likewise. * config/i386/i386.md (*add_1): Extend with new alternatives to support NDD, and adjust output template. (*addhi_1): Likewise. (*addqi_1): Likewise. gcc/testsuite/ChangeLog: * gcc.target/i386/apx-ndd.c: New test. --- gcc/config/i386/i386-expand.cc | 19 ++--- gcc/config/i386/i386-options.cc | 2 + gcc/config/i386/i386-protos.h | 6 +- gcc/config/i386/i386.md | 102 ++++++++++++++---------- gcc/testsuite/gcc.target/i386/apx-ndd.c | 21 +++++ 5 files changed, 96 insertions(+), 54 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd.c diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 4bd7d4f39c8..3ecda989cf8 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -1260,14 +1260,14 @@ ix86_swap_binary_operands_p (enum rtx_code code, machine_mode mode, return false; } - /* Fix up OPERANDS to satisfy ix86_binary_operator_ok. Return the destination to use for the operation. If different from the true - destination in operands[0], a copy operation will be required. */ + destination in operands[0], a copy operation will be required except + under TARGET_APX_NDD. */ rtx ix86_fixup_binary_operands (enum rtx_code code, machine_mode mode, - rtx operands[]) + rtx operands[], bool use_ndd) { rtx dst = operands[0]; rtx src1 = operands[1]; @@ -1307,7 +1307,7 @@ ix86_fixup_binary_operands (enum rtx_code code, machine_mode mode, src1 = force_reg (mode, src1); /* Source 1 cannot be a non-matching memory. */ - if (MEM_P (src1) && !rtx_equal_p (dst, src1)) + if (!use_ndd && MEM_P (src1) && !rtx_equal_p (dst, src1)) src1 = force_reg (mode, src1); /* Improve address combine. */ @@ -1338,11 +1338,11 @@ ix86_fixup_binary_operands_no_copy (enum rtx_code code, void ix86_expand_binary_operator (enum rtx_code code, machine_mode mode, - rtx operands[]) + rtx operands[], bool use_ndd) { rtx src1, src2, dst, op, clob; - dst = ix86_fixup_binary_operands (code, mode, operands); + dst = ix86_fixup_binary_operands (code, mode, operands, use_ndd); src1 = operands[1]; src2 = operands[2]; @@ -1352,7 +1352,8 @@ ix86_expand_binary_operator (enum rtx_code code, machine_mode mode, if (reload_completed && code == PLUS - && !rtx_equal_p (dst, src1)) + && !rtx_equal_p (dst, src1) + && !use_ndd) { /* This is going to be an LEA; avoid splitting it later. */ emit_insn (op); @@ -1451,7 +1452,7 @@ ix86_expand_vector_logical_operator (enum rtx_code code, machine_mode mode, bool ix86_binary_operator_ok (enum rtx_code code, machine_mode mode, - rtx operands[3]) + rtx operands[3], bool use_ndd) { rtx dst = operands[0]; rtx src1 = operands[1]; @@ -1475,7 +1476,7 @@ ix86_binary_operator_ok (enum rtx_code code, machine_mode mode, return false; /* Source 1 cannot be a non-matching memory. */ - if (MEM_P (src1) && !rtx_equal_p (dst, src1)) + if (!use_ndd && MEM_P (src1) && !rtx_equal_p (dst, src1)) /* Support "andhi/andsi/anddi" as a zero-extending move. */ return (code == AND && (mode == HImode diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index f86ad332aad..7d0a253e07f 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -2129,6 +2129,8 @@ ix86_option_override_internal (bool main_args_p, if (TARGET_APX_F && !TARGET_64BIT) error ("%<-mapxf%> is not supported for 32-bit code"); + else if (opts->x_ix86_apx_features != apx_none && !TARGET_64BIT) + error ("%<-mapx-features=%> option is not supported for 32-bit code"); if (TARGET_UINTR && !TARGET_64BIT) error ("%<-muintr%> not supported for 32-bit code"); diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 28d0eab11d5..a9d0c568bba 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -108,14 +108,14 @@ extern void ix86_expand_move (machine_mode, rtx[]); extern void ix86_expand_vector_move (machine_mode, rtx[]); extern void ix86_expand_vector_move_misalign (machine_mode, rtx[]); extern rtx ix86_fixup_binary_operands (enum rtx_code, - machine_mode, rtx[]); + machine_mode, rtx[], bool = false); extern void ix86_fixup_binary_operands_no_copy (enum rtx_code, machine_mode, rtx[]); extern void ix86_expand_binary_operator (enum rtx_code, - machine_mode, rtx[]); + machine_mode, rtx[], bool = false); extern void ix86_expand_vector_logical_operator (enum rtx_code, machine_mode, rtx[]); -extern bool ix86_binary_operator_ok (enum rtx_code, machine_mode, rtx[3]); +extern bool ix86_binary_operator_ok (enum rtx_code, machine_mode, rtx[3], bool = false); extern bool ix86_avoid_lea_for_add (rtx_insn *, rtx[]); extern bool ix86_use_lea_for_mov (rtx_insn *, rtx[]); extern bool ix86_avoid_lea_for_addr (rtx_insn *, rtx[]); diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index df7f9172381..a5b123a51bd 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -562,7 +562,7 @@ (define_attr "unit" "integer,i387,sse,mmx,unknown" ;; Used to control the "enabled" attribute on a per-instruction basis. (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx, - x64_avx,x64_avx512bw,x64_avx512dq,aes, + x64_avx,x64_avx512bw,x64_avx512dq,aes,apx_ndd, sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx, avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512, noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq, @@ -960,6 +960,8 @@ (define_attr "enabled" "" (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL") (eq_attr "isa" "vpclmulqdqvl") (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL") + (eq_attr "isa" "apx_ndd") + (symbol_ref "TARGET_APX_NDD") (eq_attr "mmx_isa" "native") (symbol_ref "!TARGET_MMX_WITH_SSE") @@ -6288,7 +6290,8 @@ (define_expand "add3" (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand") (match_operand:SDWIM 2 "")))] "" - "ix86_expand_binary_operator (PLUS, mode, operands); DONE;") + "ix86_expand_binary_operator (PLUS, mode, operands, + TARGET_APX_NDD); DONE;") (define_insn_and_split "*add3_doubleword" [(set (match_operand: 0 "nonimmediate_operand" "=ro,r") @@ -6415,26 +6418,29 @@ (define_insn_and_split "*add3_doubleword_concat_zext" "split_double_mode (mode, &operands[0], 1, &operands[0], &operands[5]);") (define_insn "*add_1" - [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r") + [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r,r,r") (plus:SWI48 - (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") - (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le"))) + (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r,rm,r") + (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le,re,BM"))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (PLUS, mode, operands)" + "ix86_binary_operator_ok (PLUS, mode, operands, + TARGET_APX_NDD)" { + bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD; switch (get_attr_type (insn)) { case TYPE_LEA: return "#"; case TYPE_INCDEC: - gcc_assert (rtx_equal_p (operands[0], operands[1])); if (operands[2] == const1_rtx) - return "inc{}\t%0"; + return use_ndd ? "inc{}\t{%1, %0|%0, %1}" + : "inc{}\t%0"; else { gcc_assert (operands[2] == constm1_rtx); - return "dec{}\t%0"; + return use_ndd ? "dec{}\t{%1, %0|%0, %1}" + : "dec{}\t%0"; } default: @@ -6443,14 +6449,16 @@ (define_insn "*add_1" if (which_alternative == 2) std::swap (operands[1], operands[2]); - gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], mode)) - return "sub{}\t{%2, %0|%0, %2}"; + return use_ndd ? "sub{}\t{%2, %1, %0|%0, %1, %2}" + : "sub{}\t{%2, %0|%0, %2}"; - return "add{}\t{%2, %0|%0, %2}"; + return use_ndd ? "add{}\t{%2, %1, %0|%0, %1, %2}" + : "add{}\t{%2, %0|%0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd") + (set (attr "type") (cond [(eq_attr "alternative" "3") (const_string "lea") (match_operand:SWI48 2 "incdec_operand") @@ -6519,25 +6527,26 @@ (define_insn "addsi_1_zext" (set_attr "mode" "SI")]) (define_insn "*addhi_1" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp") - (match_operand:HI 2 "general_operand" "rn,m,0,ln"))) + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp,r,r") + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp,rm,r") + (match_operand:HI 2 "general_operand" "rn,m,0,ln,rn,m"))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (PLUS, HImode, operands)" + "ix86_binary_operator_ok (PLUS, HImode, operands, + TARGET_APX_NDD)" { + bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD; switch (get_attr_type (insn)) { case TYPE_LEA: return "#"; case TYPE_INCDEC: - gcc_assert (rtx_equal_p (operands[0], operands[1])); if (operands[2] == const1_rtx) - return "inc{w}\t%0"; + return use_ndd ? "inc{w}\t{%1, %0|%0, %1}" : "inc{w}\t%0"; else { gcc_assert (operands[2] == constm1_rtx); - return "dec{w}\t%0"; + return use_ndd ? "dec{w}\t{%1, %0|%0, %1}" : "dec{w}\t%0"; } default: @@ -6546,14 +6555,16 @@ (define_insn "*addhi_1" if (which_alternative == 2) std::swap (operands[1], operands[2]); - gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], HImode)) - return "sub{w}\t{%2, %0|%0, %2}"; + return use_ndd ? "sub{w}\t{%2, %1, %0|%0, %1, %2}" + : "sub{w}\t{%2, %0|%0, %2}"; - return "add{w}\t{%2, %0|%0, %2}"; + return use_ndd ? "add{w}\t{%2, %1, %0|%0, %1, %2}" + : "add{w}\t{%2, %0|%0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd") + (set (attr "type") (cond [(eq_attr "alternative" "3") (const_string "lea") (match_operand:HI 2 "incdec_operand") @@ -6565,30 +6576,35 @@ (define_insn "*addhi_1" (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) (const_string "1") (const_string "*"))) - (set_attr "mode" "HI,HI,HI,SI")]) + (set_attr "mode" "HI,HI,HI,SI,HI,HI")]) (define_insn "*addqi_1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp") - (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln"))) + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp,r,r") + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp,rm,r") + (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln,rn,m"))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (PLUS, QImode, operands)" + "ix86_binary_operator_ok (PLUS, QImode, operands, TARGET_APX_NDD)" { bool widen = (get_attr_mode (insn) != MODE_QI); - + bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD; switch (get_attr_type (insn)) { case TYPE_LEA: return "#"; case TYPE_INCDEC: - gcc_assert (rtx_equal_p (operands[0], operands[1])); if (operands[2] == const1_rtx) - return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; + if (use_ndd) + return "inc{b}\t{%1, %0|%0, %1}"; + else + return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; else { gcc_assert (operands[2] == constm1_rtx); - return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; + if (use_ndd) + return "dec{b}\t{%1, %0|%0, %1}"; + else + return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; } default: @@ -6597,21 +6613,23 @@ (define_insn "*addqi_1" if (which_alternative == 2 || which_alternative == 4) std::swap (operands[1], operands[2]); - gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], QImode)) { - if (widen) - return "sub{l}\t{%2, %k0|%k0, %2}"; + if (use_ndd) + return "sub{b}\t{%2, %1, %0|%0, %1, %2}"; else - return "sub{b}\t{%2, %0|%0, %2}"; + return widen ? "sub{l}\t{%2, %k0|%k0, %2}" + : "sub{b}\t{%2, %0|%0, %2}"; } - if (widen) - return "add{l}\t{%k2, %k0|%k0, %k2}"; + if (use_ndd) + return "add{b}\t{%2, %1, %0|%0, %1, %2}"; else - return "add{b}\t{%2, %0|%0, %2}"; + return widen ? "add{l}\t{%k2, %k0|%k0, %k2}" + : "add{b}\t{%2, %0|%0, %2}"; } } - [(set (attr "type") + [(set_attr "isa" "*,*,*,*,*,*,apx_ndd,apx_ndd") + (set (attr "type") (cond [(eq_attr "alternative" "5") (const_string "lea") (match_operand:QI 2 "incdec_operand") @@ -6623,7 +6641,7 @@ (define_insn "*addqi_1" (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) (const_string "1") (const_string "*"))) - (set_attr "mode" "QI,QI,QI,SI,SI,SI") + (set_attr "mode" "QI,QI,QI,SI,SI,SI,QI,QI") ;; Potential partial reg stall on alternatives 3 and 4. (set (attr "preferred_for_speed") (cond [(eq_attr "alternative" "3,4") diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd.c b/gcc/testsuite/gcc.target/i386/apx-ndd.c new file mode 100644 index 00000000000..056a323a647 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mapxf -march=x86-64 -O2" } */ +/* { dg-final { scan-assembler-not "movl"} } */ + +int foo (int *a) +{ + int b = *a - 1; + return b; +} + +int foo2 (int a, int b) +{ + int c = a + b; + return c; +} + +int foo3 (int *a, int b) +{ + int c = *a + b; + return c; +} -- 2.31.1