[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 Richard Biener changed: What|Removed |Added Assignee|marxin at gcc dot gnu.org |rguenth at gcc dot gnu.org Resolution|--- |FIXED Status|ASSIGNED|RESOLVED --- Comment #11 from Richard Biener --- Fixed.
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 --- Comment #10 from CVS Commits --- The master branch has been updated by Richard Biener : https://gcc.gnu.org/g:bc909324bda71543add2229adfa59d8daff5f0db commit r11-3394-gbc909324bda71543add2229adfa59d8daff5f0db Author: Richard Biener Date: Wed Sep 23 14:20:44 2020 +0200 middle-end/96466 - fix VEC_COND isel/expansion issue We need to avoid forcing BLKmode for truth vectors, instead do as other code and use VOIDmode so layout_type can pick a suitable and consistent mode. RTL expansion of vect_cond_mask also needs to deal with CONST_INT operands which means passing the mode explicitely. 2020-09-23 Richard Biener PR middle-end/96466 * internal-fn.c (expand_vect_cond_mask_optab_fn): Use appropriate mode for force_reg. * tree.c (build_truth_vector_type_for): Pass VOIDmode to make_vector_type. * gcc.dg/pr96466.c: New testcase.
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 Richard Biener changed: What|Removed |Added CC||rsandifo at gcc dot gnu.org --- Comment #9 from Richard Biener --- So there's some weird stuff going along here. We end up with a BLKmode vector because build_truth_vector_type_for is called with a vector which has DImode (rather than V1DImode - that's stor-layouts fallback). And build_truth_vector_type_for does static tree build_truth_vector_type_for (tree vectype) { machine_mode vector_mode = TYPE_MODE (vectype); poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); machine_mode mask_mode; if (VECTOR_MODE_P (vector_mode) && targetm.vectorize.get_mask_mode (vector_mode).exists (&mask_mode)) return build_truth_vector_type_for_mode (nunits, mask_mode); poly_uint64 vsize = tree_to_poly_uint64 (TYPE_SIZE (vectype)); unsigned HOST_WIDE_INT esize = vector_element_size (vsize, nunits); tree bool_type = build_nonstandard_boolean_type (esize); return make_vector_type (bool_type, nunits, BLKmode); } where I wonder why we do not use VOIDmode so that layout_type can make an appropriate choice. If we do that then we ICE later during RTL pass: expand t.i: In function 'foo': t.i:10:10: internal compiler error: in int_mode_for_mode, at stor-layout.c:404 10 | v &= x >= v; |~~^~~~ 0x1270a2c int_mode_for_mode(machine_mode) ../../src/trunk/gcc/stor-layout.c:404 0xd94340 emit_move_via_integer ../../src/trunk/gcc/expr.c:3425 0xd9548d emit_move_insn_1(rtx_def*, rtx_def*) ../../src/trunk/gcc/expr.c:3793 0xd95dc5 emit_move_insn(rtx_def*, rtx_def*) ../../src/trunk/gcc/expr.c:3935 0xd65f48 force_reg(machine_mode, rtx_def*) ../../src/trunk/gcc/explow.c:657 0xf2384e expand_vect_cond_mask_optab_fn ../../src/trunk/gcc/internal-fn.c:2647 0xf27b82 expand_VCOND_MASK ../../src/trunk/gcc/internal-fn.def:146 because of the CONST_INT (DImode...) args with VOIDmode to force_reg in expand_vect_cond_mask_optab_fn: 2642 mask = expand_normal (op0); 2643 rtx_op1 = expand_normal (op1); 2644 rtx_op2 = expand_normal (op2); 2645 2646 mask = force_reg (mask_mode, mask); 2647 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1); (gdb) p debug_rtx (rtx_op1) (const_int -1 [0x]) simply using 'mode' here works and we expand the testcase to bar: .LFB0: .cfi_startproc fmovd1, x0 cmhsd1, d1, d0 and v0.8b, v1.8b, v0.8b ret .cfi_endproc .LFE0: .size bar, .-bar .align 2 .global foo .type foo, %function foo: .LFB1: .cfi_startproc fmovd0, xzr ret
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 --- Comment #8 from rguenther at suse dot de --- On Fri, 28 Aug 2020, marxin at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 > > --- Comment #7 from Martin Liška --- > > As said you have to fake "regular" non-bool comparison operands, > > best based on the COND_EXPRs operand types (using integer types > > of the same size) > > All right, do you mean something like what we do in > tree-vect-generic.c:422-457? Yeah. > Or is the isel pass the right place for the fake comparison? Sure, only ISEL knows that it needs it.
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 --- Comment #7 from Martin Liška --- > As said you have to fake "regular" non-bool comparison operands, > best based on the COND_EXPRs operand types (using integer types > of the same size) All right, do you mean something like what we do in tree-vect-generic.c:422-457? Or is the isel pass the right place for the fake comparison?
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 --- Comment #6 from rguenther at suse dot de --- On Fri, 28 Aug 2020, marxin at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 > > --- Comment #5 from Martin Liška --- > Looking at the ICE, we actually ICE at the place where a fake comparison is > constructed: > > if (TREE_CODE_CLASS (tcode) != tcc_comparison) > { > gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0))); > if (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0))) > != CODE_FOR_nothing) > return gimple_build_call_internal (IFN_VCOND_MASK, 3, op0, op1, op2); > /* Fake op0 < 0. */ > else > { > gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0))) > == MODE_VECTOR_INT); > op0a = op0; > op0b = build_zero_cst (TREE_TYPE (op0)); > tcode = LT_EXPR; > } > } > > So we have: > > (gdb) p debug_tree(op0a) > type type size > unit-size > align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type > 0x7743bf18 precision:64 min -9223372036854775808> max > > BLK size unit-size 0x775d4db0 8> > align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type > 0x7743b1f8 nunits:1> > visited > def_stmt _4 = { 0 }; > version:4> > $4 = void > (gdb) p debug_tree(op0b) > type type size > unit-size > align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type > 0x7743bf18 precision:64 min -9223372036854775808> max > > BLK size unit-size 0x775d4db0 8> > align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type > 0x7743b1f8 nunits:1> > constant npatterns:1 nelts-per-pattern:1 > elt:0: > constant 0>> > $5 = void > (gdb) p tcode > $7 = LT_EXPR > > but the modes do not match: > > (gdb) p mode > $1 = E_DImode > (gdb) p cmp_op_mode > $2 = E_BLKmode > > and so we ICE here: > > gcc_assert (known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (cmp_op_mode)) > && known_eq (GET_MODE_NUNITS (mode), >GET_MODE_NUNITS (cmp_op_mode))); > > So what to do about it? As said you have to fake "regular" non-bool comparison operands, best based on the COND_EXPRs operand types (using integer types of the same size)
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 --- Comment #5 from Martin Liška --- Looking at the ICE, we actually ICE at the place where a fake comparison is constructed: if (TREE_CODE_CLASS (tcode) != tcc_comparison) { gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0))); if (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0))) != CODE_FOR_nothing) return gimple_build_call_internal (IFN_VCOND_MASK, 3, op0, op1, op2); /* Fake op0 < 0. */ else { gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0))) == MODE_VECTOR_INT); op0a = op0; op0b = build_zero_cst (TREE_TYPE (op0)); tcode = LT_EXPR; } } So we have: (gdb) p debug_tree(op0a) unit-size align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7743bf18 precision:64 min max > BLK size unit-size align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7743b1f8 nunits:1> visited def_stmt _4 = { 0 }; version:4> $4 = void (gdb) p debug_tree(op0b) unit-size align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7743bf18 precision:64 min max > BLK size unit-size align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7743b1f8 nunits:1> constant npatterns:1 nelts-per-pattern:1 elt:0: constant 0>> $5 = void (gdb) p tcode $7 = LT_EXPR but the modes do not match: (gdb) p mode $1 = E_DImode (gdb) p cmp_op_mode $2 = E_BLKmode and so we ICE here: gcc_assert (known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (cmp_op_mode)) && known_eq (GET_MODE_NUNITS (mode), GET_MODE_NUNITS (cmp_op_mode))); So what to do about it?
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 --- Comment #4 from Richard Biener --- (In reply to Martin Liška from comment #3) > It's the same store as PR96453: copyprop can eliminate that to: > > Folding statement: _3 = { 5 }; > Queued stmt for removal. Folds to: { 5 } > Folding statement: _4 = VEC_COND_EXPR <_3 > { 4441221374 }, { -1 }, { 0 }>; > gimple_simplified to _4 = { 0 }; > Folded into: _4 = { 0 }; > > @Richi: Can we teach copyprop to fold constant expressions for > VEC_COND_EXPRs that have first argument equal to a constant? Not sure what you are asking for - copyprop already does constant folding. Also wouldn't -fno-tree-copy-prop then re-introduce the issue? Doesn't the issue exist with -O0 when always_inline is used? Hmm, no, then I see : x_3 = 5; v_4 = { 4441221375 }; x.0_5 = x_3; _6 = {x.0_5}; _7 = v_4 <= _6; _8 = VEC_COND_EXPR <_7, { -1 }, { 0 }>; _9 = VIEW_CONVERT_EXPR(_8); _13 = VIEW_CONVERT_EXPR(_9); _14 = _13 & 4441221375; v_10 = {_14}; _11 = v_10; fed into ISEL which makes it happy. OK, so ISEL does not like _4 = { 0 }; _5 = VEC_COND_EXPR <_4, { -1 }, { 0 }>; but I think it has to cope with this situation. I can imagine even sth like _4 = { 0 }; _5 = _4; _6 = VEC_COND_EXPR <_5, { -1 }, { 0 }>; thus a stray copy. Or a more complex boolean vector like { 0, -1, 0, -1 } or so. For a constant it should be possible to fake a compare generating it, say, for (vector(2) ) { 0, -1 } use (signed:64){ 0, -1 } != (signed:64){ 0, 0 } of course for a general SSA boolean vector there's no way to build it up if the target cannot code-generate it by itself. Note that if you'd have _4 = { 0, -1 }; _5 = VEC_COND_EXPR <_4, a_7, b_8>; then while you can constant-fold away the condition you will end up with a VEC_PERM which might not be supported either. So faking a compare is IMHO better here.
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 Martin Liška changed: What|Removed |Added CC||rguenth at gcc dot gnu.org --- Comment #3 from Martin Liška --- It's the same store as PR96453: copyprop can eliminate that to: Folding statement: _3 = { 5 }; Queued stmt for removal. Folds to: { 5 } Folding statement: _4 = VEC_COND_EXPR <_3 > { 4441221374 }, { -1 }, { 0 }>; gimple_simplified to _4 = { 0 }; Folded into: _4 = { 0 }; @Richi: Can we teach copyprop to fold constant expressions for VEC_COND_EXPRs that have first argument equal to a constant?
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 --- Comment #2 from Martin Liška --- Started with my r11-1445-g502d63b6d6141597.
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 Martin Liška changed: What|Removed |Added Ever confirmed|0 |1 Last reconfirmed||2020-08-10 Assignee|unassigned at gcc dot gnu.org |marxin at gcc dot gnu.org Status|UNCONFIRMED |ASSIGNED --- Comment #1 from Martin Liška --- Let me take a look.
[Bug tree-optimization/96466] [11 Regression] ICE: in gimple_expand_vec_cond_expr, at gimple-isel.cc:122 with -Og -finline-functions-called-once -fno-tree-ccp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96466 Richard Biener changed: What|Removed |Added Target Milestone|--- |11.0 CC||marxin at gcc dot gnu.org Summary|11 Regression] ICE: in |[11 Regression] ICE: in |gimple_expand_vec_cond_expr |gimple_expand_vec_cond_expr |, at gimple-isel.cc:122 |, at gimple-isel.cc:122 |with -Og|with -Og |-finline-functions-called-o |-finline-functions-called-o |nce -fno-tree-ccp |nce -fno-tree-ccp