While trying to build the GCC 5 with GCC 5, I ran into an ICE when building libcpp at -O0. The problem is the C++ front-end was not folding sizeof(a)/sizeof(a[0]) when passed to a function at -O0. The C++ front-end keeps around sizeof until the gimplifier and there is no way to fold the expressions that involve them. So to work around the issue we need to change __builtin_aarch64_im_lane_boundsi to accept an extra argument and change the first two arguments to size_t type so we don't get an extra cast there and do the division inside the compiler itself.
Also we don't want to cause an ICE on any source code so I changed the assert to be a sorry if either of the two arguments are not integer constants. OK? Bootstrapped and tested on aarch64-linux-gnu with no regressions and I was able to bootstrap without a modified libcpp. Thanks, Andrew Pinski ChangeLog: * config/aarch64/aarch64-builtins.c (aarch64_init_simd_builtins): Change the first argument type to size_type_node and add another size_type_node. (aarch64_simd_expand_builtin): Handle the new argument to AARCH64_SIMD_BUILTIN_LANE_CHECK and don't ICE but rather print sorry out when the first two arguments are not integer constants. * config/aarch64/arm_neon.h (__AARCH64_LANE_CHECK): Pass the sizeof's directly to __builtin_aarch64_im_lane_boundsi. testsuite/ChangeLog: * c-c++-common/torture/aarch64-vect-lane-1.c: New testcase.
commit 455a54f36a205af281b3fe8dbc97916ede704ca8 Author: Andrew Pinski <apin...@cavium.com> Date: Mon Feb 2 18:40:08 2015 +0000 Fix bug 64893: ICE with vget_lane_u32 with C++ front-end PR target/64893 * config/aarch64/aarch64-builtins.c (aarch64_init_simd_builtins): Change the first argument type to size_type_node and add another size_type_node. (aarch64_simd_expand_builtin): Handle the new argument to AARCH64_SIMD_BUILTIN_LANE_CHECK and don't ICE but rather print sorry out when the first two arguments are not integer constants. * config/aarch64/arm_neon.h (__AARCH64_LANE_CHECK): Pass the sizeof directly to __builtin_aarch64_im_lane_boundsi. * testsuite/c-c++-common/torture/aarch64-vect-lane-1.c: New testcase. diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index 87f1ac2..5bd15d1 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -712,7 +712,8 @@ aarch64_init_simd_builtins (void) aarch64_init_simd_builtin_scalar_types (); tree lane_check_fpr = build_function_type_list (void_type_node, - intSI_type_node, + size_type_node, + size_type_node, intSI_type_node, NULL); aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_LANE_CHECK] = @@ -1001,13 +1002,18 @@ aarch64_simd_expand_builtin (int fcode, tree exp, rtx target) { if (fcode == AARCH64_SIMD_BUILTIN_LANE_CHECK) { - tree nlanes = CALL_EXPR_ARG (exp, 0); - gcc_assert (TREE_CODE (nlanes) == INTEGER_CST); - rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 1)); - if (CONST_INT_P (lane_idx)) - aarch64_simd_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp); + rtx totalsize = expand_normal (CALL_EXPR_ARG (exp, 0)); + rtx elementsize = expand_normal (CALL_EXPR_ARG (exp, 1)); + if (CONST_INT_P (totalsize) && CONST_INT_P (elementsize)) + { + rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 2)); + if (CONST_INT_P (lane_idx)) + aarch64_simd_lane_bounds (lane_idx, 0, UINTVAL (totalsize)/UINTVAL (elementsize), exp); + else + error ("%Klane index must be a constant immediate", exp); + } else - error ("%Klane index must be a constant immediate", exp); + sorry ("%Ktotal size and element size must be a constant immediate", exp); /* Don't generate any RTL. */ return const0_rtx; } diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index d4ce0b8..938a3cc 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -541,7 +541,7 @@ typedef struct poly16x8x4_t #define __AARCH64_NUM_LANES(__v) (sizeof (__v) / sizeof (__v[0])) #define __AARCH64_LANE_CHECK(__vec, __idx) \ - __builtin_aarch64_im_lane_boundsi (__AARCH64_NUM_LANES (__vec), __idx) + __builtin_aarch64_im_lane_boundsi (sizeof(__vec), sizeof(__vec[0]), __idx) /* For big-endian, GCC's vector indices are the opposite way around to the architectural lane indices used by Neon intrinsics. */ diff --git a/gcc/testsuite/c-c++-common/torture/aarch64-vect-lane-1.c b/gcc/testsuite/c-c++-common/torture/aarch64-vect-lane-1.c new file mode 100644 index 0000000..1790c34 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/aarch64-vect-lane-1.c @@ -0,0 +1,8 @@ +// { dg-do compile { target "aarch64*-*-*" } } +#include <arm_neon.h> +int +search_line_fast (uint32x2_t t) +{ + return vget_lane_u32 (t, 0); +} +