]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: improve codegen for large constants with same 32-bit lo and hi parts [2]
authorVineet Gupta <vineetg@rivosinc.com>
Tue, 9 May 2023 23:22:08 +0000 (16:22 -0700)
committerVineet Gupta <vineetg@rivosinc.com>
Fri, 19 May 2023 17:18:58 +0000 (10:18 -0700)
[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>
gcc/config/riscv/riscv.cc

index 8320069f92f8f42560c7e7a692690e20d4490e75..2a7b43849e5205fbbb81db81230372175d16bdfe 100644 (file)
@@ -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.  */