aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVineet Gupta <vineetg@rivosinc.com>2023-05-09 16:22:08 -0700
committerVineet Gupta <vineetg@rivosinc.com>2023-05-19 10:18:58 -0700
commitc104ef4b5eb1f781bbef953e3c282ef1ca94c4f1 (patch)
tree800268e826c95063bad1c56b435b83d28eaddee8 /gcc
parentc5709fc87131bea0013cb67cf80bdea6e238c918 (diff)
downloadgcc-c104ef4b5eb1f781bbef953e3c282ef1ca94c4f1.zip
gcc-c104ef4b5eb1f781bbef953e3c282ef1ca94c4f1.tar.gz
gcc-c104ef4b5eb1f781bbef953e3c282ef1ca94c4f1.tar.bz2
RISC-V: improve codegen for large constants with same 32-bit lo and hi parts [2]
[part #2 of PR/109279] SPEC2017 deepsjeng uses large constants which currently generates less than ideal code. This fix improves codegen for large constants which have same low and hi parts: e.g. long long f(void) { return 0x0101010101010101ull; } Before li a5,0x1010000 addi a5,a5,0x101 mv a0,a5 slli a5,a5,32 add a0,a5,a0 ret With patch li a5,0x1010000 addi a5,a5,0x101 slli a0,a5,32 add a0,a0,a5 ret This is testsuite clean. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_split_integer): if loval is equal to hival, ASHIFT the corresponding regs. Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/riscv.cc13
1 files changed, 9 insertions, 4 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 8320069..2a7b438 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -703,13 +703,18 @@ riscv_split_integer (HOST_WIDE_INT val, machine_mode mode)
unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32);
rtx hi = gen_reg_rtx (mode), lo = gen_reg_rtx (mode);
- riscv_move_integer (hi, hi, hival, mode);
riscv_move_integer (lo, lo, loval, mode);
- hi = gen_rtx_fmt_ee (ASHIFT, mode, hi, GEN_INT (32));
- hi = force_reg (mode, hi);
+ if (loval == hival)
+ hi = gen_rtx_ASHIFT (mode, lo, GEN_INT (32));
+ else
+ {
+ riscv_move_integer (hi, hi, hival, mode);
+ hi = gen_rtx_ASHIFT (mode, hi, GEN_INT (32));
+ }
- return gen_rtx_fmt_ee (PLUS, mode, hi, lo);
+ hi = force_reg (mode, hi);
+ return gen_rtx_PLUS (mode, hi, lo);
}
/* Return true if X is a thread-local symbol. */