Skip to content

Conversation

@heshpdx
Copy link
Contributor

@heshpdx heshpdx commented Nov 20, 2025

This issue was discovered after SPEC CPU integrated #3316. The SPEC copy of vtr_strong_id_range.h is old, so I tried my best to apply the same fixes here, but please test yourself.

From the SPEC release manager:

Our builds were failing with LLVM 21 due to redefinition of iterator operators. Here's one example:

/spec/compilers/llvm-21.1.5/bin/clang++   -std=c++17   -m64 -stdlib=libc++ -c -o vtr-vpr/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.o -DSPEC -DNDEBUG -DSPEC_AUTO_BYTEORDER=0x12345678 -DNO_GRAPHICS -Ivtr-vpr/vpr/src/analysis -Ivtr-vpr/vpr/src/base -Ivtr-vpr/vpr/src/base/gen -Ivtr-vpr/vpr/src/noc -Ivtr-vpr/vpr/src/pack -Ivtr-vpr/vpr/src/place -Ivtr-vpr/vpr/src/power -Ivtr-vpr/vpr/src/route -Ivtr-vpr/vpr/src/timing -Ivtr-vpr/vpr/src/util -Ivtr-vpr/libs/libvtrutil/src -Ivtr-vpr/libs/liblog/src -Ivtr-vpr/libs/libarchfpga/src -Ivtr-vpr/libs/EXTERNAL/libpugixml/src -Ivtr-vpr/libs/libpugiutil/src -Ivtr-vpr/libs/EXTERNAL/libsdcparse/src -Ivtr-vpr/libs/EXTERNAL/libsdcparse -Ivtr-vpr/libs/EXTERNAL/libblifparse/src -Ivtr-vpr/libs/EXTERNAL/libblifparse -Ivtr-vpr/libs/EXTERNAL/libtatum/libtatum -Ivtr-vpr/libs/EXTERNAL/libargparse/src -Ivtr-vpr/libs/librrgraph/src/base -Ivtr-vpr/libs/librrgraph/src/io/gen -Ivtr-vpr/libs/librrgraph/src/io -Ivtr-vpr/libs/librrgraph/src/utils -Igetdelim -Ispecrand -Ispec_include  -g -O3       -fno-fast-math  -DSPEC_LP64 -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES  vtr-vpr/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp
In file included from vtr-vpr/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp:7:
In file included from vtr-vpr/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h:4:
In file included from vtr-vpr/libs/librrgraph/src/base/rr_graph_view.h:4:
In file included from vtr-vpr/libs/librrgraph/src/base/rr_graph_builder.h:16:
In file included from vtr-vpr/libs/librrgraph/src/base/rr_graph_storage.h:21:
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:98:37: error: redefinition of 'operator+'
   98 |     friend StrongIdIterator<IdType> operator+(
      |                                     ^
vtr-vpr/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp:188:34: note: in instantiation of template class 'vtr::StrongIdIterator<vtr::StrongId<rr_node_id_tag, unsigned int>>' requested here
  188 |     for (const RRNodeId& rr_node : rr_graph.nodes()) {
      |                                  ^
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:98:37: note: previous definition is here
   98 |     friend StrongIdIterator<IdType> operator+(
      |                                     ^
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:108:37: error: redefinition of 'operator-'
  108 |     friend StrongIdIterator<IdType> operator-(
      |                                     ^
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:108:37: note: previous definition is here
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:118:20: error: redefinition of 'operator-'
  118 |     friend ssize_t operator-(
      |                    ^
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:118:20: note: previous definition is here
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:131:17: error: redefinition of 'operator=='
  131 |     friend bool operator==(const StrongIdIterator<IdType>& lhs, const StrongIdIterator<IdType>& rhs) {
      |                 ^
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:131:17: note: previous definition is here
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:137:17: error: redefinition of 'operator!='
  137 |     friend bool operator!=(const StrongIdIterator<IdType>& lhs, const StrongIdIterator<IdType>& rhs) {
      |                 ^
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:137:17: note: previous definition is here
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:143:17: error: redefinition of 'operator<'
  143 |     friend bool operator<(const StrongIdIterator<IdType>& lhs, const StrongIdIterator<IdType>& rhs) {
      |                 ^
vtr-vpr/libs/libvtrutil/src/vtr_strong_id_range.h:143:17: note: previous definition is here
6 errors generated.

If you look closely, you'll see that the locations of the original definition as well as the redefinition are the same in all cases. I thought this was kind of cuckoo-bananas but Claude explained to me that it's because each templated instantiation of StrongIdIterator got its own set of operator functions definition that weren't tied to the class type. Or in its own(?) words:

  The real issue is that the friend functions have their own template parameter (IdType) that's independent of the class template parameter (StrongId). So:

  - StrongIdIterator<TypeA> tries to inject template<typename IdType> operator+(...)
  - StrongIdIterator<TypeB> also tries to inject the exact same template<typename IdType> operator+(...)
  - Both are defining the same function template at namespace scope → redefinition error at vtr_strong_id_range.h:98

  By removing template<typename IdType> and using the class parameter instead, each class instantiation gets its own specific operator overload rather than all of them fighting to define the same function template.

To my mild surprise, Claude was right and the suggested changes, which are the changes in this MR, built and ran all workloads with both LLVM 21.1.6 (impossible before) and GCC 15.2.0 (possible before).

…iation gets a different set

Fixes build error with LLVM 21 due to redefinition of iterator operators
@amin1377 amin1377 self-requested a review November 20, 2025 16:57
@heshpdx
Copy link
Contributor Author

heshpdx commented Nov 20, 2025

There is a build error. Maybe the new version of vtr_strong_id_range.h doesn't have this issue, or there is a different issue.

@vaughnbetz
Copy link
Contributor

Adding @AmirhosseinPoolad since he likes C++ tests. The code before the change made sense to me, so this error message seems logical to me.

@heshpdx
Copy link
Contributor Author

heshpdx commented Nov 20, 2025

Here is the SPEC version of the file, and the patch which worked for us. Hope this helps.

@AmirhosseinPoolad
Copy link
Contributor

Just compiled VTR with LLVM21 and it worked without errors. I believe #2461 fixed this issue.

@heshpdx
Copy link
Contributor Author

heshpdx commented Nov 22, 2025

Just compiled VTR with LLVM21 and it worked without errors. I believe #2461 fixed this issue.

Yes it looks like that is a similar fix. Thank you! I will close this PR.

@heshpdx heshpdx closed this Nov 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants