Summary: | [11/12/13 regression] AVR ICE: verify_gimple failed | ||
---|---|---|---|
Product: | gcc | Reporter: | gandalf |
Component: | target | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | NEW --- | ||
Severity: | normal | CC: | jakub, jsm28, rguenth, saaadhu |
Priority: | P4 | Keywords: | addr-space, ice-on-valid-code |
Version: | 9.0 | ||
Target Milestone: | 11.5 | ||
See Also: | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112830 | ||
Host: | Target: | avr | |
Build: | Known to work: | 14.0 | |
Known to fail: | Last reconfirmed: | 2023-12-04 00:00:00 |
Description
gandalf
2019-02-09 20:10:57 UTC
Not sure, but possibly not returning false here: static bool verify_gimple_assign_unary (gassign *stmt) { .. /* Allow conversions from pointer type to integral type only if there is no sign or zero extension involved. For targets were the precision of ptrofftype doesn't match that of pointers we need to allow arbitrary conversions to ptrofftype. */ if ((POINTER_TYPE_P (lhs_type) && INTEGRAL_TYPE_P (rhs1_type)) || (POINTER_TYPE_P (rhs1_type) && INTEGRAL_TYPE_P (lhs_type) && (TYPE_PRECISION (rhs1_type) >= TYPE_PRECISION (lhs_type) || ptrofftype_p (lhs_type)))) return false; elsewhere I suggested that instead of special-casing ptrofftype_p we need this special case only if POINTERS_EXTEND_UNSIGNED is defined and for Pmode and word_mode lhs_type mode. Not sure how named address-spaces are handled here since POINTERS_EXTEND_UNSIGNED doesn't talk about them. (In reply to gandalf from comment #0) > I get an ICE For the time being, you can work around this by a macro from AVR-LibC or some equivalent inline asm: #include <avr/pgmspace.h> void test() { extern const char __data_load_end[]; __uint24 top = (__uint24) pgm_get_far_address (__data_load_end); } (In reply to Georg-Johann Lay from comment #2) > For the time being, you can work around this by a macro from AVR-LibC or > some equivalent inline asm Thanks, that workaround does indeed work (and with slightly smaller code generated as well). GCC 9.1 has been released. GCC 9.2 has been released. GCC 9.3.0 has been released, adjusting target milestone. GCC 9.4 is being released, retargeting bugs to GCC 9.5. GCC 9 branch is being closed GCC 10.4 is being released, retargeting bugs to GCC 10.5. GCC 10 branch is being closed. *** Bug 91354 has been marked as a duplicate of this bug. *** Confirmed. We have a NOP_EXPR from the 24bit pointer __memx address-space to long int (32bit). That's an extension and we don't know how to do that since POINTERS_EXTEND_UNSIGNED is not defined for AVR. Note that for GIMPLE verification the exception would be #if defined(POINTERS_EXTEND_UNSIGNED) || (TYPE_MODE (rhs1_type) == ptr_mode && (TYPE_PRECISION (lhs_type) == BITS_PER_WORD /* word_mode */ || (TYPE_PRECISION (lhs_type) == GET_MODE_PRECISION (Pmode)))) #endif but that's currently written without address-spaces in mind (because POINTERS_EXTEND_UNSIGNED is defined without address-spaces in mind). I think the "bug" is that the C frontend emits extern const <address-space-7> unsigned char __data_load_end; __uint24 top = (__uint24) (long int) &__data_load_end; so it inserts the widening to 'long int' here. And that's the fault of convert.cc:convert_to_integer_1 which does /* Convert to an unsigned integer of the correct width first, and from there widen/truncate to the required type. Some targets support the coexistence of multiple valid pointer sizes, so fetch the one we need from the type. */ if (!dofold) return build1 (CONVERT_EXPR, type, expr); expr = fold_build1 (CONVERT_EXPR, lang_hooks.types.type_for_size (TYPE_PRECISION (intype), 0), expr); return fold_convert (type, expr); using type_for_mode would have yielded the __int24 type here. The code is more or less present since the original version of convert.c I'd argue the most correct way to deal with this is to _remove_ the intermediate conversion done by convert.c since it only papers over possible user errors? The C standard says the only supported conversion is to/from [u]intptr_t, that's probably what the above tried to do. But then it looks like it doesn't achieve its intent. Now, c_common_type_for_size doesn't handle registered_builtin_types like c_common_type_for_mode does, so extending that to cover these fixes the issue as well. The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:4dd02d62abd76a69f65d9f3fed6febeed53fc90a commit r14-6134-g4dd02d62abd76a69f65d9f3fed6febeed53fc90a Author: Richard Biener <rguenther@suse.de> Date: Mon Dec 4 14:03:37 2023 +0100 c/89270 - honor registered_builtin_types in type_for_size The following fixes the intermediate conversions inserted by convert_to_integer when facing address-spaces and converts to their effective [u]intptr_t when they are registered_builtin_types by considering those also from c_common_type_for_size and not only from c_common_type_for_mode. PR c/89270 gcc/c-family/ * c-common.cc (c_common_type_for_size): Consider registered_builtin_types. gcc/testsuite/ * gcc.target/avr/pr89270.c: New testcase. Fixed on trunk sofar. Joseph correctly mentioned that iff AVR would define __int24 using INT_N in avr-modes.def the issue would have been mitigated as well (that's a comparatively "modern" way of registering additional integer types). So it's really also a target issue. I'm not planning to backport this frontend change given a more targeted fix would be available. |