On 22/06/2026 09:41, Richard Biener wrote:
On Fri, Jun 19, 2026 at 4:54 PM Christopher Bazley <[email protected]> wrote:

On 17/06/2026 08:47, Richard Biener wrote:
On Tue, Jun 16, 2026 at 5:52 PM Christopher Bazley <[email protected]> wrote:

Hi Richard,

On 09/06/2026 10:40, Richard Biener wrote:
On Wed, Jun 3, 2026 at 5:21 PM Christopher Bazley <[email protected]> wrote:
@@ -8075,7 +8078,12 @@ store_constructor (tree exp, rtx target, int cleared, 
poly_int64 size,
                      similarly non-const type vectors. */
                   icode = convert_optab_handler (vec_init_optab, mode, 
eltmode);
                 }
-
+           else
+             {
+               /* Handle variable-length vector types.  */
+               icode = convert_optab_handler (vec_init_optab, mode, eltmode);
+               const_n_elts = constant_lower_bound (n_elts);
+             }

And here I'd like to see

               gcc_assert (icode != CODE_FOR_nothing);


Unfortunately, I cannot make this requested change because it causes the
compiler to crash in an existing test case, even if I restrict the scope
of the assertion to the new 'else' block.

The 'else' block was where I wanted the assert to be, of course.


Reproducer:

make check-gcc RUNTESTFLAGS="aarch64-sve-acle.exp=cops_bool.c"

Variable values:

mode = E_VNx16BImode
eltmode = E_QImode
icode = CODE_FOR_nothing

Backtrace:

#0  fancy_abort (file=file@entry=0x255f858
"/work/results_sc/src-patched/gcc/expr.cc", line=line@entry=8085,
function=function@entry=0x25602a0 "store_constructor")
       at /work/results_sc/src-patched/gcc/diagnostics/context.h:558
#1  0x0000000000be9c98 in store_constructor
(exp=exp@entry=0xfffff6577e58, target=target@entry=0xfffff605d408,
cleared=cleared@entry=0, size=..., reverse=reverse@entry=false)
       at /work/results_sc/src-patched/gcc/expr.cc:8085
#2  0x0000000000bec00c in expand_constructor
(exp=exp@entry=0xfffff6577e58, target=0xfffff605d408,
target@entry=0xfffff605d3f0, modifier=modifier@entry=EXPAND_NORMAL,
avoid_temp_mem=avoid_temp_mem@entry=false)
       at /work/results_sc/src-patched/gcc/poly-int.h:470
#3  0x0000000000bd21b8 in expand_expr_real_1 (exp=0xfffff6577e58,
target=<optimized out>, tmode=E_VNx16BImode, modifier=EXPAND_NORMAL,
alt_rtl=0x0, inner_reference_p=<optimized out>)
       at /work/results_sc/src-patched/gcc/expr.cc:11943
#4  0x0000000000bd845c in expand_expr_real_gassign
(g=g@entry=0xfffff65a88f0, target=target@entry=0xfffff605d3f0,
tmode=tmode@entry=E_VNx16BImode, modifier=modifier@entry=EXPAND_NORMAL,
       alt_rtl=alt_rtl@entry=0x0,
inner_reference_p=inner_reference_p@entry=false) at
/work/results_sc/src-patched/gcc/gimple.h:2728
#5  0x0000000000bd5604 in expand_expr_real_1
(exp=exp@entry=0xfffff65bf318, target=<optimized out>,
tmode=E_VNx16BImode, modifier=EXPAND_NORMAL, alt_rtl=0x0,
inner_reference_p=<optimized out>)
       at /work/results_sc/src-patched/gcc/expr.cc:11552
#6  0x0000000000bd8298 in expand_expr_real
(exp=exp@entry=0xfffff65bf318, target=<optimized out>, tmode=<optimized
out>, modifier=modifier@entry=EXPAND_NORMAL, alt_rtl=alt_rtl@entry=0x0,
       inner_reference_p=inner_reference_p@entry=false) at
