xref: /llvm-project/clang/unittests/Driver/DXCModeTest.cpp (revision df9a14d7bbf1180e4f1474254c9d7ed6bcb4ce55)
10ac597f3SChris Bieneman //===- unittests/Driver/DXCModeTest.cpp --- DXC Mode tests ----------------===//
20ac597f3SChris Bieneman //
30ac597f3SChris Bieneman // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40ac597f3SChris Bieneman // See https://llvm.org/LICENSE.txt for license information.
50ac597f3SChris Bieneman // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60ac597f3SChris Bieneman //
70ac597f3SChris Bieneman //===----------------------------------------------------------------------===//
80ac597f3SChris Bieneman //
90ac597f3SChris Bieneman // Unit tests for driver DXCMode.
100ac597f3SChris Bieneman //
110ac597f3SChris Bieneman //===----------------------------------------------------------------------===//
120ac597f3SChris Bieneman 
130ac597f3SChris Bieneman #include "clang/Basic/DiagnosticIDs.h"
140ac597f3SChris Bieneman #include "clang/Basic/DiagnosticOptions.h"
150ac597f3SChris Bieneman #include "clang/Basic/LLVM.h"
160ac597f3SChris Bieneman #include "clang/Basic/TargetOptions.h"
170ac597f3SChris Bieneman #include "clang/Driver/Compilation.h"
180ac597f3SChris Bieneman #include "clang/Driver/Driver.h"
190ac597f3SChris Bieneman #include "clang/Driver/ToolChain.h"
200ac597f3SChris Bieneman #include "clang/Frontend/CompilerInstance.h"
210ac597f3SChris Bieneman #include "llvm/Support/VirtualFileSystem.h"
220ac597f3SChris Bieneman #include "llvm/Support/raw_ostream.h"
230ac597f3SChris Bieneman #include "gtest/gtest.h"
240ac597f3SChris Bieneman #include <memory>
250ac597f3SChris Bieneman 
260ac597f3SChris Bieneman #include "SimpleDiagnosticConsumer.h"
270ac597f3SChris Bieneman 
280ac597f3SChris Bieneman using namespace clang;
290ac597f3SChris Bieneman using namespace clang::driver;
300ac597f3SChris Bieneman 
310ac597f3SChris Bieneman static void validateTargetProfile(
320ac597f3SChris Bieneman     StringRef TargetProfile, StringRef ExpectTriple,
330ac597f3SChris Bieneman     IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> &InMemoryFileSystem,
340ac597f3SChris Bieneman     DiagnosticsEngine &Diags) {
350ac597f3SChris Bieneman   Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
360ac597f3SChris Bieneman   std::unique_ptr<Compilation> C{TheDriver.BuildCompilation(
37d5a7439eSXiang Li       {"clang", "--driver-mode=dxc", TargetProfile.data(), "foo.hlsl", "-Vd"})};
380ac597f3SChris Bieneman   EXPECT_TRUE(C);
390ac597f3SChris Bieneman   EXPECT_STREQ(TheDriver.getTargetTriple().c_str(), ExpectTriple.data());
400ac597f3SChris Bieneman   EXPECT_EQ(Diags.getNumErrors(), 0u);
410ac597f3SChris Bieneman }
420ac597f3SChris Bieneman 
430ac597f3SChris Bieneman static void validateTargetProfile(
440ac597f3SChris Bieneman     StringRef TargetProfile, StringRef ExpectError,
450ac597f3SChris Bieneman     IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> &InMemoryFileSystem,
460ac597f3SChris Bieneman     DiagnosticsEngine &Diags, SimpleDiagnosticConsumer *DiagConsumer,
470ac597f3SChris Bieneman     unsigned NumOfErrors) {
480ac597f3SChris Bieneman   Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
490ac597f3SChris Bieneman   std::unique_ptr<Compilation> C{TheDriver.BuildCompilation(
50d5a7439eSXiang Li       {"clang", "--driver-mode=dxc", TargetProfile.data(), "foo.hlsl", "-Vd"})};
510ac597f3SChris Bieneman   EXPECT_TRUE(C);
520ac597f3SChris Bieneman   EXPECT_EQ(Diags.getNumErrors(), NumOfErrors);
530ac597f3SChris Bieneman   EXPECT_STREQ(DiagConsumer->Errors.back().c_str(), ExpectError.data());
540ac597f3SChris Bieneman   DiagConsumer->clear();
550ac597f3SChris Bieneman }
560ac597f3SChris Bieneman 
570ac597f3SChris Bieneman TEST(DxcModeTest, TargetProfileValidation) {
580ac597f3SChris Bieneman   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
590ac597f3SChris Bieneman 
600ac597f3SChris Bieneman   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
610ac597f3SChris Bieneman       new llvm::vfs::InMemoryFileSystem);
620ac597f3SChris Bieneman 
630ac597f3SChris Bieneman   InMemoryFileSystem->addFile("foo.hlsl", 0,
640ac597f3SChris Bieneman                               llvm::MemoryBuffer::getMemBuffer("\n"));
650ac597f3SChris Bieneman 
660ac597f3SChris Bieneman   auto *DiagConsumer = new SimpleDiagnosticConsumer;
670ac597f3SChris Bieneman   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
680ac597f3SChris Bieneman   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
690ac597f3SChris Bieneman 
706d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tvs_6_0", "dxilv1.0--shadermodel6.0-vertex",
710ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
726d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Ths_6_1", "dxilv1.1--shadermodel6.1-hull",
730ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
746d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tds_6_2", "dxilv1.2--shadermodel6.2-domain",
750ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
766d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tds_6_2", "dxilv1.2--shadermodel6.2-domain",
770ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
786d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tgs_6_3", "dxilv1.3--shadermodel6.3-geometry",
790ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
806d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tps_6_4", "dxilv1.4--shadermodel6.4-pixel",
810ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
826d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tcs_6_5", "dxilv1.5--shadermodel6.5-compute",
830ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
846d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tms_6_6", "dxilv1.6--shadermodel6.6-mesh",
850ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
866d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tas_6_7", "dxilv1.7--shadermodel6.7-amplification",
870ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
886d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tcs_6_8", "dxilv1.8--shadermodel6.8-compute",
896d890148SS. Bharadwaj Yadavalli                         InMemoryFileSystem, Diags);
906d890148SS. Bharadwaj Yadavalli   validateTargetProfile("-Tlib_6_x", "dxilv1.8--shadermodel6.15-library",
910ac597f3SChris Bieneman                         InMemoryFileSystem, Diags);
920ac597f3SChris Bieneman 
930ac597f3SChris Bieneman   // Invalid tests.
940ac597f3SChris Bieneman   validateTargetProfile("-Tpss_6_1", "invalid profile : pss_6_1",
950ac597f3SChris Bieneman                         InMemoryFileSystem, Diags, DiagConsumer, 1);
960ac597f3SChris Bieneman 
970ac597f3SChris Bieneman   validateTargetProfile("-Tps_6_x", "invalid profile : ps_6_x",
980ac597f3SChris Bieneman                         InMemoryFileSystem, Diags, DiagConsumer, 2);
990ac597f3SChris Bieneman   validateTargetProfile("-Tlib_6_1", "invalid profile : lib_6_1",
1000ac597f3SChris Bieneman                         InMemoryFileSystem, Diags, DiagConsumer, 3);
1010ac597f3SChris Bieneman   validateTargetProfile("-Tfoo", "invalid profile : foo", InMemoryFileSystem,
1020ac597f3SChris Bieneman                         Diags, DiagConsumer, 4);
1030ac597f3SChris Bieneman   validateTargetProfile("", "target profile option (-T) is missing",
1040ac597f3SChris Bieneman                         InMemoryFileSystem, Diags, DiagConsumer, 5);
1050ac597f3SChris Bieneman }
1060ac597f3SChris Bieneman 
1070ac597f3SChris Bieneman TEST(DxcModeTest, ValidatorVersionValidation) {
1080ac597f3SChris Bieneman   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
1090ac597f3SChris Bieneman 
1100ac597f3SChris Bieneman   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
1110ac597f3SChris Bieneman       new llvm::vfs::InMemoryFileSystem);
1120ac597f3SChris Bieneman 
1130ac597f3SChris Bieneman   InMemoryFileSystem->addFile("foo.hlsl", 0,
1140ac597f3SChris Bieneman                               llvm::MemoryBuffer::getMemBuffer("\n"));
1150ac597f3SChris Bieneman 
1160ac597f3SChris Bieneman   auto *DiagConsumer = new SimpleDiagnosticConsumer;
1170ac597f3SChris Bieneman   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
1180ac597f3SChris Bieneman   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
1190ac597f3SChris Bieneman   Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
1200ac597f3SChris Bieneman   std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
1210ac597f3SChris Bieneman       {"clang", "--driver-mode=dxc", "-Tlib_6_7", "foo.hlsl"}));
1220ac597f3SChris Bieneman   EXPECT_TRUE(C);
1230ac597f3SChris Bieneman   EXPECT_TRUE(!C->containsError());
1240ac597f3SChris Bieneman 
1250ac597f3SChris Bieneman   auto &TC = C->getDefaultToolChain();
1260ac597f3SChris Bieneman   bool ContainsError = false;
1270ac597f3SChris Bieneman   auto Args = TheDriver.ParseArgStrings({"-validator-version", "1.1"}, false,
1280ac597f3SChris Bieneman                                         ContainsError);
1290ac597f3SChris Bieneman   EXPECT_FALSE(ContainsError);
1300ac597f3SChris Bieneman   auto DAL = std::make_unique<llvm::opt::DerivedArgList>(Args);
1310ac597f3SChris Bieneman   for (auto *A : Args)
1320ac597f3SChris Bieneman     DAL->append(A);
1330ac597f3SChris Bieneman 
1340ac597f3SChris Bieneman   std::unique_ptr<llvm::opt::DerivedArgList> TranslatedArgs{
1350ac597f3SChris Bieneman       TC.TranslateArgs(*DAL, "0", Action::OffloadKind::OFK_None)};
1360ac597f3SChris Bieneman   EXPECT_NE(TranslatedArgs, nullptr);
1370ac597f3SChris Bieneman   if (TranslatedArgs) {
1380ac597f3SChris Bieneman     auto *A = TranslatedArgs->getLastArg(
1390ac597f3SChris Bieneman         clang::driver::options::OPT_dxil_validator_version);
1400ac597f3SChris Bieneman     EXPECT_NE(A, nullptr);
141c8a23ec0SMichael Platings     if (A) {
1420ac597f3SChris Bieneman       EXPECT_STREQ(A->getValue(), "1.1");
1430ac597f3SChris Bieneman     }
144c8a23ec0SMichael Platings   }
1450ac597f3SChris Bieneman   EXPECT_EQ(Diags.getNumErrors(), 0u);
1460ac597f3SChris Bieneman 
1470ac597f3SChris Bieneman   // Invalid tests.
1480ac597f3SChris Bieneman   Args = TheDriver.ParseArgStrings({"-validator-version", "0.1"}, false,
1490ac597f3SChris Bieneman                                    ContainsError);
1500ac597f3SChris Bieneman   EXPECT_FALSE(ContainsError);
1510ac597f3SChris Bieneman   DAL = std::make_unique<llvm::opt::DerivedArgList>(Args);
1520ac597f3SChris Bieneman   for (auto *A : Args)
1530ac597f3SChris Bieneman     DAL->append(A);
1540ac597f3SChris Bieneman 
1550ac597f3SChris Bieneman   TranslatedArgs.reset(
1560ac597f3SChris Bieneman       TC.TranslateArgs(*DAL, "0", Action::OffloadKind::OFK_None));
1570ac597f3SChris Bieneman   EXPECT_EQ(Diags.getNumErrors(), 1u);
158b49ce9c3SAaron Ballman   EXPECT_STREQ(
159b49ce9c3SAaron Ballman       DiagConsumer->Errors.back().c_str(),
16010be6c96SAaron Ballman       "invalid validator version : 0.1; if validator major version is 0, "
161b49ce9c3SAaron Ballman       "minor version must also be 0");
1620ac597f3SChris Bieneman   DiagConsumer->clear();
1630ac597f3SChris Bieneman 
1640ac597f3SChris Bieneman   Args = TheDriver.ParseArgStrings({"-validator-version", "1"}, false,
1650ac597f3SChris Bieneman                                    ContainsError);
1660ac597f3SChris Bieneman   EXPECT_FALSE(ContainsError);
1670ac597f3SChris Bieneman   DAL = std::make_unique<llvm::opt::DerivedArgList>(Args);
1680ac597f3SChris Bieneman   for (auto *A : Args)
1690ac597f3SChris Bieneman     DAL->append(A);
1700ac597f3SChris Bieneman 
1710ac597f3SChris Bieneman   TranslatedArgs.reset(
1720ac597f3SChris Bieneman       TC.TranslateArgs(*DAL, "0", Action::OffloadKind::OFK_None));
1730ac597f3SChris Bieneman   EXPECT_EQ(Diags.getNumErrors(), 2u);
1740ac597f3SChris Bieneman   EXPECT_STREQ(DiagConsumer->Errors.back().c_str(),
175b49ce9c3SAaron Ballman                "invalid validator version : 1; format of validator version is "
176b49ce9c3SAaron Ballman                "\"<major>.<minor>\" (ex:\"1.4\")");
1770ac597f3SChris Bieneman   DiagConsumer->clear();
1780ac597f3SChris Bieneman 
1790ac597f3SChris Bieneman   Args = TheDriver.ParseArgStrings({"-validator-version", "-Tlib_6_7"}, false,
1800ac597f3SChris Bieneman                                    ContainsError);
1810ac597f3SChris Bieneman   EXPECT_FALSE(ContainsError);
1820ac597f3SChris Bieneman   DAL = std::make_unique<llvm::opt::DerivedArgList>(Args);
1830ac597f3SChris Bieneman   for (auto *A : Args)
1840ac597f3SChris Bieneman     DAL->append(A);
1850ac597f3SChris Bieneman 
1860ac597f3SChris Bieneman   TranslatedArgs.reset(
1870ac597f3SChris Bieneman       TC.TranslateArgs(*DAL, "0", Action::OffloadKind::OFK_None));
1880ac597f3SChris Bieneman   EXPECT_EQ(Diags.getNumErrors(), 3u);
1890ac597f3SChris Bieneman   EXPECT_STREQ(
1900ac597f3SChris Bieneman       DiagConsumer->Errors.back().c_str(),
191b49ce9c3SAaron Ballman       "invalid validator version : -Tlib_6_7; format of validator version is "
192b49ce9c3SAaron Ballman       "\"<major>.<minor>\" (ex:\"1.4\")");
1930ac597f3SChris Bieneman   DiagConsumer->clear();
1940ac597f3SChris Bieneman 
1950ac597f3SChris Bieneman   Args = TheDriver.ParseArgStrings({"-validator-version", "foo"}, false,
1960ac597f3SChris Bieneman                                    ContainsError);
1970ac597f3SChris Bieneman   EXPECT_FALSE(ContainsError);
1980ac597f3SChris Bieneman   DAL = std::make_unique<llvm::opt::DerivedArgList>(Args);
1990ac597f3SChris Bieneman   for (auto *A : Args)
2000ac597f3SChris Bieneman     DAL->append(A);
2010ac597f3SChris Bieneman 
2020ac597f3SChris Bieneman   TranslatedArgs.reset(
2030ac597f3SChris Bieneman       TC.TranslateArgs(*DAL, "0", Action::OffloadKind::OFK_None));
2040ac597f3SChris Bieneman   EXPECT_EQ(Diags.getNumErrors(), 4u);
2050ac597f3SChris Bieneman   EXPECT_STREQ(
2060ac597f3SChris Bieneman       DiagConsumer->Errors.back().c_str(),
207b49ce9c3SAaron Ballman       "invalid validator version : foo; format of validator version is "
208b49ce9c3SAaron Ballman       "\"<major>.<minor>\" (ex:\"1.4\")");
2090ac597f3SChris Bieneman   DiagConsumer->clear();
2100ac597f3SChris Bieneman }
2110ac597f3SChris Bieneman 
2120ac597f3SChris Bieneman TEST(DxcModeTest, DefaultEntry) {
2130ac597f3SChris Bieneman   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
2140ac597f3SChris Bieneman       new llvm::vfs::InMemoryFileSystem);
2150ac597f3SChris Bieneman 
2160ac597f3SChris Bieneman   InMemoryFileSystem->addFile("foo.hlsl", 0,
2170ac597f3SChris Bieneman                               llvm::MemoryBuffer::getMemBuffer("\n"));
2180ac597f3SChris Bieneman 
2190ac597f3SChris Bieneman   const char *Args[] = {"clang", "--driver-mode=dxc", "-Tcs_6_7", "foo.hlsl"};
2200ac597f3SChris Bieneman 
2210ac597f3SChris Bieneman   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
222*df9a14d7SKadir Cetinkaya       CompilerInstance::createDiagnostics(*InMemoryFileSystem,
223*df9a14d7SKadir Cetinkaya                                           new DiagnosticOptions());
2240ac597f3SChris Bieneman 
2250ac597f3SChris Bieneman   CreateInvocationOptions CIOpts;
2260ac597f3SChris Bieneman   CIOpts.Diags = Diags;
2270ac597f3SChris Bieneman   std::unique_ptr<CompilerInvocation> CInvok =
2280ac597f3SChris Bieneman       createInvocation(Args, std::move(CIOpts));
2290ac597f3SChris Bieneman   EXPECT_TRUE(CInvok);
2300ac597f3SChris Bieneman   // Make sure default entry is "main".
2310ac597f3SChris Bieneman   EXPECT_STREQ(CInvok->getTargetOpts().HLSLEntry.c_str(), "main");
2320ac597f3SChris Bieneman 
2330ac597f3SChris Bieneman   const char *EntryArgs[] = {"clang", "--driver-mode=dxc", "-Ebar", "-Tcs_6_7",
2340ac597f3SChris Bieneman                              "foo.hlsl"};
2350ac597f3SChris Bieneman   CInvok = createInvocation(EntryArgs, std::move(CIOpts));
2360ac597f3SChris Bieneman   EXPECT_TRUE(CInvok);
2370ac597f3SChris Bieneman   // Make sure "-E" will set entry.
2380ac597f3SChris Bieneman   EXPECT_STREQ(CInvok->getTargetOpts().HLSLEntry.c_str(), "bar");
2390ac597f3SChris Bieneman }
240