Bug 95487 - [10 Regression] ICE: verify_gimple failed (error: invalid vector types in nop conversion) with -O3 -march=skylake-avx512 since r10-1052-gc29c92c789d93848
Summary: [10 Regression] ICE: verify_gimple failed (error: invalid vector types in nop...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 11.0
: P2 normal
Target Milestone: 10.2
Assignee: Richard Biener
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: yarpgen
  Show dependency treegraph
 
Reported: 2020-06-03 00:56 UTC by Vsevolod Livinskii
Modified: 2021-11-01 23:07 UTC (History)
8 users (show)

See Also:
Host:
Target: x86_64-*-* i?86-*-*
Build:
Known to work: 10.1.1, 11.0
Known to fail: 10.1.0
Last reconfirmed: 2020-06-03 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vsevolod Livinskii 2020-06-03 00:56:25 UTC
Error:
>$ g++ -O3 -march=skylake-avx512 -c func.cpp
func.cpp: In function ‘void h()’:
func.cpp:7:6: error: invalid vector types in nop conversion
    7 | void h() {
      |      ^
char
vector(32) unsigned char
stmp_117 = (char) stmp_116;
func.cpp:7:6: error: invalid vector types in nop conversion
char
vector(32) unsigned char
stmp_120 = (char) stmp_119;
during GIMPLE pass: vect
func.cpp:7:6: internal compiler error: verify_gimple failed
0x1141df1 verify_gimple_in_cfg(function*, bool)
	/gcc/tree-cfg.c:5461
0x10152af execute_function_todo
	/gcc/passes.c:1985
0x101608e execute_todo
	/gcc/passes.c:2039

Reproducer:
int a;
bool d;
char e;
extern short f[];
extern int g[];
short j;
void h() {
  for (short b = j; b < 0; b += 2) {
    f[b] = 0;
    if (d) {
      for (char c = 0; c < a; c += 3)
        e = 0;
      g[b] = 0;
    }
  }
}

GCC version:
11.0.0 (4b68cb38ddca37a14a6f2f43de3a6d396ee1bc79)

bug 92741 might be related
Comment 1 Martin Liška 2020-06-03 04:53:48 UTC
Confirmed, started with r10-1052-gc29c92c789d93848.
Comment 2 Richard Biener 2020-06-03 06:22:45 UTC
So the issue is in the scatter store the mask is vectorized with V32QImode
but we expect a vector boolean (it seems).  And we run into

             if (TYPE_MODE (masktype) == TYPE_MODE (optype))
                utype = masktype;
              else
                utype = lang_hooks.types.type_for_mode (TYPE_MODE (optype), 1);

with maskype QImode and optype V32QImode.  utype is V32QImode as well after
the above and then with masktype still QImode we do

              if (!useless_type_conversion_p (masktype, utype))
                {
                  gcc_assert (TYPE_PRECISION (utype)
                              <= TYPE_PRECISION (masktype));
                  var = vect_get_new_ssa_name (masktype, vect_scalar_var);
                  new_stmt = gimple_build_assign (var, NOP_EXPR, mask_arg);
                  vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
                  mask_arg = var;

and emit the bogus NOP_EXPR trying to convert from V32QImode to QImode.  Oops?

Jakub, you added the scatter support - do you remember what the code tries to
do here?
Comment 3 Jakub Jelinek 2020-06-03 08:56:28 UTC
(In reply to Richard Biener from comment #2)
> Jakub, you added the scatter support - do you remember what the code tries to
> do here?

I've only added gathers myself (and only the AVX2-ish), scatters were added by Kirill and others from Intel.  And the integer mask in vector boolean vs. normal vectors is a big pain.
Comment 4 Richard Biener 2020-06-03 11:40:02 UTC
I will have a closer look.
Comment 5 Richard Biener 2020-06-03 13:37:10 UTC
We also fail to unswitch the outer loop on if (d) (probably simply because we don't unswitch outer loops).  It's likely the invariantness of the condition
that makes the problem.  We're vectorizing

  <bb 32> [local count: 437450365]:
  # b_43 = PHI <b_24(33), b_15(53)>
  _46 = (int) b_43;
  _65 = &g[_46];
  .MASK_STORE (_65, 32B, d.0_2, 0);
  b.3_25 = (unsigned short) b_43;
  _33 = b.3_25 + 2;
  b_24 = (short int) _33;
  if (b_24 >= 0)
    goto <bb 30>; [11.00%]
  else
    goto <bb 33>; [89.00%]

  <bb 33> [local count: 389330825]:
  goto <bb 32>; [100.00%]

where we use a scatter because we fail to analyze the evolution for g[b].
We don't get a vector boolean type for the mask because the "magic" here
doesn't work this way.

1508          else if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op))
1509                   && VECTOR_BOOLEAN_TYPE_P (stmt_vectype))
1510            vector_type = truth_type_for (stmt_vectype);

which does not consider that the mask in scatters might need a
vector boolean type.  But it appearantly does.

Test coverage for this code seems to be non-existent though :/

I do have a patch that fixes the testcase though.
Comment 6 GCC Commits 2020-06-03 16:59:23 UTC
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:887c45fb5b047171e82710baa51108d5c210eb42

commit r11-878-g887c45fb5b047171e82710baa51108d5c210eb42
Author: Richard Biener <rguenther@suse.de>
Date:   Wed Jun 3 15:51:29 2020 +0200

    tree-optimization/95487 - use a truth type for scatter masks
    
    This makes sure to get a truth type for scatter masks even when they
    are invariant.
    
    2020-06-03  Richard Biener  <rguenther@suse.de>
    
            PR tree-optimization/95487
            * tree-vect-stmts.c (vectorizable_store): Use a truth type
            for the scatter mask.
    
            * g++.dg/vect/pr95487.cc: New testcase.
Comment 7 Richard Biener 2020-06-03 16:59:57 UTC
Fixed on trunk sofar.
Comment 8 GCC Commits 2020-06-23 11:06:52 UTC
The releases/gcc-10 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:2eed94cbf2e8182d700aac3ac52b0967f00a2621

commit r10-8353-g2eed94cbf2e8182d700aac3ac52b0967f00a2621
Author: Richard Biener <rguenther@suse.de>
Date:   Wed Jun 3 15:51:29 2020 +0200

    tree-optimization/95487 - use a truth type for scatter masks
    
    This makes sure to get a truth type for scatter masks even when they
    are invariant.
    
    2020-06-03  Richard Biener  <rguenther@suse.de>
    
            PR tree-optimization/95487
            * tree-vect-stmts.c (vectorizable_store): Use a truth type
            for the scatter mask.
    
            * g++.dg/vect/pr95487.cc: New testcase.
Comment 9 Richard Biener 2020-06-23 11:09:23 UTC
Fixed.