From: Eric Botcazou Date: Tue, 6 Jan 2026 14:18:34 +0000 (+0100) Subject: Fix gcc.c-torture/execute/pr110817-[13].c on the SPARC X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=434c587537bc381ce0ba64289cf081543d38ce8a;p=thirdparty%2Fgcc.git Fix gcc.c-torture/execute/pr110817-[13].c on the SPARC As discussed in the audit trail, the TARGET_VECTORIZE_GET_MASK_MODE hook of the SPARC back-end always returns Pmode (SImode would probably have been OK) and this causes build_truth_vector_type_for_mode to generate questionable types like: unit-size align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff6f6d9d8 precision:1 min max > DI size constant 64> unit-size constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff6f6da80 nunits:1> which then go through this trick in store_constructor: /* Use sign-extension for uniform boolean vectors with integer modes and single-bit mask entries. Effectively "vec_duplicate" for bitmasks. */ if (elt_size == 1 && !TREE_SIDE_EFFECTS (exp) && VECTOR_BOOLEAN_TYPE_P (type) && SCALAR_INT_MODE_P (TYPE_MODE (type)) && (elt = uniform_vector_p (exp)) && !VECTOR_TYPE_P (TREE_TYPE (elt))) { rtx op0 = force_reg (TYPE_MODE (TREE_TYPE (elt)), expand_normal (elt)); rtx tmp = gen_reg_rtx (mode); convert_move (tmp, op0, 0); /* Ensure no excess bits are set. GCN needs this for nunits < 64. x86 needs this for nunits < 8. */ auto nunits = TYPE_VECTOR_SUBPARTS (type).to_constant (); if (maybe_ne (GET_MODE_PRECISION (mode), nunits)) tmp = expand_binop (mode, and_optab, tmp, GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1), target, true, OPTAB_WIDEN); if (tmp != target) emit_move_insn (target, tmp); break; } to yield code that cannot possibly work on a big-endian platform. Coaxing build_truth_vector_type_for_mode to generate more sensible types fixes the problem but runs afoul of the TARGET_VECTORIZE_GET_MASK_MODE hook for some AVX512 modes, so is probably not worth the risk. Moreover, I didn't manage to come up with a big-endian implementation of the above trick that would make some sense for the questionable vector types, so the fix simply disables it. gcc/ PR target/121192 * expr.cc (store_constructor) : Disable the special trick for uniform boolean vectors with integer modes and single-bit mask entries on big-endian platforms. --- diff --git a/gcc/expr.cc b/gcc/expr.cc index 8a1d72ad23b..70b4eda6df3 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -8012,7 +8012,8 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, && VECTOR_BOOLEAN_TYPE_P (type) && SCALAR_INT_MODE_P (TYPE_MODE (type)) && (elt = uniform_vector_p (exp)) - && !VECTOR_TYPE_P (TREE_TYPE (elt))) + && !VECTOR_TYPE_P (TREE_TYPE (elt)) + && !BYTES_BIG_ENDIAN) { rtx op0 = force_reg (TYPE_MODE (TREE_TYPE (elt)), expand_normal (elt)); @@ -8022,7 +8023,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, /* Ensure no excess bits are set. GCN needs this for nunits < 64. x86 needs this for nunits < 8. */ - auto nunits = TYPE_VECTOR_SUBPARTS (type).to_constant (); + unsigned int nunits = TYPE_VECTOR_SUBPARTS (type).to_constant (); if (maybe_ne (GET_MODE_PRECISION (mode), nunits)) tmp = expand_binop (mode, and_optab, tmp, GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),