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.
  • [Bug target/115562] New: RISC-V:... cmuellner at gcc dot gnu.org via Gcc-bugs

Reply via email to