@@ -1030,10 +1030,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
10301030 return ;
10311031 }
10321032
1033- llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
1034- llvm::StringMap<StringRef> FoundNormalizedTriples;
1035- std::multiset<StringRef> OpenMPTriples;
1036-
10371033 // If the user specified -fopenmp-targets= we create a toolchain for each
10381034 // valid triple. Otherwise, if only --offload-arch= was specified we instead
10391035 // attempt to derive the appropriate toolchains from the arguments.
@@ -1044,82 +1040,77 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
10441040 << OpenMPTargets->getAsString (C.getInputArgs ());
10451041 return ;
10461042 }
1043+
1044+ // Make sure these show up in a deterministic order.
1045+ std::multiset<StringRef> OpenMPTriples;
10471046 for (StringRef T : OpenMPTargets->getValues ())
10481047 OpenMPTriples.insert (T);
1048+
1049+ llvm::StringMap<StringRef> FoundNormalizedTriples;
1050+ for (StringRef T : OpenMPTriples) {
1051+ llvm::Triple TT (ToolChain::getOpenMPTriple (T));
1052+ std::string NormalizedName = TT.normalize ();
1053+
1054+ // Make sure we don't have a duplicate triple.
1055+ auto [TripleIt, Inserted] =
1056+ FoundNormalizedTriples.try_emplace (NormalizedName, T);
1057+ if (!Inserted) {
1058+ Diag (clang::diag::warn_drv_omp_offload_target_duplicate)
1059+ << T << TripleIt->second ;
1060+ continue ;
1061+ }
1062+
1063+ // If the specified target is invalid, emit a diagnostic.
1064+ if (TT.getArch () == llvm::Triple::UnknownArch) {
1065+ Diag (clang::diag::err_drv_invalid_omp_target) << T;
1066+ continue ;
1067+ }
1068+
1069+ auto &TC = getOffloadToolChain (C.getInputArgs (), Action::OFK_OpenMP, TT,
1070+ C.getDefaultToolChain ().getTriple ());
1071+ C.addOffloadDeviceToolChain (&TC, Action::OFK_OpenMP);
1072+ }
10491073 } else if (C.getInputArgs ().hasArg (options::OPT_offload_arch_EQ) &&
10501074 ((!IsHIP && !IsCuda) || UseLLVMOffload)) {
1051- const ToolChain *HostTC = C.getSingleOffloadToolChain <Action::OFK_Host>();
1052- auto AMDTriple = getHIPOffloadTargetTriple (*this , C.getInputArgs ());
1053- auto NVPTXTriple = getNVIDIAOffloadTargetTriple (*this , C.getInputArgs (),
1054- HostTC->getTriple ());
1075+ llvm::Triple AMDTriple (" amdgcn-amd-amdhsa" );
1076+ llvm::Triple NVPTXTriple (" nvptx64-nvidia-cuda" );
10551077
10561078 // Attempt to deduce the offloading triple from the set of architectures.
10571079 // We can only correctly deduce NVPTX / AMDGPU triples currently.
1058- // We need to temporarily create these toolchains so that we can access
1059- // tools for inferring architectures.
1060- llvm::DenseSet<StringRef> Archs;
1061- for (const std::optional<llvm::Triple> &TT : {NVPTXTriple, AMDTriple}) {
1062- if (!TT)
1063- continue ;
1064-
1065- auto &TC =
1066- getOffloadToolChain (C.getInputArgs (), Action::OFK_OpenMP, *TT,
1067- C.getDefaultToolChain ().getTriple ());
1068- for (StringRef Arch :
1069- getOffloadArchs (C, C.getArgs (), Action::OFK_OpenMP, &TC, true ))
1070- Archs.insert (Arch);
1071- }
1080+ for (const llvm::Triple &TT : {AMDTriple, NVPTXTriple}) {
1081+ auto &TC = getOffloadToolChain (C.getInputArgs (), Action::OFK_OpenMP, TT,
1082+ C.getDefaultToolChain ().getTriple ());
1083+
1084+ llvm::DenseSet<StringRef> Archs =
1085+ getOffloadArchs (C, C.getArgs (), Action::OFK_OpenMP, &TC, true );
1086+ llvm::DenseSet<StringRef> ArchsForTarget;
1087+ for (StringRef Arch : Archs) {
1088+ bool IsNVPTX = IsNVIDIAOffloadArch (
1089+ StringToOffloadArch (getProcessorFromTargetID (NVPTXTriple, Arch)));
1090+ bool IsAMDGPU = IsAMDOffloadArch (
1091+ StringToOffloadArch (getProcessorFromTargetID (AMDTriple, Arch)));
1092+ if (!IsNVPTX && !IsAMDGPU && !Arch.equals_insensitive (" native" )) {
1093+ Diag (clang::diag::err_drv_failed_to_deduce_target_from_arch)
1094+ << Arch;
1095+ return ;
1096+ }
10721097
1073- for (StringRef Arch : Archs) {
1074- if (NVPTXTriple && IsNVIDIAOffloadArch (StringToOffloadArch (
1075- getProcessorFromTargetID (*NVPTXTriple, Arch)))) {
1076- DerivedArchs[NVPTXTriple->getTriple ()].insert (Arch);
1077- } else if (AMDTriple &&
1078- IsAMDOffloadArch (StringToOffloadArch (
1079- getProcessorFromTargetID (*AMDTriple, Arch)))) {
1080- DerivedArchs[AMDTriple->getTriple ()].insert (Arch);
1081- } else {
1082- Diag (clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
1083- return ;
1098+ if (TT.isNVPTX () && IsNVPTX)
1099+ ArchsForTarget.insert (Arch);
1100+ else if (TT.isAMDGPU () && IsAMDGPU)
1101+ ArchsForTarget.insert (Arch);
1102+ }
1103+ if (!ArchsForTarget.empty ()) {
1104+ C.addOffloadDeviceToolChain (&TC, Action::OFK_OpenMP);
1105+ KnownArchs[&TC] = ArchsForTarget;
10841106 }
10851107 }
10861108
10871109 // If the set is empty then we failed to find a native architecture.
1088- if (Archs.empty ()) {
1110+ auto TCRange = C.getOffloadToolChains (Action::OFK_OpenMP);
1111+ if (TCRange.first == TCRange.second )
10891112 Diag (clang::diag::err_drv_failed_to_deduce_target_from_arch)
10901113 << " native" ;
1091- return ;
1092- }
1093-
1094- for (const auto &TripleAndArchs : DerivedArchs)
1095- OpenMPTriples.insert (TripleAndArchs.first ());
1096- }
1097-
1098- for (StringRef Val : OpenMPTriples) {
1099- llvm::Triple TT (ToolChain::getOpenMPTriple (Val));
1100- std::string NormalizedName = TT.normalize ();
1101-
1102- // Make sure we don't have a duplicate triple.
1103- auto [TripleIt, Inserted] =
1104- FoundNormalizedTriples.try_emplace (NormalizedName, Val);
1105- if (!Inserted) {
1106- Diag (clang::diag::warn_drv_omp_offload_target_duplicate)
1107- << Val << TripleIt->second ;
1108- continue ;
1109- }
1110-
1111- // If the specified target is invalid, emit a diagnostic.
1112- if (TT.getArch () == llvm::Triple::UnknownArch) {
1113- Diag (clang::diag::err_drv_invalid_omp_target) << Val;
1114- continue ;
1115- }
1116-
1117- auto &TC = getOffloadToolChain (C.getInputArgs (), Action::OFK_OpenMP, TT,
1118- C.getDefaultToolChain ().getTriple ());
1119- C.addOffloadDeviceToolChain (&TC, Action::OFK_OpenMP);
1120- auto It = DerivedArchs.find (TT.getTriple ());
1121- if (It != DerivedArchs.end ())
1122- KnownArchs[&TC] = It->second ;
11231114 }
11241115 } else if (C.getInputArgs ().hasArg (options::OPT_fopenmp_targets_EQ)) {
11251116 Diag (clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
0 commit comments