/work/results_sc/src-patched/gcc/expr.cc:9628
#7  0x0000000000a86328 in expand_expr (exp=0xfffff65bf318,
target=<optimized out>, mode=<optimized out>, modifier=EXPAND_NORMAL) at
/work/results_sc/src-patched/gcc/expr.h:323
#8  expand_return (retval=0xfffff74c9a28) at
/work/results_sc/src-patched/gcc/cfgexpand.cc:4172
#9  expand_gimple_stmt_1 (stmt=0xfffff65a89a0) at
/work/results_sc/src-patched/gcc/cfgexpand.cc:4281
#10 expand_gimple_stmt (stmt=stmt@entry=0xfffff65a89a0) at
/work/results_sc/src-patched/gcc/cfgexpand.cc:4390
#11 0x0000000000a88938 in expand_gimple_basic_block (bb=<optimized out>,
asan_epilog_seq=asan_epilog_seq@entry=0x0) at
/work/results_sc/src-patched/gcc/cfgexpand.cc:6507
--Type <RET> for more, q to quit, c to continue without paging--
#12 0x0000000000a8a568 in (anonymous namespace)::pass_expand::execute
(this=<optimized out>, fun=0xfffff6591000) at
/work/results_sc/src-patched/gcc/cfgexpand.cc:7254
#13 0x0000000000f7ce98 in execute_one_pass (pass=pass@entry=0x3297c70)
at /work/results_sc/src-patched/gcc/passes.cc:2646
#14 0x0000000000f7d8d4 in execute_pass_list_1 (pass=0x3297c70) at
/work/results_sc/src-patched/gcc/passes.cc:2757
#15 0x0000000000f7d948 in execute_pass_list (fn=<optimized out>,
pass=<optimized out>) at /work/results_sc/src-patched/gcc/passes.cc:2768
#16 0x0000000000aced24 in cgraph_node::expand (this=0xfffff6588aa0) at
/work/results_sc/src-patched/gcc/context.h:49
#17 cgraph_node::expand (this=0xfffff6588aa0) at
/work/results_sc/src-patched/gcc/cgraphunit.cc:1827
#18 0x0000000000ad0dc0 in expand_all_functions () at
/work/results_sc/src-patched/gcc/cgraphunit.cc:2057
#19 symbol_table::compile (this=this@entry=0xfffff7406000) at
/work/results_sc/src-patched/gcc/cgraphunit.cc:2435
#20 0x0000000000ad3a48 in symbol_table::compile (this=0xfffff7406000) at
/work/results_sc/src-patched/gcc/cgraphunit.cc:2348
#21 symbol_table::finalize_compilation_unit (this=0xfffff7406000) at
/work/results_sc/src-patched/gcc/cgraphunit.cc:2626
#22 0x00000000010bf96c in compile_file () at
/work/results_sc/src-patched/gcc/toplev.cc:482
#23 0x000000000086baac in do_compile () at
/work/results_sc/src-patched/gcc/toplev.cc:2228
#24 toplev::main (this=this@entry=0xfffffffff078, argc=<optimized out>,
argc@entry=35, argv=<optimized out>, argv@entry=0xfffffffff1f8) at
/work/results_sc/src-patched/gcc/toplev.cc:2392
#25 0x000000000086d094 in main (argc=35, argv=0xfffffffff1f8) at
/work/results_sc/src-patched/gcc/main.cc:39
(gdb) up
#1  0x0000000000be9c98 in store_constructor
(exp=exp@entry=0xfffff6577e58, target=target@entry=0xfffff605d408,
cleared=cleared@entry=0, size=..., reverse=reverse@entry=false)
       at /work/results_sc/src-patched/gcc/expr.cc:8085
8085                    gcc_assert (icode != CODE_FOR_nothing);

Context:

8080                  }
8081                else
8082                  {
8083                    /* Handle variable-length vector types.  */
8084                    icode = convert_optab_handler (vec_init_optab,
mode, eltmode);
8085                    gcc_assert (icode != CODE_FOR_nothing);
8086                    const_n_elts = constant_lower_bound (n_elts);
8087                  }
8088
8089                if (const_n_elts && icode != CODE_FOR_nothing)

As far as I can tell, store_constructor is designed to handle the case
where vector is null. For example, it calls the store_constructor_field
function per element instead of assigning values to RTVEC_ELT (vector,
eltpos).

But right here it does

                vector = rtvec_alloc (const_n_elts);


That statement is in a secondary block that is only entered if
const_n_elts && icode != CODE_FOR_nothing.

In the specific failing test case, the only effect of my proposed change
is to set const_n_elts to a non-zero value; 'vector' keeps its initial
value because icode is still equal to CODE_FOR_nothing:

rtvec vector = NULL;

