From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1005) id 7806138515E0; Thu, 10 Jun 2021 22:55:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7806138515E0 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Michael Meissner To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/meissner/heads/work055)] PR 101019: Improve loading 64-bit constants on power10. X-Act-Checkin: gcc X-Git-Author: Michael Meissner X-Git-Refname: refs/users/meissner/heads/work055 X-Git-Oldrev: d69367f2d3ffa90be72a1b52ad81692f0f25a33c X-Git-Newrev: 0f34f87fd5adb91d36b3ad961d9396567c5f7e98 Message-Id: <20210610225527.7806138515E0@sourceware.org> Date: Thu, 10 Jun 2021 22:55:27 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Jun 2021 22:55:27 -0000 https://gcc.gnu.org/g:0f34f87fd5adb91d36b3ad961d9396567c5f7e98 commit 0f34f87fd5adb91d36b3ad961d9396567c5f7e98 Author: Michael Meissner Date: Thu Jun 10 18:55:12 2021 -0400 PR 101019: Improve loading 64-bit constants on power10. When the support for prefixed instructions went into GCC, we did not modify loading up larger constants to use one or two PLI/PADDI instructions. This patch adds this support. gcc/ 2021-06-10 Michael Meissner PR target/101019 * config/rs6000/rs6000-cpus.def (ISA_3_1_MASKS_SERVER): Add -mpower10-large-consts support. (POWERPC_MASKS): Add -mpower10-large-consts support. * config/rs6000/rs6000.c (rs6000_option_override_internal): Add -mpower10-large-consts support. (num_insns_constant_gpr): Add -mpower10-large-consts support. (rs6000_emit_set_long_const): Add -mpower10-large-consts support. (rs6000_opt_masks): Add -mpower10-large-consts. * config/rs6000/rs6000.opt (-mpower10-large-consts): New switch. gcc/testsuite/ 2021-06-09 Michael Meissner PR target/101019 * gcc.target/powerpc/prefix-large-const.c: New test. Diff: --- gcc/config/rs6000/rs6000-cpus.def | 2 + gcc/config/rs6000/rs6000.c | 50 ++++++++++++++++++++-- gcc/config/rs6000/rs6000.opt | 4 ++ .../gcc.target/powerpc/prefix-large-const.c | 32 ++++++++++++++ 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def index c0d89434fcd..b119f574e4c 100644 --- a/gcc/config/rs6000/rs6000-cpus.def +++ b/gcc/config/rs6000/rs6000-cpus.def @@ -90,6 +90,7 @@ | OPTION_MASK_P10_FUSION_LOGADD \ | OPTION_MASK_P10_FUSION_ADDLOG \ | OPTION_MASK_P10_FUSION_2ADD \ + | OPTION_MASK_P10_LARGE_CONSTS \ | OPTION_MASK_XXSPLTI32DX \ | OPTION_MASK_XXSPLTIDP \ | OPTION_MASK_XXSPLTIW) @@ -145,6 +146,7 @@ | OPTION_MASK_P10_FUSION_LOGADD \ | OPTION_MASK_P10_FUSION_ADDLOG \ | OPTION_MASK_P10_FUSION_2ADD \ + | OPTION_MASK_P10_LARGE_CONSTS \ | OPTION_MASK_HTM \ | OPTION_MASK_ISEL \ | OPTION_MASK_LXVKQ \ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index ca92ee63d73..93e14570ed3 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -4489,6 +4489,12 @@ rs6000_option_override_internal (bool global_init_p) && (rs6000_isa_flags_explicit & OPTION_MASK_P10_FUSION_2ADD) == 0) rs6000_isa_flags |= OPTION_MASK_P10_FUSION_2ADD; + if (TARGET_PREFIXED + && (rs6000_isa_flags_explicit & OPTION_MASK_P10_LARGE_CONSTS) == 0) + rs6000_isa_flags |= OPTION_MASK_P10_LARGE_CONSTS; + else if (!TARGET_PREFIXED) + rs6000_isa_flags &= ~OPTION_MASK_P10_LARGE_CONSTS; + /* Turn off vector pair/mma options on non-power10 systems. */ else if (!TARGET_POWER10 && TARGET_MMA) { @@ -5959,9 +5965,20 @@ num_insns_constant_gpr (HOST_WIDE_INT value) && (value >> 31 == -1 || value >> 31 == 0)) return 1; - /* PADDI can support up to 34 bit signed integers. */ - else if (TARGET_PREFIXED && SIGNED_INTEGER_34BIT_P (value)) - return 1; + /* PADDI can support up to 34 bit signed integers, or using a combination of + PADDI and shift left. */ + else if (TARGET_P10_LARGE_CONSTS) + { + if (SIGNED_INTEGER_34BIT_P (value)) + return 1; + + /* PLI and SLDI. */ + if ((value & 0xffffffff) == 0) + return 2; + + /* PLI, SLDI, PADDI. */ + return 3; + } else if (TARGET_POWERPC64) { @@ -10415,7 +10432,31 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c) rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32)); emit_move_insn (dest, gen_rtx_IOR (DImode, one, two)); } - else if ((ud4 == 0xffff && (ud3 & 0x8000)) + /* We can't load R0 using PLI/SLDA/PADDI, since the R0 in the PADDI would be + interpreted as 0 and not register 0. */ + else if (TARGET_P10_LARGE_CONSTS + && (base_reg_operand (dest, DImode) + || can_create_pseudo_p () + || (ud1 == 0 && ud2 == 0))) + { + HOST_WIDE_INT low_32bit = ud1 | (ud2 << 16); + HOST_WIDE_INT high_32bit = ud3 | (ud4 << 16); + + temp = !can_create_pseudo_p () ? copy_rtx (dest) : gen_reg_rtx (DImode); + emit_move_insn (temp, GEN_INT (high_32bit)); + + if (!low_32bit) + emit_insn (gen_ashldi3 (dest, temp, GEN_INT (32))); + else + { + rtx temp2 = (!can_create_pseudo_p () + ? copy_rtx (dest) + : gen_reg_rtx (DImode)); + emit_insn (gen_ashldi3 (temp2, temp, GEN_INT (32))); + emit_insn (gen_adddi3 (dest, temp2, GEN_INT (low_32bit))); + } + } + else if ((ud4 == 0xaffff && (ud3 & 0x8000)) || (ud4 == 0 && ! (ud3 & 0x8000))) { temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); @@ -24424,6 +24465,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] = { "power9-misc", OPTION_MASK_P9_MISC, false, true }, { "power9-vector", OPTION_MASK_P9_VECTOR, false, true }, { "power10-fusion", OPTION_MASK_P10_FUSION, false, true }, + { "power10-large-consts", OPTION_MASK_P10_LARGE_CONSTS, false, true }, { "powerpc-gfxopt", OPTION_MASK_PPC_GFXOPT, false, true }, { "powerpc-gpopt", OPTION_MASK_PPC_GPOPT, false, true }, { "prefixed", OPTION_MASK_PREFIXED, false, true }, diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index e65dd8762a4..add22c8be1a 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -655,3 +655,7 @@ Generate (do not generate) XXSPLTI32DX instructions. mlxvkq Target Undocumented Mask(LXVKQ) Var(rs6000_isa_flags) Generate (do not generate) LXVKQ instructions. + +mpower10-large-consts +Target Undocumented Mask(P10_LARGE_CONSTS) Var(rs6000_isa_flags) +Generate (do not generate) PLI/SLDI/PADDI to load large constants. diff --git a/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c new file mode 100644 index 00000000000..fa4904efbc7 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/prefix-large-const.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_prefixed_addr } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2 -mdejagnu-cpu=power10" } */ + +/* Test whether we can use PLI/PADDI to load up large constants. */ + +long +foo_1 (void) +{ + return 1L << 53; /* LIS, SLDI. */ +} + +long +foo_2 (void) +{ + return (1L << 53) | (1L << 35); /* PLI, SLDI. */ +} + +long +foo_3 (void) +{ + return ((1L << 53) /* PLI, SLDI, PADDI. */ + | (1L << 35) + | (1L << 30) + | (1L << 2)); +} + +/* { dg-final { scan-assembler-times {\mlis\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mpaddi\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mpli\M} 2 } } */ +/* { dg-final { scan-assembler-times {\msldi\M} 3 } } */