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.
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 95951605fb4..84bce409bc7 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -4684,10 +4684,22 @@ (define_insn_and_split ""
"(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 @@ (define_insn_and_split ""
"(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 00000000000..2a490c90615
--- /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" } } */