aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/riscv
diff options
context:
space:
mode:
authorJeff Law <jlaw@ventanamicro.com>2025-01-13 07:29:39 -0700
committerJeff Law <jlaw@ventanamicro.com>2025-01-13 07:29:39 -0700
commitd23d338da4d2bd581b2d3fd97785dd2c26053a92 (patch)
tree896af3464bd4036b9f25de03628b4b0d7292492f /gcc/testsuite/gcc.target/riscv
parent52e4ede030979d8aff2f88364e1d11c61fb212aa (diff)
downloadgcc-d23d338da4d2bd581b2d3fd97785dd2c26053a92.zip
gcc-d23d338da4d2bd581b2d3fd97785dd2c26053a92.tar.gz
gcc-d23d338da4d2bd581b2d3fd97785dd2c26053a92.tar.bz2
[PR rtl-optimization/107455] Eliminate unnecessary constant load
This resurrects a patch from a bit over 2 years ago that I never wrapped up. IIRC, I ended up up catching covid, then in the hospital for an unrelated issue and it just got dropped on the floor in the insanity. The basic idea here is to help postreload-cse eliminate more const/copies by recording a small set of conditional equivalences (as Richi said in 2022, "Ick"). It was originally to help eliminate an unnecessary constant load I saw in coremark, but as seen in BZ107455 the same issues show up in real code as well. Bootstrapped and regression tested on x86-64, also been through multiple spins in my tester. Changes since v2: - Simplified logic for blocks to examine - Remove redundant tests when filtering blocks to examine - Remove bogus check which only allowed reg->reg copies Changes since v1: Richard B and Richard S both had good comments last time around and their requests are reflected in this update: - Use rtx_equal_p rather than pointer equality - Restrict to register "destinations" - Restrict to integer modes - Adjust entry block handling My own wider scale testing resulted in a few more changes. - Robustify extracting the (set (pc) ... ), which then required ... - Handle if src/dst are clobbered by the conditional branch - Fix logic error causing too many equivalences to be recorded PR rtl-optimization/107455 gcc/ * postreload.cc (reload_cse_regs_1): Take advantage of conditional equivalences. gcc/testsuite * gcc.target/riscv/pr107455-1.c: New test. * gcc.target/riscv/pr107455-2.c: New test.
Diffstat (limited to 'gcc/testsuite/gcc.target/riscv')
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr107455-1.c46
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr107455-2.c40
2 files changed, 86 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/riscv/pr107455-1.c b/gcc/testsuite/gcc.target/riscv/pr107455-1.c
new file mode 100644
index 0000000..59616b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr107455-1.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-dp" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O2" "-O3" "-Og" } } */
+
+
+typedef struct dllist
+{
+ int i;
+ struct dllist *ptr_to_next;
+ struct dllist *ptr_to_previous;
+} dllist;
+
+int sglib_dllist_len(dllist *list) {
+ int res;
+ dllist *_dl_;
+ int _r1_, _r2_;
+ if (list== ((void *)0)) {
+ res = 0;
+ } else {
+ dllist *_ce_;
+ dllist *_ne_;
+ _r1_ = 0;
+ _ce_ = list;
+ while (_ce_!= ((void *)0)) {
+ _ne_ = _ce_->ptr_to_previous;
+ _r1_++;
+ _ce_ = _ne_;
+ }
+ _dl_ = list->ptr_to_next;
+ _r2_ = 0;
+ _ce_ = _dl_;
+ while (_ce_!= (void *)0) {
+ _ne_ = _ce_->ptr_to_next;
+ _r2_++;
+ _ce_ = _ne_;
+ }
+ res = _r1_ + _r2_;
+ }
+ return res;
+}
+
+
+/* There was an unnecessary assignment to the return value until
+ recently. Scan for that in the resulting output. */
+/* { dg-final { scan-assembler-times "li\\ta0,0" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/pr107455-2.c b/gcc/testsuite/gcc.target/riscv/pr107455-2.c
new file mode 100644
index 0000000..91106bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr107455-2.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -dp" } */
+/* This was extracted from coremark. */
+
+
+typedef signed short ee_s16;
+typedef struct list_data_s
+{
+ ee_s16 data16;
+ ee_s16 idx;
+} list_data;
+
+typedef struct list_head_s
+{
+ struct list_head_s *next;
+ struct list_data_s *info;
+} list_head;
+
+
+list_head *
+core_list_find(list_head *list, list_data *info)
+{
+ if (info->idx >= 0)
+ {
+ while (list && (list->info->idx != info->idx))
+ list = list->next;
+ return list;
+ }
+ else
+ {
+ while (list && ((list->info->data16 & 0xff) != info->data16))
+ list = list->next;
+ return list;
+ }
+}
+
+/* There was an unnecessary assignment to the return value until
+ recently. Scan for that in the resulting output. */
+/* { dg-final { scan-assembler-not "li\\ta0,0" } } */
+