Bug 113163 - [14 Regression][GCN] ICE in vect_peel_nonlinear_iv_init, at tree-vect-loop.cc:9420
Summary: [14 Regression][GCN] ICE in vect_peel_nonlinear_iv_init, at tree-vect-loop.cc...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 14.0
: P1 normal
Target Milestone: 14.0
Assignee: Tamar Christina
URL:
Keywords: ice-on-valid-code
: 113169 (view as bug list)
Depends on:
Blocks:
 
Reported: 2023-12-28 11:37 UTC by Tobias Burnus
Modified: 2024-03-06 16:09 UTC (History)
3 users (show)

See Also:
Host:
Target: amdgcn-amdhsa
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-12-28 00:00:00


Attachments
Reduced testcase ( (360 bytes, text/plain)
2023-12-28 12:20 UTC, Tobias Burnus
Details
nonlinear IV (1.02 KB, patch)
2023-12-28 14:20 UTC, Tamar Christina
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2023-12-28 11:37:57 UTC
The ICE happens when building Newlib with the GCN compiler:

during GIMPLE pass: vect
In file included from src/accel_newlib-mainline/newlib/libc/stdlib/l64a.c:24:
src/accel_newlib-mainline/newlib/libc/include/stdlib.h: In function 'l64a':
src/accel_newlib-mainline/newlib/libc/include/stdlib.h:195:9: internal compiler error: in vect_peel_nonlinear_iv_init, at tree-vect-loop.cc:9420
  195 | char *  l64a (long __input);
      |         ^~~~
Comment 1 Tamar Christina 2023-12-28 11:53:32 UTC
Hi,

This does not contain enough information for me to try to reproduce the issue.

Can you give me the full target triple, compile flag and how the compiler was configured?

A reproducer would be helpful too.
Comment 2 Tobias Burnus 2023-12-28 12:20:00 UTC
Created attachment 56958 [details]
Reduced testcase (

$ amdgcn-amdhsa-gcc -g -O2 inp5.i -march=gfx900

during GIMPLE pass: vect
inp5.i: In function '_l64a_r':
inp5.i:4:1: internal compiler error: in vect_peel_nonlinear_iv_init, at tree-vect-loop.cc:9420
    4 | _l64a_r (struct _reent *rptr,
      | ^~~~~~~
0x94cc17 vect_peel_nonlinear_iv_init(gimple**, tree_node*, tree_node*, tree_node*, vect_induction_op_type)
        /net/build5-fossa-cs/scratch/tburnus/fsf.mainline.x86_64-linux-gnu-amdgcn/src/gcc-mainline/gcc/tree-vect-loop.cc:9420
0x148bb04 vect_update_ivs_after_vectorizer
        src/gcc-mainline/gcc/tree-vect-loop-manip.cc:2267
0x1498153 vect_do_peeling(_loop_vec_info*, tree_node*, tree_node*, tree_node**, tree_node**, tree_node**, int, bool, bool, tree_node**)
        src/gcc-mainline/gcc/tree-vect-loop-manip.cc:3399
0x148714e vect_transform_loop(_loop_vec_info*, gimple*)
        src/gcc-mainline/gcc/tree-vect-loop.cc:11911
0x14c9544 vect_transform_loops
        src/gcc-mainline/gcc/tree-vectorizer.cc:1006
0x14c9bc3 try_vectorize_loop_1
        src/gcc-mainline/gcc/tree-vectorizer.cc:1152
0x14c9bc3 try_vectorize_loop
        src/gcc-mainline/gcc/tree-vectorizer.cc:1182
0x14ca224 execute
        src/gcc-mainline/gcc/tree-vectorizer.cc:1298

 * * *

Breakpoint 1, vect_peel_nonlinear_iv_init (stmts=0x7fffffffd698, init_expr=0x7ffff7a56948, skip_niters=0x7ffff7bb8798, 
    step_expr=0x7ffff7a64ba0, induction_type=vect_step_op_shr)
    at src/gcc-mainline/gcc/tree-vect-loop.cc:9420
9420      gcc_assert (TREE_CODE (skip_niters) == INTEGER_CST);

(gdb) p debug_tree(skip_niters)
 <ssa_name 0x7ffff7bb8798
    type <integer_type 0x7ffff7b5e3f0 public unsigned SI
        size <integer_cst 0x7ffff7a64768 constant 32>
        unit-size <integer_cst 0x7ffff7a64780 constant 4>
        align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff7b5e3f0 precision:32 min <integer_cst 0x7ffff7b752d0 0> max <integer_cst 0x7ffff7a64b28 4294967295>>
   
    def_stmt GIMPLE_NOP
    version:54>
$2 = void
Comment 3 Tamar Christina 2023-12-28 12:22:05 UTC
Thanks, taking a look.
Comment 4 Tamar Christina 2023-12-28 12:25:48 UTC
Hmm so can't seem to reproduce it with x86_64 or aarch64.

let me build a --target=amdgcn-amdhsa
Comment 5 Tobias Burnus 2023-12-28 12:27:30 UTC
While higher at the call stack:

#3  0x000000000148714f in vect_transform_loop (loop_vinfo=loop_vinfo@entry=0x350f2a0, loop_vectorized_call=loop_vectorized_call@entry=0x0)
    at src/gcc-mainline/gcc/tree-vect-loop.cc:11911
11911     epilogue = vect_do_peeling (loop_vinfo, niters, nitersm1, &niters_vector,

(gdb) p debug_tree(niters)
 <integer_cst 0x7ffff7bb2030 type <integer_type 0x7ffff7b5e3f0> constant 6>


One level down:

#2  0x0000000001498154 in vect_do_peeling (loop_vinfo=loop_vinfo@entry=0x350f2a0, niters=<optimized out>, niters@entry=0x7ffff7bb2030, 
    nitersm1=nitersm1@entry=0x7ffff7bb2c78, niters_vector=niters_vector@entry=0x7fffffffda60, step_vector=step_vector@entry=0x7fffffffda68, 
    niters_vector_mult_vf_var=niters_vector_mult_vf_var@entry=0x7fffffffda70, th=<optimized out>, check_profitability=<optimized out>, 
    niters_no_overflow=<optimized out>, advance=<optimized out>)
    at src/gcc-mainline/gcc/tree-vect-loop-manip.cc:3399
3399            vect_update_ivs_after_vectorizer (loop_vinfo, niters_vector_mult_vf,

where niters_vector_mult_vf is ssa_name that fails in the assert.


The variable seems to be generated a few lines up in the same function (line 3375 and following):

      if (!integer_onep (*step_vector))
        {
          /* On exit from the loop we will have an easy way of calcalating
             NITERS_VECTOR / STEP * STEP.  Install a dummy definition
             until then.  */
          niters_vector_mult_vf = make_ssa_name (TREE_TYPE (*niters_vector));
          SSA_NAME_DEF_STMT (niters_vector_mult_vf) = gimple_build_nop ();
          *niters_vector_mult_vf_var = niters_vector_mult_vf;
        }
      else
        vect_gen_vector_loop_niters_mult_vf (loop_vinfo, *niters_vector,
                                             &niters_vector_mult_vf);
Comment 6 Tobias Burnus 2023-12-28 12:30:27 UTC
and for that condition, we have:

3375          if (!integer_onep (*step_vector))
(gdb) p debug_tree(*step_vector)
 <integer_cst 0x7ffff7bb2f48 type <integer_type 0x7ffff7b5e3f0> constant 8>
Comment 7 Tamar Christina 2023-12-28 14:20:05 UTC
ok, managed to reproduce using a cross cc1.

This seems to happen because the vectorizer decides to use partial vectors to vectorize the loop and the target picks a nonlinear induction step which we can't support for early breaks.

The attached patch fixes it by rejecting these kind of inductions when partial vectors are forced.

I'll submit the patch for when maintainers are back from holidays.
Comment 8 Tamar Christina 2023-12-28 14:20:46 UTC
Created attachment 56959 [details]
nonlinear IV
Comment 9 Tamar Christina 2023-12-29 14:48:05 UTC
*** Bug 113169 has been marked as a duplicate of this bug. ***
Comment 10 Tamar Christina 2023-12-29 21:06:43 UTC
Patch submitted
Comment 11 Andrew Stubbs 2024-01-02 11:29:46 UTC
(In reply to Tamar Christina from comment #7)
> This seems to happen because the vectorizer decides to use partial vectors
> to vectorize the loop and the target picks a nonlinear induction step which
> we can't support for early breaks.

In which hook is this selected?

I'm not aware of this being a deliberate choice we made...
Comment 12 Tamar Christina 2024-01-02 11:35:34 UTC
(In reply to Andrew Stubbs from comment #11)
> (In reply to Tamar Christina from comment #7)
> > This seems to happen because the vectorizer decides to use partial vectors
> > to vectorize the loop and the target picks a nonlinear induction step which
> > we can't support for early breaks.
> 
> In which hook is this selected?
> 
> I'm not aware of this being a deliberate choice we made...

I haven't looked into why on the target we get a nonlinear induction (mostly because I don't know much about the target). I however wasn't able to reproduce it on SVE and x86_64 even when forcing partial vectors.

So I guess it's more accurate to say "something about the target" is making the vectorizer pick a nonlinear induction.  most likely missing support for something.

Note that the testcase does work if partial vectors is turned off. So It should work fine if the vectorizer retries without partial vectors.

waiting for Richi to come back from holiday to review the patch and should be fixed.
Comment 13 GCC Commits 2024-01-09 11:18:41 UTC
The master branch has been updated by Tamar Christina <tnfchris@gcc.gnu.org>:

https://gcc.gnu.org/g:cbf569486b2decbde0308f9f4d0f0837e4cfefd9

commit r14-7036-gcbf569486b2decbde0308f9f4d0f0837e4cfefd9
Author: Tamar Christina <tamar.christina@arm.com>
Date:   Tue Jan 9 11:16:16 2024 +0000

    middle-end: rejects loops with nonlinear inductions and early breaks [PR113163]
    
    We can't support nonlinear inductions other than neg when vectorizing
    early breaks and iteration count is known.
    
    For early break we currently require a peeled epilog but in these cases
    we can't compute the remaining values.
    
    gcc/ChangeLog:
    
            PR middle-end/113163
            * tree-vect-loop-manip.cc (vect_can_peel_nonlinear_iv_p):
            Reject non-linear inductions that aren't supported.
    
    gcc/testsuite/ChangeLog:
    
            PR middle-end/113163
            * gcc.target/gcn/pr113163.c: New test.
Comment 14 Tamar Christina 2024-01-09 11:25:07 UTC
Fixed, thanks for the report.