diff mbox series

[to-be-committed] RISC-V Fix minor regression in synthesis WRT bseti usage

Message ID c0b5e6e8-1af4-4d65-9f0c-cfa5745d9764@ventanamicro.com
State New
Headers show
Series [to-be-committed] RISC-V Fix minor regression in synthesis WRT bseti usage | expand

Commit Message

Jeff Law May 12, 2024, 1:26 a.m. UTC
Overnight testing showed a small number of cases where constant 
synthesis was doing something dumb.  Specifically generating more 
instructions than the number of bits set in the constant.

It was a minor goof in the recent bseti code.  In the code to first 
figure out what bits LUI could set, I included one bit outside the space 
LUI operates.  For some dumb reason I kept thinking in terms of 11 low 
bits belonging to addi, but it's actually 12 bits.  The net is what we 
thought should be a single LUI for costing turned into LUI+ADDI.

I didn't let the test run to completion, but over the course of 12 hours 
it found 9 cases.  Given we know that the triggers all have 0x800 set, I 
bet we could likely find more, but I doubt it's that critical to cover 
every possible constant that regressed.

This has run in my tester (rv64gc, rv32gcv), but I'll wait for the CI 
tester as it covers the bitmanip extensions much better.


Jeff
diff mbox series

Patch

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 9c98b1da035..049f8f8cb9f 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -921,12 +921,12 @@  riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS],
 
       /* First handle any bits set by LUI.  Be careful of the
 	 SImode sign bit!.  */
-      if (value & 0x7ffff800)
+      if (value & 0x7ffff000)
 	{
 	  alt_codes[i].code = (i == 0 ? UNKNOWN : IOR);
-	  alt_codes[i].value = value & 0x7ffff800;
+	  alt_codes[i].value = value & 0x7ffff000;
 	  alt_codes[i].use_uw = false;
-	  value &= ~0x7ffff800;
+	  value &= ~0x7ffff000;
 	   i++;
 	}
 
diff --git a/gcc/testsuite/gcc.target/riscv/synthesis-4.c b/gcc/testsuite/gcc.target/riscv/synthesis-4.c
new file mode 100644
index 00000000000..328a55b9e6e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/synthesis-4.c
@@ -0,0 +1,34 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* We aggressively skip as we really just need to test the basic synthesis
+   which shouldn't vary based on the optimization level.  -O1 seems to work
+   and eliminates the usual sources of extraneous dead code that would throw
+   off the counts.  */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O2" "-O3" "-Os" "-Oz" "-flto" } } */
+/* { dg-options "-march=rv64gc_zba_zbb_zbs" } */
+
+/* Rather than test for a specific synthesis of all these constants or
+   having thousands of tests each testing one variant, we just test the
+   total number of instructions. 
+
+   This isn't expected to change much and any change is worthy of a look.  */
+/* { dg-final { scan-assembler-times "\\t(add|addi|bseti|li|ret|sh1add|sh2add|sh3add|slli)" 45 } } */
+
+
+unsigned long foo_0x60000400000800(void) { return 0x60000400000800UL; }
+
+unsigned long foo_0xc0000400000800(void) { return 0xc0000400000800UL; }
+
+unsigned long foo_0x180000400000800(void) { return 0x180000400000800UL; }
+
+unsigned long foo_0x300000400000800(void) { return 0x300000400000800UL; }
+
+unsigned long foo_0x600000400000800(void) { return 0x600000400000800UL; }
+
+unsigned long foo_0xc00000400000800(void) { return 0xc00000400000800UL; }
+
+unsigned long foo_0x1800000400000800(void) { return 0x1800000400000800UL; }
+
+unsigned long foo_0x3000000400000800(void) { return 0x3000000400000800UL; }
+
+unsigned long foo_0x6000000400000800(void) { return 0x6000000400000800UL; }