[clang] [offload-arch] Fix HIP DLL discovery and loading on Windows (PR #194063)

Jacob Lambert via cfe-commits cfe-commits at lists.llvm.org
Fri May 1 12:20:23 PDT 2026


================
@@ -0,0 +1,103 @@
+//===-- OffloadArchTest.cpp - Tests for offload-arch helpers ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include <algorithm>
+#include <string>
+
+// Defined in AMDGPUArchByHIP.cpp (non-static, compiled into this test).
+#ifdef _WIN32
+bool compareVersions(llvm::StringRef A, llvm::StringRef B);
+llvm::SmallVector<std::string, 8> getCandidateBinPaths(llvm::StringRef ExeDir);
+#endif
+
+using namespace llvm;
+
+#ifdef _WIN32
+
+// --- compareVersions ---
+
+TEST(CompareVersions, HigherVersionWins) {
+  EXPECT_TRUE(
+      compareVersions("C:/bin/amdhip64_7.dll", "C:/bin/amdhip64_6.dll"));
+  EXPECT_FALSE(
+      compareVersions("C:/bin/amdhip64_6.dll", "C:/bin/amdhip64_7.dll"));
+}
+
+TEST(CompareVersions, EqualVersionsReturnFalse) {
+  EXPECT_FALSE(compareVersions("C:/a/amdhip64_7.dll", "C:/b/amdhip64_7.dll"));
+}
+
+TEST(CompareVersions, MultiDigitVersions) {
+  EXPECT_TRUE(compareVersions("amdhip64_12.dll", "amdhip64_6.dll"));
+}
+
+TEST(CompareVersions, StableSortPreservesInsertionOrder) {
+  std::vector<std::string> DLLs = {"C:/rocm/bin/amdhip64_7.dll",
+                                   "C:/Windows/System32/amdhip64_7.dll"};
+  llvm::stable_sort(DLLs, compareVersions);
+  EXPECT_EQ(DLLs[0], "C:/rocm/bin/amdhip64_7.dll");
+}
+
+// --- getCandidateBinPaths ---
+
+TEST(CandidateBinPaths, FindsParentBin) {
+  auto Paths = getCandidateBinPaths("C:/root/lib/llvm/bin");
+  bool Found = false;
+  for (const auto &P : Paths)
+    if (StringRef(P).equals_insensitive("C:/root/bin"))
+      Found = true;
+  EXPECT_TRUE(Found);
+}
+
+TEST(CandidateBinPaths, NoDuplicatesWhenExeInBin) {
+  auto Paths = getCandidateBinPaths("C:/root/bin");
+  int Count = 0;
+  for (const auto &P : Paths)
+    if (StringRef(P).equals_insensitive("C:/root/bin"))
+      Count++;
+  EXPECT_EQ(Count, 1);
+}
+
+TEST(CandidateBinPaths, CaseInsensitiveDedup) {
+  // Paths differing only in case should not both appear.
+  auto Paths = getCandidateBinPaths("C:/Root/Lib/Bin");
+  int Count = 0;
+  for (const auto &P : Paths)
+    if (StringRef(P).equals_insensitive("C:/Root/bin"))
+      Count++;
+  EXPECT_LE(Count, 1);
+}
+
+TEST(CandidateBinPaths, StopsWithinBound) {
+  auto Paths = getCandidateBinPaths("C:/a/b/c/d/e/f/g/h");
+  // MaxParentLevels=6 + self = 7 max entries.
+  EXPECT_LE(Paths.size(), 7u);
+}
+
+TEST(CandidateBinPaths, RootInput) {
+  auto Paths = getCandidateBinPaths("C:/");
+  // Should produce at least 1 entry (self) and not crash.
+  EXPECT_GE(Paths.size(), 1u);
+}
+
+TEST(CandidateBinPaths, NonAsciiPath) {
+  // Paths with non-ASCII characters should not crash.
+  auto Paths = getCandidateBinPaths(u8"C:/üser/äpp/bin");
----------------
lamb-j wrote:

In C++20, u8"…" is const char8_t[] and won't implicitly convert to const char* / StringRef, so this won't compile on a C++20 toolchain. LLVM still defaults to C++17, but worth making it future-proof — either drop the u8 prefix (raw bytes are sufficient for what the test exercises) or reinterpret_cast<const char*>(u8"…").

https://github.com/llvm/llvm-project/pull/194063


More information about the cfe-commits mailing list