From: Aurelien Jarno <aurelien@aurel32.net>
To: "Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>
Cc: qemu-devel@nongnu.org, qemu-riscv@nongnu.org,
Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>,
Richard Henderson <richard.henderson@linaro.org>,
Alistair Francis <Alistair.Francis@wdc.com>,
Peter Maydell <peter.maydell@linaro.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
qemu-arm@nongnu.org, qemu-stable@nongnu.org
Subject: Re: [PATCH v3 5/6] tcg/riscv64: Fix logical vector immediate matching and emission
Date: Thu, 29 Oct 2026 19:33:28 +0100 [thread overview]
Message-ID: <auOReLXT3EK7ITyf@aurel32.net> (raw)
In-Reply-To: <20261028143330.6518-6-philmd@oss.qualcomm.com>
On 2026-10-28 15:33, Philippe Mathieu-Daudé wrote:
> and/or/xor_vec always have VECE 0, yet their constant was matched
> as a byte element and applied at the stale SEW of the previous op:
> "bic v4.8h, #0xf0" became "vand.vi ..., 15".
>
> Add the 'N' constraint: use the smallest element size at which the
> constant replicates, if that element fits simm5, and switch SEW to
> it. A wider element can't fit when the smallest doesn't: its upper
> half repeats the smaller element, which would then be 0 or -1.
>
> Cc: qemu-stable@nongnu.org
> Fixes: 5a63f5998791 ("tcg/riscv: Add support for basic vector opcodes")
> Reported-by: Aurelien Jarno <aurelien@aurel32.net>
> Suggested-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> ---
> tcg/riscv64/tcg-target-con-set.h | 1 +
> tcg/riscv64/tcg-target-con-str.h | 1 +
> tcg/riscv64/tcg-target.c.inc | 53 +++++++++++++++++++++++++++-----
> 3 files changed, 48 insertions(+), 7 deletions(-)
>
> diff --git a/tcg/riscv64/tcg-target-con-set.h b/tcg/riscv64/tcg-target-con-set.h
> index 0fc26d3f98b4..9b4e219fac16 100644
> --- a/tcg/riscv64/tcg-target-con-set.h
> +++ b/tcg/riscv64/tcg-target-con-set.h
> @@ -26,4 +26,5 @@ C_O1_I2(v, v, v)
> C_O1_I2(v, vK, v)
> C_O1_I2(v, v, vK)
> C_O1_I2(v, v, vL)
> +C_O1_I2(v, v, vN)
> C_O1_I4(v, v, vL, vK, vK)
> diff --git a/tcg/riscv64/tcg-target-con-str.h b/tcg/riscv64/tcg-target-con-str.h
> index c04e15ddfa3c..d7e8b2ce4f2f 100644
> --- a/tcg/riscv64/tcg-target-con-str.h
> +++ b/tcg/riscv64/tcg-target-con-str.h
> @@ -19,3 +19,4 @@ CONST('I', TCG_CT_CONST_S12)
> CONST('K', TCG_CT_CONST_S5)
> CONST('L', TCG_CT_CONST_CMP_VI)
> CONST('M', TCG_CT_CONST_M12)
> +CONST('N', TCG_CT_CONST_LOGICAL_VI)
> diff --git a/tcg/riscv64/tcg-target.c.inc b/tcg/riscv64/tcg-target.c.inc
> index 168932711796..4faf7ff36e07 100644
> --- a/tcg/riscv64/tcg-target.c.inc
> +++ b/tcg/riscv64/tcg-target.c.inc
> @@ -116,6 +116,7 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
> #define TCG_CT_CONST_M12 0x200
> #define TCG_CT_CONST_S5 0x400
> #define TCG_CT_CONST_CMP_VI 0x800
> +#define TCG_CT_CONST_LOGICAL_VI 0x1000
>
> #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
> #define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
> @@ -384,6 +385,22 @@ static const struct {
> [TCG_COND_GEU] = { OPC_VMSGTU_VI, 1, 16, true },
> };
>
> +/*
> + * Return the element size at which VAL is a replicated simm5,
> + * or -1 if there is none. Used for vector logical ops, whose
> + * VECE is not meaningful.
> + */
> +static int vec_logical_immediate_vece(int64_t val)
> +{
> + for (int e = MO_8; e <= MO_64; e++) {
> + if (val == dup_const(e, val)) {
> + int64_t x = sextract64(val, 0, 8 << e);
> + return x >= -0x10 && x <= 0x0f ? e : -1;
> + }
> + }
> + g_assert_not_reached();
> +}
> +
> /* test if a constant matches the constraint */
> static bool tcg_target_const_match(int64_t val, int ct,
> TCGType type, TCGCond cond, int vece)
> @@ -391,6 +408,10 @@ static bool tcg_target_const_match(int64_t val, int ct,
> if (ct & TCG_CT_CONST) {
> return 1;
> }
> + if ((ct & TCG_CT_CONST_LOGICAL_VI) &&
> + vec_logical_immediate_vece(val) >= 0) {
> + return true;
> + }
> if (type >= TCG_TYPE_V64) {
> /* Val is replicated by VECE; extract the highest element. */
> val >>= (-8 << vece) & 63;
> @@ -2769,6 +2790,23 @@ static const TCGOutOpStore outop_st = {
> };
>
>
> +static void tcg_out_opc_vv_vi_logical(TCGContext *s, TCGType type,
> + RISCVInsn o_vv, RISCVInsn o_vi,
> + TCGReg vd, TCGReg vs2,
> + TCGArg vi1, int c_vi1)
> +{
> + if (c_vi1) {
> + int vece = vec_logical_immediate_vece(vi1);
> +
> + tcg_debug_assert(vece >= 0);
> + set_vtype_len_sew(s, type, vece);
> + tcg_out_opc_vi(s, o_vi, vd, vs2, vec_imm(vi1, vece));
> + } else {
> + set_vtype_len(s, type);
> + tcg_out_opc_vv(s, o_vv, vd, vs2, vi1);
> + }
> +}
> +
> static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
> unsigned vecl, unsigned vece,
> const TCGArg args[TCG_MAX_OP_ARGS],
> @@ -2807,16 +2845,16 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
> }
> break;
> case INDEX_op_and_vec:
> - set_vtype_len(s, type);
> - tcg_out_opc_vv_vi(s, OPC_VAND_VV, OPC_VAND_VI, a0, a1, a2, c2);
> + tcg_out_opc_vv_vi_logical(s, type, OPC_VAND_VV, OPC_VAND_VI,
> + a0, a1, a2, c2);
> break;
> case INDEX_op_or_vec:
> - set_vtype_len(s, type);
> - tcg_out_opc_vv_vi(s, OPC_VOR_VV, OPC_VOR_VI, a0, a1, a2, c2);
> + tcg_out_opc_vv_vi_logical(s, type, OPC_VOR_VV, OPC_VOR_VI,
> + a0, a1, a2, c2);
> break;
> case INDEX_op_xor_vec:
> - set_vtype_len(s, type);
> - tcg_out_opc_vv_vi(s, OPC_VXOR_VV, OPC_VXOR_VI, a0, a1, a2, c2);
> + tcg_out_opc_vv_vi_logical(s, type, OPC_VXOR_VV, OPC_VXOR_VI,
> + a0, a1, a2, c2);
> break;
> case INDEX_op_not_vec:
> set_vtype_len(s, type);
> @@ -3008,10 +3046,11 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
> case INDEX_op_sari_vec:
> case INDEX_op_rotli_vec:
> return C_O1_I1(v, v);
> - case INDEX_op_add_vec:
> case INDEX_op_and_vec:
> case INDEX_op_or_vec:
> case INDEX_op_xor_vec:
> + return C_O1_I2(v, v, vN);
> + case INDEX_op_add_vec:
> case INDEX_op_ssadd_vec:
> case INDEX_op_sssub_vec:
> case INDEX_op_usadd_vec:
I am still wondering why not propagating VECE for logical ops at the TCG
level, instead of recomputing it at the TCG target level. But this is
how TCG is currently designed, so:
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://aurel32.net
next prev parent reply other threads:[~2026-10-29 18:34 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 14:33 [PATCH v3 0/6] tcg/riscv64: Fix vector immediate handling Philippe Mathieu-Daudé
2026-10-28 14:33 ` [PATCH v3 1/6] tcg/riscv64: Factor encode_vi_raw() out of encode_vi() Philippe Mathieu-Daudé
2026-10-29 12:16 ` Richard Henderson
2026-10-29 18:18 ` Aurelien Jarno
2026-10-28 14:33 ` [PATCH v3 2/6] tcg/riscv64: Use a uimm5 encoder for vector shift immediates Philippe Mathieu-Daudé
2026-10-29 12:16 ` Richard Henderson
2026-10-29 18:18 ` Aurelien Jarno
2026-10-28 14:33 ` [PATCH v3 3/6] tcg/riscv64: Extract elements for vector arithmetic immediates Philippe Mathieu-Daudé
2026-10-29 12:17 ` Richard Henderson
2026-10-29 18:18 ` Aurelien Jarno
2026-10-28 14:33 ` [PATCH v3 4/6] tcg/riscv64: Fix constant handling in vector comparisons and selects Philippe Mathieu-Daudé
2026-10-29 12:17 ` Richard Henderson
2026-10-29 18:31 ` Aurelien Jarno
2026-10-28 14:33 ` [PATCH v3 5/6] tcg/riscv64: Fix logical vector immediate matching and emission Philippe Mathieu-Daudé
2026-10-29 12:20 ` Richard Henderson
2026-10-29 14:12 ` Richard Henderson
2026-10-29 18:33 ` Aurelien Jarno [this message]
2026-10-28 14:33 ` [PATCH v3 6/6] tests/tcg/aarch64: Add vector immediate regression tests Philippe Mathieu-Daudé
2026-10-29 12:22 ` Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=auOReLXT3EK7ITyf@aurel32.net \
--to=aurelien@aurel32.net \
--cc=Alistair.Francis@wdc.com \
--cc=daniel.barboza@oss.qualcomm.com \
--cc=palmer@dabbelt.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@oss.qualcomm.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=qemu-stable@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.