https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115562
Bug ID: 115562 Summary: RISC-V: ICE because of reused fndecl with target-arch attribute Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: cmuellner at gcc dot gnu.org Target Milestone: --- Minimal (?) reproducer: $ cat foo-copy.c void foo (void); __attribute__((target("arch=+zbb"))) void* memcpy (void *d, const void *, unsigned long) { return d; } __attribute__((target("arch=+zbb"))) void fun0(void) {} __attribute__((target("arch=+zbb"))) void fun1(void) {} __attribute__((target("arch=+zbb"))) void fun2(void) {} __attribute__((target("arch=+zbb"))) void fun3(void) {} __attribute__((target("arch=+zbb"))) void fun4(void) {} __attribute__((target("arch=+zbb"))) void fun5(void) {} __attribute__((target("arch=+zbb"))) void fun6(void) {} __attribute__((target("arch=+zbb"))) void fun7(void) {} __attribute__((target("arch=+zbb"))) void fun8(void) {} __attribute__((target("arch=+zbb"))) void fun9(void) {} __attribute__((target("arch=+zbb"))) void fun10(void) {} __attribute__((target("arch=+zbb"))) void fun11(void) {} __attribute__((target("arch=+zbb"))) void fun12(void) {} This is similar to PR115554, but triggers the assertion in riscv_func_target_put() because when processing `fun12` the fndecl is equal to the previously processed fndecl of `memcpy`. I.e., the assumption that the fndecl pointer can be used as an identifier (or comparable for the hash-table) does not hold. Like PR115554, this bug is part of GCC14 and on the master branch. The ICE looks the same as for PR115554 (the same assertion is triggered). To analyze this issue, I've extended riscv_func_target_put() like this: + if (*target_info_slot) + { + inform (loc, "Hash collision detected:"); + inform (loc, " old function: %qE (%p)", (*target_info_slot)->fn_decl, (*target_info_slot)->fn_decl); + inform (loc, " old attributes: %s", (*target_info_slot)->fn_target_name.c_str()); + inform (loc, " new function: %qE", fn_decl); + inform (loc, " new attributes: %s", fn_target_name.c_str ()); + } + else + { + inform (loc, "Adding target attributes to function:"); + inform (loc, " new function: %qE (%p)", fn_decl, fn_decl); + inform (loc, " new attributes: %s", fn_target_name.c_str ()); + } gcc_assert (!*target_info_slot); Additionally, I've included tree.h and added "location_t loc" as parameter of this function. This gives the following output on the reproducer above: $ /opt/riscv-mainline/bin/riscv64-unknown-linux-gnu-gcc -c foo-copy.c foo-copy.c:5:1: note: Adding target attributes to function: 5 | memcpy (void *d, const void *, unsigned long) | ^~~~~~ foo-copy.c:5:1: note: new function: 'memcpy' (0x7f295879e200) // first appearance foo-copy.c:5:1: note: new attributes: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zaamo1p0_zalrsc1p0_zbb1p0 foo-copy.c:10:43: note: Adding target attributes to function: 10 | __attribute__((target("arch=+zbb"))) void fun0(void) {} | ^~~~ foo-copy.c:10:43: note: new function: 'fun0' (0x7f295879e400) foo-copy.c:10:43: note: new attributes: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zaamo1p0_zalrsc1p0_zbb1p0 [...] foo-copy.c:22:43: note: Adding target attributes to function: 22 | __attribute__((target("arch=+zbb"))) void fun11(void) {} | ^~~~~ foo-copy.c:22:43: note: new function: 'fun11' (0x7f295879ef00) foo-copy.c:22:43: note: new attributes: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zaamo1p0_zalrsc1p0_zbb1p0 foo-copy.c:23:43: note: Hash collision detected: 23 | __attribute__((target("arch=+zbb"))) void fun12(void) {} | ^~~~~ foo-copy.c:23:43: note: old function: 'fun12' (0x7f295879e200) // same address! foo-copy.c:23:43: note: old attributes: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zaamo1p0_zalrsc1p0_zbb1p0 foo-copy.c:23:43: note: new function: 'fun12' foo-copy.c:23:43: note: new attributes: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zaamo1p0_zalrsc1p0_zbb1p0 foo-copy.c:23:1: internal compiler error: in riscv_func_target_put, at common/config/riscv/riscv-common.cc:536 23 | __attribute__((target("arch=+zbb"))) void fun12(void) {} | ^~~~~~~~~~~~~ As can be seen in the example above, fndecl of `memcpy` has the address 0x7f295879e200, which is equal to the address of fndecl of `fun12`. Note that even small adjustments to the source will break the reproducer. Therefore, I could not rename `memcpy` to something different.