diff options
author | Jeff Law <jlaw@ventanamicro.com> | 2025-01-13 07:29:39 -0700 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro.com> | 2025-01-13 07:29:39 -0700 |
commit | d23d338da4d2bd581b2d3fd97785dd2c26053a92 (patch) | |
tree | 896af3464bd4036b9f25de03628b4b0d7292492f /gcc/testsuite/gcc.target/riscv | |
parent | 52e4ede030979d8aff2f88364e1d11c61fb212aa (diff) | |
download | gcc-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.c | 46 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/pr107455-2.c | 40 |
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" } } */ + |