diff mbox series

[to-be-committed,RISC-V] Avoid unnecessary sign extension after memcmp

Message ID 2fcf8ec4-a55d-47ce-b8da-2d9453519781@gmail.com
State New
Headers show
Series [to-be-committed,RISC-V] Avoid unnecessary sign extension after memcmp | expand

Commit Message

Jeff Law July 11, 2024, 6:13 p.m. UTC
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.

Jeff
* 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.
diff mbox series

Patch

diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
index 4736228e6f1..80d22e87d57 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 2e2379dfca4..5dee837a587 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2675,9 +2675,19 @@  (define_expand "cmpmemsi"
 				       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;
 })