On 10/30/23 13:33, Jeff Law wrote:

+/* Helper function for riscv_extend_comparands to Sign-extend the OP.
+   However if the OP is SI subreg promoted with an inner DI, such as
+       (subreg/s/v:SI (reg/v:DI) 0
+   just peel off the SUBREG to get DI, avoiding extraneous extension.  */
+
+static void
+riscv_sign_extend_if_not_subreg_prom (rtx *op)
+{
+  if (GET_MODE (*op) == SImode

So I may have been partially wrong about v2 patch being wrong and needing this fixup ;-) [1]

It seems we don't have to limit this to SImode. I re-read the calling convention doc [2] and it says this

"When passed in registers or on the stack, integer scalars narrower than XLEN
 bits are widened according to the sign of their type up to 32 bits, then
 sign-extended to XLEN bits."

This essentially means signed short, and signed char will be already sign-extended at caller site and need not be done in callee: Palmer mention in internal slack that unadorned char is unsigned on RISC-V hence we don't see the compiler extra work for say gcc.dg/torture/pr75964.c. If the test is however tweaked to use signed chars (or short), it seems caller is doing the work (adjusting the constant being passed to be a sign-extended variant).

This further validates Jeff's comment about checking for SUBREG_PROMOTED_SIGNED_P (it was anyhow the right thing to begin with anyways).

At this point I feel like I'm into splitting hairs (in vain) territory, as fixing this might not matter much in practice ....

I'd suppose we go ahead with the v3 with changes Jeff asked for and maybe do a later fixup to relax SI.

+      && GET_CODE (*op) == SUBREG
+      && SUBREG_PROMOTED_VAR_P (*op)
+      && GET_MODE_SIZE (GET_MODE (XEXP (*op, 0))).to_constant ()
+     == GET_MODE_SIZE (word_mode))
+    *op = XEXP (*op, 0);
+  else
+    *op = gen_rtx_SIGN_EXTEND (word_mode, *op);
So for the wrapped test GET_MODE_SIZE stuff), add parenthesis and indent the "==" clause.  ie

  && (GET_MODE_SIZE (GET_MODE (XEXP (*op), 0))).to_constant ()
      == GET_MODE_SIZE (word_mode))

Don't you also need to verify that the subreg was sign extended? The PROMOTED_VAR_P just notes that it was promoted, not *how* it was promoted.  I think you just need to add a test like this:

  && SUBREG_PROMOTED_SIGNED_P (*op)

[1] https://gcc.gnu.org/pipermail/gcc-patches/2023-October/634327.html
[2] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc>


Reply via email to