Bug 92741 - [10 Regression] ICE: verify_gimple failed (error: invalid vector types in nop conversion)
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: 10.0
: P3 normal
Target Milestone: 10.0
Assignee: Richard Sandiford
URL:
Keywords: ice-on-valid-code, missed-optimization
Depends on:
Blocks:
 
Reported: 2019-12-01 04:56 UTC by Arseny Solokha
Modified: 2019-12-02 17:52 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64-unknown-linux-gnu
Build:
Known to work: 9.2.0
Known to fail: 10.0
Last reconfirmed: 2019-12-01 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arseny Solokha 2019-12-01 04:56:14 UTC
gcc-10.0.0-alpha20191124 snapshot (r278660) ICEs when compiling the following testcase reduced from testsuite/gcc.target/i386/sse2-mmx-pinsrw.c w/ -O2 -fexceptions -fnon-call-exceptions -fno-inline:

typedef int vh __attribute__ ((__vector_size__ (2 * sizeof (int))));
typedef short int cq __attribute__ ((__vector_size__ (4 * sizeof (short int))));

static void
id (int *r8, vh *tu)
{
  *(vh *) r8 = *tu;
}

void
mr (void)
{
  int r8;
  cq he = { 0, };

  id (&r8, (vh *) &he);
}

% x86_64-unknown-linux-gnu-gcc-10.0.0-alpha20191124 -O2 -fexceptions -fnon-call-exceptions -fno-inline -c pi4vkh1k.c
pi4vkh1k.c: In function 'id.constprop':
pi4vkh1k.c:5:1: error: invalid vector types in nop conversion
    5 | id (int *r8, vh *tu)
      | ^~
vector(2) int
cq
_2 = (vector(2) int) { 0, 0, 0, 0 };
during GIMPLE pass: fixup_cfg
pi4vkh1k.c:5:1: internal compiler error: verify_gimple failed
0xd57c08 verify_gimple_in_cfg(function*, bool)
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/tree-cfg.c:5445
0xc3af99 execute_function_todo
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/passes.c:1983
0xc3bcb7 do_per_function
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/passes.c:1638
0xc3bcb7 execute_todo
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/passes.c:2037

W/ -fopenacc the check fails during IPA pass pta instead.
Comment 1 Martin Liška 2019-12-01 18:05:08 UTC
Confirmed, started with r278245.
Comment 2 Richard Biener 2019-12-02 07:48:41 UTC
_2 = (vector(2) int) { 0, 0, 0, 0 };

that's also not folded.
Comment 3 Richard Sandiford 2019-12-02 07:51:35 UTC
Mine.
Comment 4 Richard Sandiford 2019-12-02 09:13:45 UTC
This comes from:

      if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v->value)))
        {
          if (fold_convertible_p (TREE_TYPE (rhs), v->value))
            val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v->value);
          else if (TYPE_SIZE (TREE_TYPE (rhs))
                   == TYPE_SIZE (TREE_TYPE (v->value)))
            val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v->value);

in ipcp_modif_dom_walker::before_dom_children.  fold_convertible_p
is returning true for the mismatched vector types, which is clearly
a bug and I have a fix.  But does anyone have any thoughts on whether
the above code is correct?  It seems strange to be trusting
fold_convertible_p with the choice when this kind of type punning
always acts as a VIEW_CONVERT_EXPR-style reinterpret of the
memory contents.  Earlier we have:

      if (!v
          || v->by_ref != by_ref
          || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v->value))),
                       size))
        continue;

which I guess makes it safe in practice.
Comment 5 Martin Jambor 2019-12-02 12:28:25 UTC
(In reply to rsandifo@gcc.gnu.org from comment #4)
> This comes from:
> 
>       if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v->value)))
>         {
>           if (fold_convertible_p (TREE_TYPE (rhs), v->value))
>             val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v->value);
>           else if (TYPE_SIZE (TREE_TYPE (rhs))
>                    == TYPE_SIZE (TREE_TYPE (v->value)))
>             val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v->value);
> 
> in ipcp_modif_dom_walker::before_dom_children.  fold_convertible_p
> is returning true for the mismatched vector types, which is clearly
> a bug and I have a fix.  But does anyone have any thoughts on whether
> the above code is correct?

We do the same for inlining (and IPA-SRA) in force_value_to_type in
tree-inline.c which is where I guess this comes from.  There it is
meant to deal with potential parameter type promotion but you are
right that with values passed in aggregates, V_C_Eing always makes
more sense.

> It seems strange to be trusting
> fold_convertible_p with the choice when this kind of type punning
> always acts as a VIEW_CONVERT_EXPR-style reinterpret of the
> memory contents.  Earlier we have:
> 
>       if (!v
>           || v->by_ref != by_ref
>           || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v->value))),
>                        size))
>         continue;
> 
> which I guess makes it safe in practice.

Yes, I guess it would.
Comment 6 Richard Sandiford 2019-12-02 17:51:39 UTC
Author: rsandifo
Date: Mon Dec  2 17:51:08 2019
New Revision: 278910

URL: https://gcc.gnu.org/viewcvs?rev=278910&root=gcc&view=rev
Log:
Tighten check for vector types in fold_convertible_p (PR 92741)

In this PR, IPA-CP was misled into using NOP_EXPR rather than
VIEW_CONVERT_EXPR to reinterpret a vector of 4 shorts as a vector
of 2 ints.  This tripped the tree-cfg.c assert I'd added in r278245.

2019-12-02  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	PR middle-end/92741
	* fold-const.c (fold_convertible_p): Check vector types more
	thoroughly.

gcc/testsuite/
	PR middle-end/92741
	* gcc.dg/pr92741.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr92741.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/fold-const.c
    trunk/gcc/testsuite/ChangeLog
Comment 7 Richard Sandiford 2019-12-02 17:52:02 UTC
Fixed.