aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <jlaw@ventanamicro.com>2024-07-12 07:53:41 -0600
committerJeff Law <jlaw@ventanamicro.com>2024-07-12 07:53:41 -0600
commitae829a27785307232e4db0df6a30ca275941b613 (patch)
tree8e51a57679497189f49ec22a895e0993864ef78c
parent13757e50ff0b4e0dccfabc67b1322a2724bf3a5c (diff)
downloadgcc-ae829a27785307232e4db0df6a30ca275941b613.zip
gcc-ae829a27785307232e4db0df6a30ca275941b613.tar.gz
gcc-ae829a27785307232e4db0df6a30ca275941b613.tar.bz2
[RISC-V] Avoid unnecessary sign extension after memcmp
Similar to the str[n]cmp work, this adjusts the block compare expansion to do its work in X mode with an appropriate lowpart extraction of the results at the end of the sequence. This has gone through my tester on rv32 and rv64, but that's it. Waiting on pre-commit testing before moving forward. gcc/ * config/riscv/riscv-string.cc (emit_memcmp_scalar_load_and_compare): Set RESULT directly rather than using a temporary. (emit_memcmp_scalar_result_calculation): Similarly. (riscv_expand_block_compare_scalar): Use CONST0_RTX rather than generating new RTL. * config/riscv/riscv.md (cmpmemsi): Pass an X mode temporary to the expansion routines. If necessary extract low part of the word to store in final result location.
-rw-r--r--gcc/config/riscv/riscv-string.cc15
-rw-r--r--gcc/config/riscv/riscv.md14
2 files changed, 18 insertions, 11 deletions
diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
index 4736228..80d22e8 100644
--- a/gcc/config/riscv/riscv-string.cc
+++ b/gcc/config/riscv/riscv-string.cc
@@ -663,9 +663,7 @@ emit_memcmp_scalar_load_and_compare (rtx result, rtx src1, rtx src2,
/* Fast-path for a single byte. */
if (cmp_bytes == 1)
{
- rtx tmp = gen_reg_rtx (Xmode);
- do_sub3 (tmp, data1, data2);
- emit_insn (gen_movsi (result, gen_lowpart (SImode, tmp)));
+ do_sub3 (result, data1, data2);
emit_jump_insn (gen_jump (final_label));
emit_barrier (); /* No fall-through. */
return;
@@ -702,12 +700,11 @@ emit_memcmp_scalar_result_calculation (rtx result, rtx data1, rtx data2)
/* Get bytes in big-endian order and compare as words. */
do_bswap2 (data1, data1);
do_bswap2 (data2, data2);
+
/* Synthesize (data1 >= data2) ? 1 : -1 in a branchless sequence. */
- rtx tmp = gen_reg_rtx (Xmode);
- emit_insn (gen_slt_3 (LTU, Xmode, Xmode, tmp, data1, data2));
- do_neg2 (tmp, tmp);
- do_ior3 (tmp, tmp, const1_rtx);
- emit_insn (gen_movsi (result, gen_lowpart (SImode, tmp)));
+ emit_insn (gen_slt_3 (LTU, Xmode, Xmode, result, data1, data2));
+ do_neg2 (result, result);
+ do_ior3 (result, result, const1_rtx);
}
/* Expand memcmp using scalar instructions (incl. Zbb).
@@ -773,7 +770,7 @@ riscv_expand_block_compare_scalar (rtx result, rtx src1, rtx src2, rtx nbytes)
data1, data2,
diff_label, final_label);
- emit_insn (gen_rtx_SET (result, gen_rtx_CONST_INT (SImode, 0)));
+ emit_move_insn (result, CONST0_RTX (GET_MODE (result)));
emit_jump_insn (gen_jump (final_label));
emit_barrier (); /* No fall-through. */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 2e2379d..5dee837 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2675,9 +2675,19 @@
operands[2], operands[3]))
DONE;
- if (riscv_expand_block_compare (operands[0], operands[1], operands[2],
+ rtx temp = gen_reg_rtx (word_mode);
+ if (riscv_expand_block_compare (temp, operands[1], operands[2],
operands[3]))
- DONE;
+ {
+ if (TARGET_64BIT)
+ {
+ temp = gen_lowpart (SImode, temp);
+ SUBREG_PROMOTED_VAR_P (temp) = 1;
+ SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
+ }
+ emit_move_insn (operands[0], temp);
+ DONE;
+ }
else
FAIL;
})