diff options
| author | Shreya Munnangi <smunnangi1@ventanamicro.com> | 2025-11-02 19:21:53 -0700 |
|---|---|---|
| committer | Jeff Law <jlaw@ventanamicro.com> | 2025-11-02 19:22:20 -0700 |
| commit | 22b3de712f796281d6592a6650c2992d3324c049 (patch) | |
| tree | ce6bde0a59e7b8b4ecc6917a00d1f7570834a713 /gcc/testsuite/rust/compile/issue-3556.rs | |
| parent | c2013267642fea4a6e89b826940c8aa80a76089d (diff) | |
| download | gcc-master.zip gcc-master.tar.gz gcc-master.tar.bz2 | |
This is Shreya's work, my contribution was primarily covering the testing.
Bootstrapped and regression tested on x86 and riscv64. It's also been tested
on all the embedded targets in my tester without regression.
While this improves code generation to optimal on riscv-64, I'm electing to
keep the BZ open because we probably should have the same kind of
simplification in match.pd. Shreya is just starting to write some match.pd
patterns and I expect we'll return to write a match.pd pattern for this issue
relatively soon.
Obviously waiting for pre-commit CI to chime in before moving forward.
Jeff
--
In PR52345, we have this testcase:
int f(int a, int b)
{
int c = a != 0;
int d = (c!=0|b!=0);
return d;
}
Basically, "d" will either be 0 or 1. Depending on "a", "c" will also
either be 0 or 1. So if "a" is 0 and "b" is 0, then "d" will also be 0. Otherwise, it will be 1.
When the testcase is compiled, we get this generated assembly code:
snez a0,a0
or a0,a1,a0
snez a0,a0
RISC-V has a missed optimization here, as this can simply be done by first
computing a|b and checking if the result is equal to 0. If "a" is 0 and "b" is
0, we will get 0. Otherwise, we will get 1. Doing this removes the unnecessary
first snez instruction.
When we looked at the combine pass, it was trying:
Failed to match this instruction:
(set (reg/i:DI 10 a0)
(ne:DI (ior:DI (ne:DI (reg:DI 151 [ a ])
(const_int 0 [0]))
(reg:DI 152 [ b ]))
(const_int 0 [0])))
In simplify_relational_operation_1 of simplify-rtx.cc, we added a condition.
For cases where the outer code is a "not equal to" (NE) and the operands match
the pattern above, we simply emit an NE of an IOR of the two registers, giving
us:
or a0,a0,a1
snez a0,a0
We then generalized this to include the case where the outer code is an "equal
to" (EQ). With the logic working in the same way, we simply adjust the
recognition code to check that the outer code is either an NE or EQ and
generalize the NE we emit to match the outer code.
--
PR target/52345
gcc/
* simplify-rtx.cc (simplify_relational_operation_1): Optimize boolean
IOR equality tests.
gcc/testsuite/
* gcc.target/riscv/pr52345.c: Add new test cases.
Diffstat (limited to 'gcc/testsuite/rust/compile/issue-3556.rs')
0 files changed, 0 insertions, 0 deletions
