Hi Jakub, On Tue, 26 Apr 2022, Jakub Jelinek via Gcc-patches wrote:
> The following testcase regressed on riscv due to the splitting of critical > edges in the sink pass, similarly to x86_64 compared to GCC 11 we now swap > the edges, whether true or false edge goes to an empty forwarded bb. > >From GIMPLE POV, those 2 forms are equivalent, but as can be seen here, for > some ifcvt opts it matters one way or another. [...] > --- gcc/testsuite/gcc.target/riscv/pr105314.c.jj 2022-04-25 > 17:41:00.958736306 +0200 > +++ gcc/testsuite/gcc.target/riscv/pr105314.c 2022-04-25 17:40:46.237940642 > +0200 > @@ -0,0 +1,12 @@ > +/* PR rtl-optimization/105314 */ > +/* { dg-do compile } * > +/* { dg-options "-O2" } */ > +/* { dg-final { scan-assembler-not "\tbeq\t" } } */ > + > +long > +foo (long a, long b, long c) > +{ > + if (c) > + a = 0; > + return a; > +} It's not clear to me why we insist that a branch is to be unconditionally avoided here. I think it has to be microarchitecture-specific and based on my observations a branch will or will not be used depending on what the specific microarchitecture sets the branch cost to (via BRANCH_COST), e.g. if the cost is set to 1 (which none of our current microarchitectures do), then a branch is preferred to a three-instruction fall-through sequence, i.e.: foo: beq a2,zero,.L1 li a0,0 .L1: ret vs: foo: seqz a2,a2 neg a2,a2 and a0,a0,a2 ret Also with `-mtune=sifive-7-series' code produced here is already as follows: foo: beq a2,zero,1f; mv a0,zero; 1: # movcc ret and it only passes the test case due to sloppy coding in the machine description (which I'll post a fix for separately and which will obviously uncover the failure expected here) combined with the test's strictness about using tabs for white space. Therefore shouldn't the case be somehow restricted to a subset of RISC-V microarchitectures, ones we know that do not want to see a branch here? Maciej