https://gcc.gnu.org/g:9d68a2a67351fc5b56262c0028ef8fd1d1466627
commit r15-8080-g9d68a2a67351fc5b56262c0028ef8fd1d1466627 Author: Jeff Law <j...@ventanamicro.com> Date: Sun Mar 16 17:43:48 2025 -0600 [RISC-V][PR target/116256][V4] Fix minor code quality regression in reassociated arithmetic Arggh. This time add arguments for rv32. Hand edited the testcase part of the patch, but I think I got it right. One. More. Time. -pedantic-errors this time ;( Adding an explicit -std=gnu23 to shut that up. Part of me wants to know why that's getting added by the pre-commit, but not enough to chase it down. -- This failed pre-commit CI the first time through. The only change is in the return type in the test bool -> _Bool. The patch for target/116256 significantly simplified the condition and, I guess not too surprisingly, exposed a minor code quality regression. Specifically the split part of the define_insn_and_split only splits after reload (because we use a match_scratch). So there's nothing to combine the load-immediate with the subsequent add into an addi when the immediate fits into a simm12 field. This patch adjusts the split code to handle that scenario directly and generate the more efficient code. We can squeeze out the slli in this test with a bit more work, but that's out of scope right now since that isn't a regression. Tested in my tester. Waiting on pre-commit testing to render a verdict. PR target/116256 gcc * config/riscv/riscv.md (reassociation splitters): Do not load the adjusted addend into a register if it fits in a simm12. gcc/testsuite * gcc.target/riscv/pr116256-1.c: New test. Diff: --- gcc/config/riscv/riscv.md | 39 +++++++++++++++++++++++------ gcc/testsuite/gcc.target/riscv/pr116256-1.c | 15 +++++++++++ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 95951605fb46..84bce409bc72 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -4684,10 +4684,22 @@ "(TARGET_64BIT && riscv_const_insns (operands[3], false) == 1)" "#" "&& reload_completed" - [(set (match_dup 0) (ashift:DI (match_dup 1) (match_dup 2))) - (set (match_dup 4) (match_dup 3)) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] - "" + [(const_int 0)] + "{ + rtx x = gen_rtx_ASHIFT (DImode, operands[1], operands[2]); + emit_insn (gen_rtx_SET (operands[0], x)); + + /* If the constant fits in a simm12, use it directly as we do not + get another good chance to optimize things again. */ + if (!SMALL_OPERAND (INTVAL (operands[3]))) + emit_move_insn (operands[4], operands[3]); + else + operands[4] = operands[3]; + + x = gen_rtx_PLUS (DImode, operands[0], operands[4]); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; + }" [(set_attr "type" "arith")]) (define_insn_and_split "" @@ -4700,13 +4712,26 @@ "(TARGET_64BIT && riscv_const_insns (operands[3], false) == 1)" "#" "&& reload_completed" - [(set (match_dup 0) (ashift:DI (match_dup 1) (match_dup 2))) - (set (match_dup 4) (match_dup 3)) - (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 6))))] + [(const_int 0)] "{ operands[1] = gen_lowpart (DImode, operands[1]); operands[5] = gen_lowpart (SImode, operands[0]); operands[6] = gen_lowpart (SImode, operands[4]); + + rtx x = gen_rtx_ASHIFT (DImode, operands[1], operands[2]); + emit_insn (gen_rtx_SET (operands[0], x)); + + /* If the constant fits in a simm12, use it directly as we do not + get another good chance to optimize things again. */ + if (!SMALL_OPERAND (INTVAL (operands[3]))) + emit_move_insn (operands[4], operands[3]); + else + operands[6] = operands[3]; + + x = gen_rtx_PLUS (SImode, operands[5], operands[6]); + x = gen_rtx_SIGN_EXTEND (DImode, x); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; }" [(set_attr "type" "arith")]) diff --git a/gcc/testsuite/gcc.target/riscv/pr116256-1.c b/gcc/testsuite/gcc.target/riscv/pr116256-1.c new file mode 100644 index 000000000000..46fd7f2b399c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr116256-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu23 -march=rv32gcb -mabi=ilp32" { target { rv32 } } } */ +/* { dg-options "-std=gnu23 -march=rv64gcb -mabi=lp64d" { target { rv64 } } } */ + + +_Bool f1(long a) +{ + long b = a << 4; + return b == -128; +} + +/* We want to verify that we have generated addi + rather than li+add. */ +/* { dg-final { scan-assembler-not "add\t" } } */ +/* { dg-final { scan-assembler "addi\t" } } */