The error is not specific to skylake-avx512, I have a reproducer that shows it. Reproducer: #include <algorithm> extern int var_142; extern int a, c; long h; unsigned long long e; signed char d; extern short arr_323[][7][5][30]; void test(long long b, short f[][17][25][22][20]) { for (char i = 0; i < 7; i += 3) for (unsigned char l = e; l < 5; l += 2) { if (std::max((long long)0, std::min((long long)7, b))) for (bool j = 0; j < 1; j = b) { for (unsigned k = d; k < 20; k++) h = f[0][i][l][b][k]; for (int m = 0; m < 5; m++) arr_323[c][i][l][m] = 0; } for (int n = 0; n < 4; n += a) var_142 = n; } } Error: >$ g++ -O3 -march=skylake-avx512 func.cpp -c during GIMPLE pass: lim func.cpp: In function ‘void test(long long int, short int (*)[17][25][22][20])’: func.cpp:10:6: internal compiler error: in build2, at tree.c:4869 10 | void test(long long b, | ^~~~ 0x85386f build2(tree_code, tree_node*, tree_node*, tree_node*) gcc/gcc_src/gcc/tree.c:4869 0xddb96f build2_loc gcc/gcc_src/gcc/tree.h:4407 0xddb96f fold_build2_loc(unsigned int, tree_code, tree_node*, tree_node*, tree_node*) gcc/gcc_src/gcc/fold-const.c:13736 0xde8de3 extract_muldiv_1 gcc/gcc_src/gcc/fold-const.c:6976 0xdea422 extract_muldiv gcc/gcc_src/gcc/fold-const.c:6662 0xdea422 extract_muldiv gcc/gcc_src/gcc/fold-const.c:6662 0xdea422 extract_muldiv gcc/gcc_src/gcc/fold-const.c:6662 0xdd6bb1 fold_binary_loc(unsigned int, tree_code, tree_node*, tree_node*, tree_node*) gcc/gcc_src/gcc/fold-const.c:11486 0xddb94d fold_build2_loc(unsigned int, tree_code, tree_node*, tree_node*, tree_node*) gcc/gcc_src/gcc/fold-const.c:13734 0x1c3b096 aff_combination_add_elt(aff_tree*, tree_node*, generic_wide_int<fixed_wide_int_storage<192> > const&) gcc/gcc_src/gcc/tree-affine.c:187 0x1c3b3d5 aff_combination_add(aff_tree*, aff_tree*) gcc/gcc_src/gcc/tree-affine.c:215 0x124fc0f mem_refs_may_alias_p gcc/gcc_src/gcc/tree-ssa-loop-im.c:1718 0x124fc83 refs_independent_p gcc/gcc_src/gcc/tree-ssa-loop-im.c:2703 0x12502b4 ref_indep_loop_p gcc/gcc_src/gcc/tree-ssa-loop-im.c:2764 0x1255ff4 can_sm_ref_p gcc/gcc_src/gcc/tree-ssa-loop-im.c:2832 0x1255ff4 find_refs_for_sm gcc/gcc_src/gcc/tree-ssa-loop-im.c:2853 0x1255ff4 store_motion_loop gcc/gcc_src/gcc/tree-ssa-loop-im.c:2889 0x1255ddc store_motion_loop gcc/gcc_src/gcc/tree-ssa-loop-im.c:2896 0x1255ddc store_motion_loop gcc/gcc_src/gcc/tree-ssa-loop-im.c:2896 0x1258262 do_store_motion gcc/gcc_src/gcc/tree-ssa-loop-im.c:2911 gcc version 11.0.1 20210323 (6b1f841ce0ccf30eda7896ba5ab0aa94c72307b2) (GCC)
Started with r11-3705-gdae673abd37d400408959497e50fe1f3fbef5533 Testcase without any includes: template<typename T> constexpr inline const T& min(const T& a, const T& b) { if (b < a) return b; return a; } template<typename T> constexpr inline const T& max(const T& a, const T& b) { if (a < b) return b; return a; } extern int var_142; extern int a, c; long h; unsigned long long e; signed char d; extern short arr_323[][7][5][30]; void test(long long b, short f[][17][25][22][20]) { for (char i = 0; i < 7; i += 3) for (unsigned char l = e; l < 5; l += 2) { if (max(0LL, min(7LL, b))) for (bool j = 0; j < 1; j = b) { for (unsigned k = d; k < 20; k++) h = f[0][i][l][b][k]; for (int m = 0; m < 5; m++) arr_323[c][i][l][m] = 0; } for (int n = 0; n < 4; n += a) var_142 = n; } }
Seems to be a fold-const.c bug.
So, one thing is that tree-affine.c during store motion alias analysis feeds very questionable expressions to the folder, in particular it attempts to fold MULT_EXPR of (sizetype) (vector(4) short int *) ((int) ivtmp.46_14 * 3) where ivtmp.46_14 is unsigned int, and (sizetype) -1. Note e.g. the cast from int to pointer of different size, or pointer back to sizetype. And another thing is that extract_muldiv{,_1} really relies on integral types only, is called when the divisor or second multiplication operand is INTEGER_CST and the multiplication/division aren't defined for other types that represent constants as INTEGER_CST (e.g. pointers, NULLPTR_TYPE etc.). Vector types really should use VECTOR_CSTs... The ICE can be fixed with: --- gcc/fold-const.c.jj 2021-03-25 13:41:55.000000000 +0100 +++ gcc/fold-const.c 2021-03-26 11:51:57.901091895 +0100 @@ -6713,6 +6713,8 @@ extract_muldiv_1 (tree t, tree c, enum t break; CASE_CONVERT: case NON_LVALUE_EXPR: + if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))) + break; /* If op0 is an expression ... */ if ((COMPARISON_CLASS_P (op0) || UNARY_CLASS_P (op0) @@ -6721,8 +6723,7 @@ extract_muldiv_1 (tree t, tree c, enum t || EXPRESSION_CLASS_P (op0)) /* ... and has wrapping overflow, and its type is smaller than ctype, then we cannot pass through as widening. */ - && (((ANY_INTEGRAL_TYPE_P (TREE_TYPE (op0)) - && TYPE_OVERFLOW_WRAPS (TREE_TYPE (op0))) + && ((TYPE_OVERFLOW_WRAPS (TREE_TYPE (op0)) && (TYPE_PRECISION (ctype) > TYPE_PRECISION (TREE_TYPE (op0)))) /* ... or this is a truncation (t is narrower than op0), @@ -6737,8 +6738,7 @@ extract_muldiv_1 (tree t, tree c, enum t /* ... or has undefined overflow while the converted to type has not, we cannot do the operation in the inner type as that would introduce undefined overflow. */ - || ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (op0)) - && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0))) + || (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)) && !TYPE_OVERFLOW_UNDEFINED (type)))) break;
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:25e515d2199d555848dfba01fd5364df94096496 commit r11-7887-g25e515d2199d555848dfba01fd5364df94096496 Author: Jakub Jelinek <jakub@redhat.com> Date: Mon Mar 29 12:35:32 2021 +0200 fold-const: Fix ICE in extract_muldiv_1 [PR99777] extract_muldiv{,_1} is apparently only prepared to handle scalar integer operations, the callers ensure it by only calling it if the divisor or one of the multiplicands is INTEGER_CST and because neither multiplication nor division nor modulo are really supported e.g. for pointer types, nullptr type etc. But the CASE_CONVERT handling doesn't really check if it isn't a cast from some other type kind, so on the testcase we end up trying to build MULT_EXPR in POINTER_TYPE which ICEs. A few years ago Marek has added ANY_INTEGRAL_TYPE_P checks to two spots, but the code uses TYPE_PRECISION which means something completely different for vector types, etc. So IMNSHO we should just punt on conversions from non-integrals or non-scalar integrals. 2021-03-29 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/99777 * fold-const.c (extract_muldiv_1): For conversions, punt on casts from types other than scalar integral types. * g++.dg/torture/pr99777.C: New test.
Fixed.
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:afe9a630eae114665e77402ea083201c9d406e99 commit r10-9625-gafe9a630eae114665e77402ea083201c9d406e99 Author: Jakub Jelinek <jakub@redhat.com> Date: Mon Mar 29 12:35:32 2021 +0200 fold-const: Fix ICE in extract_muldiv_1 [PR99777] extract_muldiv{,_1} is apparently only prepared to handle scalar integer operations, the callers ensure it by only calling it if the divisor or one of the multiplicands is INTEGER_CST and because neither multiplication nor division nor modulo are really supported e.g. for pointer types, nullptr type etc. But the CASE_CONVERT handling doesn't really check if it isn't a cast from some other type kind, so on the testcase we end up trying to build MULT_EXPR in POINTER_TYPE which ICEs. A few years ago Marek has added ANY_INTEGRAL_TYPE_P checks to two spots, but the code uses TYPE_PRECISION which means something completely different for vector types, etc. So IMNSHO we should just punt on conversions from non-integrals or non-scalar integrals. 2021-03-29 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/99777 * fold-const.c (extract_muldiv_1): For conversions, punt on casts from types other than scalar integral types. * g++.dg/torture/pr99777.C: New test.
The releases/gcc-9 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:a784483132fd7f3830b96e5a606d8eeb8f64e5ce commit r9-9439-ga784483132fd7f3830b96e5a606d8eeb8f64e5ce Author: Jakub Jelinek <jakub@redhat.com> Date: Mon Mar 29 12:35:32 2021 +0200 fold-const: Fix ICE in extract_muldiv_1 [PR99777] extract_muldiv{,_1} is apparently only prepared to handle scalar integer operations, the callers ensure it by only calling it if the divisor or one of the multiplicands is INTEGER_CST and because neither multiplication nor division nor modulo are really supported e.g. for pointer types, nullptr type etc. But the CASE_CONVERT handling doesn't really check if it isn't a cast from some other type kind, so on the testcase we end up trying to build MULT_EXPR in POINTER_TYPE which ICEs. A few years ago Marek has added ANY_INTEGRAL_TYPE_P checks to two spots, but the code uses TYPE_PRECISION which means something completely different for vector types, etc. So IMNSHO we should just punt on conversions from non-integrals or non-scalar integrals. 2021-03-29 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/99777 * fold-const.c (extract_muldiv_1): For conversions, punt on casts from types other than scalar integral types. * g++.dg/torture/pr99777.C: New test. (cherry picked from commit afe9a630eae114665e77402ea083201c9d406e99)
The releases/gcc-8 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:1ee66d06f25d5bf14e2f3b599fc391dc3d532722 commit r8-10902-g1ee66d06f25d5bf14e2f3b599fc391dc3d532722 Author: Jakub Jelinek <jakub@redhat.com> Date: Mon Mar 29 12:35:32 2021 +0200 fold-const: Fix ICE in extract_muldiv_1 [PR99777] extract_muldiv{,_1} is apparently only prepared to handle scalar integer operations, the callers ensure it by only calling it if the divisor or one of the multiplicands is INTEGER_CST and because neither multiplication nor division nor modulo are really supported e.g. for pointer types, nullptr type etc. But the CASE_CONVERT handling doesn't really check if it isn't a cast from some other type kind, so on the testcase we end up trying to build MULT_EXPR in POINTER_TYPE which ICEs. A few years ago Marek has added ANY_INTEGRAL_TYPE_P checks to two spots, but the code uses TYPE_PRECISION which means something completely different for vector types, etc. So IMNSHO we should just punt on conversions from non-integrals or non-scalar integrals. 2021-03-29 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/99777 * fold-const.c (extract_muldiv_1): For conversions, punt on casts from types other than scalar integral types. * g++.dg/torture/pr99777.C: New test. (cherry picked from commit afe9a630eae114665e77402ea083201c9d406e99)