From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out30-132.freemail.mail.aliyun.com (out30-132.freemail.mail.aliyun.com [115.124.30.132]) by sourceware.org (Postfix) with ESMTPS id 067D13858D1E for ; Thu, 10 Nov 2022 14:37:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 067D13858D1E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linux.alibaba.com X-Alimail-AntiSpam:AC=PASS;BC=-1|-1;BR=01201311R491e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046050;MF=sinan.lin@linux.alibaba.com;NM=1;PH=DS;RN=5;SR=0;TI=SMTPD_---0VUTN49A_1668091050; Received: from localhost(mailfrom:sinan.lin@linux.alibaba.com fp:SMTPD_---0VUTN49A_1668091050) by smtp.aliyun-inc.com; Thu, 10 Nov 2022 22:37:35 +0800 From: Lin Sinan To: gcc-patches@gcc.gnu.org Cc: palmer@dabbelt.com, kito.cheng@gmail.com, andrew@sifive.com, Lin Sinan Subject: [PATCH RESEND] riscv: improve the cost model for loading a 64bit constant in rv32. Date: Thu, 10 Nov 2022 22:37:13 +0800 Message-Id: <6787a2d509d2b8ef27083d3b9806661eb8f56102.1668090837.git.sinan.lin@linux.alibaba.com> X-Mailer: git-send-email 2.36.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-18.7 required=5.0 tests=BAYES_00,ENV_AND_HDR_SPF_MATCH,GIT_PATCH_0,KAM_DMARC_STATUS,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS,TXREP,UNPARSEABLE_RELAY,USER_IN_DEF_SPF_WL 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: The motivation of this patch is to correct the wrong estimation of the number of instructions needed for loading a 64bit constant in rv32 in the current cost model(riscv_interger_cost). According to the current implementation, if a constant requires more than 3 instructions(riscv_const_insn and riscv_legitimate_constant_p), then the constant will be put into constant pool when expanding gimple to rtl(legitimate_constant_p hook and emit_move_insn). So the inaccurate cost model leads to the suboptimal codegen in rv32 and the wrong estimation part could be corrected through this fix. e.g. the current codegen for loading 0x839290001 in rv32 lui a5,%hi(.LC0) lw a0,%lo(.LC0)(a5) lw a1,%lo(.LC0+4)(a5) .LC0: .word 958988289 .word 8 output after this patch li a0,958988288 addi a0,a0,1 li a1,8 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_build_integer): Handle the case of loading 64bit constant in rv32. gcc/testsuite/ChangeLog: * gcc.target/riscv/rv32-load-64bit-constant.c: New test. Signed-off-by: Lin Sinan --- gcc/config/riscv/riscv.cc | 23 +++++++++++ .../riscv/rv32-load-64bit-constant.c | 38 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 32f9ef9ade9..9dffabdc5e3 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -618,6 +618,29 @@ riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value, } } + if ((value > INT32_MAX || value < INT32_MIN) && !TARGET_64BIT) + { + unsigned HOST_WIDE_INT loval = sext_hwi (value, 32); + unsigned HOST_WIDE_INT hival = sext_hwi ((value - loval) >> 32, 32); + struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS], + hicode[RISCV_MAX_INTEGER_OPS]; + int hi_cost, lo_cost; + + hi_cost = riscv_build_integer_1 (hicode, hival, mode); + if (hi_cost < cost) + { + lo_cost = riscv_build_integer_1 (alt_codes, loval, mode); + if (lo_cost + hi_cost < cost) + { + memcpy (codes, alt_codes, + lo_cost * sizeof (struct riscv_integer_op)); + memcpy (codes + lo_cost, hicode, + hi_cost * sizeof (struct riscv_integer_op)); + cost = lo_cost + hi_cost; + } + } + } + return cost; } diff --git a/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c b/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c new file mode 100644 index 00000000000..61d482fb283 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32im -mabi=ilp32 -O1" } */ + +/* This test only applies to RV32. Some of 64bit constants in this test will be put +into the constant pool in RV64, since RV64 might need one extra instruction to load +64bit constant. */ + +unsigned long long +rv32_mov_64bit_int1 (void) +{ + return 0x739290001LL; +} + +unsigned long long +rv32_mov_64bit_int2 (void) +{ + return 0x839290001LL; +} + +unsigned long long +rv32_mov_64bit_int3 (void) +{ + return 0x3929000139290000LL; +} + +unsigned long long +rv32_mov_64bit_int4 (void) +{ + return 0x3929001139290000LL; +} + +unsigned long long +rv32_mov_64bit_int5 (void) +{ + return 0x14736def39290000LL; +} + +/* { dg-final { scan-assembler-not "lw\t" } } */ -- 2.36.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out30-42.freemail.mail.aliyun.com (out30-42.freemail.mail.aliyun.com [115.124.30.42]) by sourceware.org (Postfix) with ESMTPS id D33E1383236C for ; Thu, 17 Nov 2022 07:32:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D33E1383236C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linux.alibaba.com X-Alimail-AntiSpam:AC=PASS;BC=-1|-1;BR=01201311R261e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046056;MF=sinan.lin@linux.alibaba.com;NM=1;PH=DS;RN=6;SR=0;TI=SMTPD_---0VV-zsHY_1668670339; Received: from localhost(mailfrom:sinan.lin@linux.alibaba.com fp:SMTPD_---0VV-zsHY_1668670339) by smtp.aliyun-inc.com; Thu, 17 Nov 2022 15:32:24 +0800 From: Lin Sinan To: mynameisxiaou@gmail.com, gcc-patches@gcc.gnu.org Cc: kito.cheng@gmail.com, palmer@dabbelt.com, andrew@sifive.com, Lin Sinan Subject: [PING] [PATCH RESEND] riscv: improve the cost model for loading a 64bit constant in rv32. Date: Thu, 17 Nov 2022 15:32:16 +0800 Message-ID: <6787a2d509d2b8ef27083d3b9806661eb8f56102.1668090837.git.sinan.lin@linux.alibaba.com> X-Mailer: git-send-email 2.36.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-19.1 required=5.0 tests=BAYES_00,ENV_AND_HDR_SPF_MATCH,GIT_PATCH_0,KAM_DMARC_STATUS,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS,TXREP,UNPARSEABLE_RELAY,USER_IN_DEF_SPF_WL 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: Message-ID: <20221117073216.9RSoFwMholgCWg5q8DXdsZihK8UTKVqfm7EUBgQN_sk@z> The motivation of this patch is to correct the wrong estimation of the number of instructions needed for loading a 64bit constant in rv32 in the current cost model(riscv_interger_cost). According to the current implementation, if a constant requires more than 3 instructions(riscv_const_insn and riscv_legitimate_constant_p), then the constant will be put into constant pool when expanding gimple to rtl(legitimate_constant_p hook and emit_move_insn). So the inaccurate cost model leads to the suboptimal codegen in rv32 and the wrong estimation part could be corrected through this fix. e.g. the current codegen for loading 0x839290001 in rv32 lui a5,%hi(.LC0) lw a0,%lo(.LC0)(a5) lw a1,%lo(.LC0+4)(a5) .LC0: .word 958988289 .word 8 output after this patch li a0,958988288 addi a0,a0,1 li a1,8 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_build_integer): Handle the case of loading 64bit constant in rv32. gcc/testsuite/ChangeLog: * gcc.target/riscv/rv32-load-64bit-constant.c: New test. Signed-off-by: Lin Sinan --- gcc/config/riscv/riscv.cc | 23 +++++++++++ .../riscv/rv32-load-64bit-constant.c | 38 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 32f9ef9ade9..9dffabdc5e3 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -618,6 +618,29 @@ riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value, } } + if ((value > INT32_MAX || value < INT32_MIN) && !TARGET_64BIT) + { + unsigned HOST_WIDE_INT loval = sext_hwi (value, 32); + unsigned HOST_WIDE_INT hival = sext_hwi ((value - loval) >> 32, 32); + struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS], + hicode[RISCV_MAX_INTEGER_OPS]; + int hi_cost, lo_cost; + + hi_cost = riscv_build_integer_1 (hicode, hival, mode); + if (hi_cost < cost) + { + lo_cost = riscv_build_integer_1 (alt_codes, loval, mode); + if (lo_cost + hi_cost < cost) + { + memcpy (codes, alt_codes, + lo_cost * sizeof (struct riscv_integer_op)); + memcpy (codes + lo_cost, hicode, + hi_cost * sizeof (struct riscv_integer_op)); + cost = lo_cost + hi_cost; + } + } + } + return cost; } diff --git a/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c b/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c new file mode 100644 index 00000000000..61d482fb283 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32im -mabi=ilp32 -O1" } */ + +/* This test only applies to RV32. Some of 64bit constants in this test will be put +into the constant pool in RV64, since RV64 might need one extra instruction to load +64bit constant. */ + +unsigned long long +rv32_mov_64bit_int1 (void) +{ + return 0x739290001LL; +} + +unsigned long long +rv32_mov_64bit_int2 (void) +{ + return 0x839290001LL; +} + +unsigned long long +rv32_mov_64bit_int3 (void) +{ + return 0x3929000139290000LL; +} + +unsigned long long +rv32_mov_64bit_int4 (void) +{ + return 0x3929001139290000LL; +} + +unsigned long long +rv32_mov_64bit_int5 (void) +{ + return 0x14736def39290000LL; +} + +/* { dg-final { scan-assembler-not "lw\t" } } */ -- 2.36.0