Hi, PR71778 is an ICE when you pass a non-constant argument to an intrinsic which requires a constant.
This ICE was introduced after we rewrote some of the builtin handling for Neon intrinsics, the issue is that after throwing an error in arm_expand_builtin_args, we return const0_rtx to indicate the expand has failed if (!(*insn_data[icode].operand[opno].predicate) (op[argc], mode[argc])) { error ("%Kargument %d must be a constant immediate", exp, argc + 1); return const0_rtx; } At this point we're safely in to invalid code, but the mid-end continues trying to resolve the assignment, with const0_rtx on the right-hand side. That gets in to trouble in movv2di, which sees the constant and tries to expand through neon_make_constant, which doesn't expect to see a const0_rtx in the assignment (it wants a vector), and we hit a gcc_unreachable () and take the ICE. There are a few moving parts in the back end, so it isn't clear to me that the fix I've come up with is 100% in the right place. AArch64 doesn't bother with a similar construct, expanding straight to a mov with whatever you've given it, so I don't see a right place over there. The change is defensible, but I don't really know the ARM back end. Bootstrapped on arm-none-linux-gnueabihf. OK? Thanks, James --- gcc/ 2017-06-12 James Greenhalgh <james.greenha...@arm.com> PR target/71778 * config/arm/arm.c (neon_make_constant): Return const0_rtx for const0_rtx input. gcc/testsuite/ 2017-06-12 James Greenhalgh <james.greenha...@arm.com> PR target/71778 * gcc.target/arm/pr71778.c: New.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index e503891..b8d59c6 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -12124,6 +12124,11 @@ neon_make_constant (rtx vals) if (n_const == n_elts) const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)); } + else if (vals == const0_rtx) + /* Something invalid, perhaps from expanding an intrinsic + which requires a constant argument, where a variable argument + was passed. */ + return const0_rtx; else gcc_unreachable (); diff --git a/gcc/testsuite/gcc.target/arm/pr71778.c b/gcc/testsuite/gcc.target/arm/pr71778.c new file mode 100644 index 0000000..d5b0d04 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr71778.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-O2" } */ +/* { dg-add-options arm_neon } */ + +typedef __simd128_int32_t int32x4_t; + +__extension__ extern __inline int32x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vshrq_n_s32 (int32x4_t __a, const int __b) +{ + /* Errors for arm_neon.h intrinsics using constants end up on the line + in arm_neon.h rather than the source file line. That means we + need to put the dg-error up here, rather than on line 22 where we'd + like it. */ + return (int32x4_t)__builtin_neon_vshrs_nv4si (__a, __b); /* { dg-error "argument 2 must be a constant immediate" } */ +} + +int32x4_t +shift (int32x4_t a, int b) +{ + return vshrq_n_s32 (a, b); +} +