const_n_elts is not used outside the secondary block that is not
entered, therefore the non-zero value of const_n_elts is irrelevant to
the failing test case.

so not sure what you mean with 'vector is null'.  Or is
constant_lower_bound == 0?

constant_lower_bound (n_elts) is 16, as expected for mode = E_VNx16BImode.

The only case that might be relevant is a {} CTOR, one without elements.  But

CONSTRUCTOR_NELTS (exp) is also 16, so I think that the {} case does not
apply here.

we should have special-paths for that - are they possibly not taken for VLA
vector modes?

I'll note that in general vector CTORs for BImode vectors that are not constant
are a red herring - totally inefficent - and we should avoid those at all cost.

As far as I can tell, the vector is constant, and the generated code
looks acceptable to me, e.g.

         ptrue   p0.b, vl3
         ptrue   p1.b, all

from this macro body (when n == 3):

      svbool_t pg = svptrue_b8 (); \
      svbool_t data1 = svptrue_pat_b8 (SV_VL ## n); \

But yes, the requirement outlined is that the target needs to support
vec_init with E_VNx16BImode, E_QImode.  If it does not the vectorizer
should not have created such CTOR.

I don't think the vectoriser did create it, at least not in this case.
The cops_bool.c.200t.slp2 file is full of "***** Analysis failed
with..." messages. The test does not seem to contain any loops, either.

My understanding is that the vector constructor is created by a call to
a function such as svptrue_b8 (), e.g.

      svbool_t all_true = svptrue_b8 ();

becomes { -1, ... } in

    cmp_35 = sveor_b_z ({ -1, ... }, init1_30, res_init1_34);

which is the GIMPLE version of

    svbool_t cmp = sveor_b_z (all_true, init1, res_init1);

But {-1, ...} is a VECTOR_CST, not a CONSTRUCTOR.


You are right. I was looking at the wrong part of the dump file. I think this is the right part:

__attribute__((noipa, noinline, noclone, no_icf))
svbool_t func_init4 ()
{
  svbool_t temp;
  int _1;
  <signed-boolean:1> _2;
  int _3;
  <signed-boolean:1> _4;

  <bb 2> [local count: 1073741824]:
  _1 = t ();
  _2 = _1 != 0;
  _3 = f ();
  _4 = _3 != 0;
  temp_8 = {-1, _2, 0, -1, 0, _4, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1};
  return temp_8;

}

For which the source code is:

  svbool_t __attribute__ ((noipa)) \
  func_init4 () { \
    svbool_t temp = VECT_CSTN; \
    return temp; \
  } \

using:

#define VECT_CSTN { -1, t (), 0, -1, 0, f (), 0, 0, 0, -1, 0, -1, 0, -1, 0, -1 } /* { dg-warning "overflow in conversion from" "" { target c } } */
        /* { dg-warning "narrowing conversion of" "" { target c++ } .-1 }  */

which does indeed compile to very inefficient-looking code:

func_init4:
.LFB24:
        .cfi_startproc
        addvl   sp, sp, #-1
        .cfi_escape 0xf,0x8,0x8f,0,0x92,0x2e,0,0x38,0x1e,0x22
        sub     sp, sp, #32
        .cfi_escape 0xf,0xa,0x8f,0,0x92,0x2e,0,0x38,0x1e,0x23,0x20,0x22
        stp     x29, x30, [sp]
        .cfi_escape 0x10,0x1d,0x2,0x8f,0
        .cfi_escape 0x10,0x1e,0x2,0x8f,0x8
        mov     x29, sp
        str     x19, [sp, 16]
        addvl   sp, sp, #-18
        .cfi_escape 0xf,0xb,0x8f,0,0x92,0x2e,0,0x8,0x98,0x1e,0x23,0x20,0x22
        .cfi_escape 
0x10,0x13,0xb,0x8f,0,0x92,0x2e,0,0x8,0x90,0x1e,0x23,0x10,0x22
        str     z8, [sp, #2, mul vl]
        str     z9, [sp, #3, mul vl]
        str     z10, [sp, #4, mul vl]
        str     z11, [sp, #5, mul vl]
        str     p15, [sp, #11, mul vl]
        str     p5, [sp, #1, mul vl]
        str     p6, [sp, #2, mul vl]
        str     p7, [sp, #3, mul vl]
        str     p8, [sp, #4, mul vl]
        str     p9, [sp, #5, mul vl]
        str     p10, [sp, #6, mul vl]
        str     p11, [sp, #7, mul vl]
        str     p12, [sp, #8, mul vl]
        str     p13, [sp, #9, mul vl]
        str     p14, [sp, #10, mul vl]
        str     z12, [sp, #6, mul vl]
        str     z13, [sp, #7, mul vl]
        str     z14, [sp, #8, mul vl]
        str     z15, [sp, #9, mul vl]
        str     z16, [sp, #10, mul vl]
        str     z17, [sp, #11, mul vl]
        str     z18, [sp, #12, mul vl]
        str     z19, [sp, #13, mul vl]
        str     z20, [sp, #14, mul vl]
        str     z21, [sp, #15, mul vl]
        str     p4, [sp]
        str     z22, [sp, #16, mul vl]
        str     z23, [sp, #17, mul vl]
        .cfi_escape 0x10,0x48,0x8,0x8f,0,0x92,0x2e,0,0x40,0x1e,0x22
        .cfi_escape 0x10,0x49,0x8,0x8f,0,0x92,0x2e,0,0x48,0x1e,0x22
        .cfi_escape 0x10,0x4a,0x9,0x8f,0,0x92,0x2e,0,0x8,0x20,0x1e,0x22
        .cfi_escape 0x10,0x4b,0x9,0x8f,0,0x92,0x2e,0,0x8,0x28,0x1e,0x22
        .cfi_escape 0x10,0x4c,0x9,0x8f,0,0x92,0x2e,0,0x8,0x30,0x1e,0x22
        .cfi_escape 0x10,0x4d,0x9,0x8f,0,0x92,0x2e,0,0x8,0x38,0x1e,0x22
        .cfi_escape 0x10,0x4e,0x9,0x8f,0,0x92,0x2e,0,0x8,0x40,0x1e,0x22
        .cfi_escape 0x10,0x4f,0x9,0x8f,0,0x92,0x2e,0,0x8,0x48,0x1e,0x22
        bl      t
        mov     w19, w0

        bl      f
        mov     w2, 151

        cntd    x1
        pfalse  p15.b
        mov     w3, 151
        cmp     w19, 0
        mul     x1, x1, x2
        cntd    x2
        mul     x2, x2, x3
        add     x1, x1, 32
        add     x1, sp, x1
        str     p15, [x1]

        add     x2, sp, x2
        mov     w1, 1
        strh    w1, [x2, 32]

        cntd    x1
        rdvl    x2, #20
        mul     x1, x1, x3
        rdvl    x3, #20
        add     x1, x1, 32
        add     x1, sp, x1
        ldr     p15, [x1]
        addpl   x1, x2, #-10
        rdvl    x2, #20
        add     x1, x1, 32
        add     x1, sp, x1
        str     p15, [x1]

        addpl   x1, x2, #-10
        csetm   w2, ne
        add     x1, x1, 32
        cmp     w0, 0
        ldrh    w1, [sp, x1]
        bfi     w1, w2, 1, 1
        addpl   x2, x3, #-10
        add     x2, x2, 32
        add     x2, sp, x2
        strh    w1, [x2]

        addpl   x1, x3, #-10
        add     x1, x1, 32
        mov     w2, 149
        add     x1, sp, x1
        ldr     p15, [x1]
        mov     w3, 149
        cntd    x1
        mul     x1, x1, x2
        add     x1, x1, 32
        add     x1, sp, x1
        str     p15, [x1]

etc..

I have confirmed that the same (bad) code generation occurs without my changes in this patchset, and also at the commit upon which my patch series is based (i.e., without any of my BB SLP patches).

I think it would be worthwhile to improve store_constructor for most types even if it still has pathological behavior for one type, so I am tempted to report it as a bug and move on. I can also note in the commit log that the described non-fallback behaviour of store_constructor relies on vec_init having been implemented for the mode and eltmode.

Please consider approving the latest version of this patch without the bugfix:
https://forge.sourceware.org/gcc/gcc-TEST/pulls/177
https://inbox.sourceware.org/gcc-patches/bmm.hjj7t7yaru.gcc.gcc-test.chris.bazley.177....@forge-stage.sourceware.org/
--
Christopher Bazley
Staff Software Engineer, GNU Tools Team.
Arm Ltd, 110 Fulbourn Road, Cambridge, CB1 9NJ, UK.
http://www.arm.com/

Reply via email to