LinkerTest.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // LinkerTest.cpp //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // //
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include <memory>
  11. #include <vector>
  12. #include <string>
  13. #include "llvm/ADT/ArrayRef.h"
  14. #include "CompilationResult.h"
  15. #include "HLSLTestData.h"
  16. #include "llvm/Support/ManagedStatic.h"
  17. #include <fstream>
  18. #include "WexTestClass.h"
  19. #include "HlslTestUtils.h"
  20. #include "dxc/dxcapi.h"
  21. #include "DxcTestUtils.h"
  22. using namespace std;
  23. using namespace hlsl;
  24. using namespace llvm;
  25. // The test fixture.
  26. class LinkerTest
  27. {
  28. public:
  29. BEGIN_TEST_CLASS(LinkerTest)
  30. TEST_CLASS_PROPERTY(L"Parallel", L"true")
  31. TEST_METHOD_PROPERTY(L"Priority", L"0")
  32. END_TEST_CLASS()
  33. TEST_CLASS_SETUP(InitSupport);
  34. TEST_METHOD(RunLinkResource);
  35. TEST_METHOD(RunLinkAllProfiles);
  36. TEST_METHOD(RunLinkFailNoDefine);
  37. TEST_METHOD(RunLinkFailReDefine);
  38. TEST_METHOD(RunLinkGlobalInit);
  39. TEST_METHOD(RunLinkNoAlloca);
  40. TEST_METHOD(RunLinkResRet);
  41. TEST_METHOD(RunLinkToLib);
  42. TEST_METHOD(RunLinkToLibExport);
  43. TEST_METHOD(RunLinkFailReDefineGlobal);
  44. TEST_METHOD(RunLinkFailProfileMismatch);
  45. TEST_METHOD(RunLinkFailEntryNoProps);
  46. TEST_METHOD(RunLinkFailSelectRes);
  47. TEST_METHOD(RunLinkToLibWithUnresolvedFunctions);
  48. TEST_METHOD(RunLinkToLibWithUnresolvedFunctionsExports);
  49. TEST_METHOD(RunLinkToLibWithExportNamesSwapped);
  50. TEST_METHOD(RunLinkToLibWithExportCollision);
  51. TEST_METHOD(RunLinkToLibWithUnusedExport);
  52. TEST_METHOD(RunLinkToLibWithNoExports);
  53. TEST_METHOD(RunLinkWithPotentialIntrinsicNameCollisions);
  54. dxc::DxcDllSupport m_dllSupport;
  55. VersionSupportInfo m_ver;
  56. void CreateLinker(IDxcLinker **pResultLinker) {
  57. VERIFY_SUCCEEDED(
  58. m_dllSupport.CreateInstance(CLSID_DxcLinker, pResultLinker));
  59. }
  60. void CompileLib(LPCWSTR filename, IDxcBlob **pResultBlob, LPCWSTR *pArguments,
  61. UINT32 argCount) {
  62. std::wstring fullPath = hlsl_test::GetPathToHlslDataFile(filename);
  63. CComPtr<IDxcBlobEncoding> pSource;
  64. CComPtr<IDxcLibrary> pLibrary;
  65. VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary));
  66. VERIFY_SUCCEEDED(
  67. pLibrary->CreateBlobFromFile(fullPath.c_str(), nullptr, &pSource));
  68. CComPtr<IDxcCompiler> pCompiler;
  69. CComPtr<IDxcOperationResult> pResult;
  70. CComPtr<IDxcBlob> pProgram;
  71. CA2W shWide("lib_6_1", CP_UTF8);
  72. VERIFY_SUCCEEDED(
  73. m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
  74. VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"", shWide,
  75. pArguments, argCount, nullptr, 0,
  76. nullptr, &pResult));
  77. VERIFY_SUCCEEDED(pResult->GetResult(pResultBlob));
  78. }
  79. void CompileLib(LPCWSTR filename, IDxcBlob **pResourceBlob) {
  80. CompileLib(filename, pResourceBlob, nullptr, 0);
  81. }
  82. void RegisterDxcModule(LPCWSTR pLibName, IDxcBlob *pBlob,
  83. IDxcLinker *pLinker) {
  84. VERIFY_SUCCEEDED(pLinker->RegisterLibrary(pLibName, pBlob));
  85. }
  86. void Link(LPCWSTR pEntryName, LPCWSTR pShaderModel, IDxcLinker *pLinker,
  87. ArrayRef<LPCWSTR> libNames, llvm::ArrayRef<LPCSTR> pCheckMsgs,
  88. llvm::ArrayRef<LPCSTR> pCheckNotMsgs,
  89. llvm::ArrayRef<LPCWSTR> pArguments = {}) {
  90. CComPtr<IDxcOperationResult> pResult;
  91. VERIFY_SUCCEEDED(pLinker->Link(pEntryName, pShaderModel, libNames.data(),
  92. libNames.size(),
  93. pArguments.data(), pArguments.size(),
  94. &pResult));
  95. CComPtr<IDxcBlob> pProgram;
  96. CheckOperationSucceeded(pResult, &pProgram);
  97. CComPtr<IDxcCompiler> pCompiler;
  98. CComPtr<IDxcBlobEncoding> pDisassembly;
  99. VERIFY_SUCCEEDED(
  100. m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
  101. VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgram, &pDisassembly));
  102. std::string IR = BlobToUtf8(pDisassembly);
  103. CheckMsgs(IR.c_str(), IR.size(), pCheckMsgs.data(), pCheckMsgs.size(), false);
  104. CheckNotMsgs(IR.c_str(), IR.size(), pCheckNotMsgs.data(), pCheckNotMsgs.size(), false);
  105. }
  106. void LinkCheckMsg(LPCWSTR pEntryName, LPCWSTR pShaderModel, IDxcLinker *pLinker,
  107. ArrayRef<LPCWSTR> libNames, llvm::ArrayRef<LPCSTR> pErrorMsgs,
  108. llvm::ArrayRef<LPCWSTR> pArguments = {}) {
  109. CComPtr<IDxcOperationResult> pResult;
  110. VERIFY_SUCCEEDED(pLinker->Link(pEntryName, pShaderModel,
  111. libNames.data(), libNames.size(),
  112. pArguments.data(), pArguments.size(),
  113. &pResult));
  114. CheckOperationResultMsgs(pResult, pErrorMsgs.data(), pErrorMsgs.size(),
  115. false, false);
  116. }
  117. };
  118. bool LinkerTest::InitSupport() {
  119. if (!m_dllSupport.IsEnabled()) {
  120. VERIFY_SUCCEEDED(m_dllSupport.Initialize());
  121. m_ver.Initialize(m_dllSupport);
  122. }
  123. return true;
  124. }
  125. TEST_F(LinkerTest, RunLinkResource) {
  126. CComPtr<IDxcBlob> pResLib;
  127. CompileLib(L"..\\CodeGenHLSL\\lib_resource2.hlsl", &pResLib);
  128. CComPtr<IDxcBlob> pEntryLib;
  129. CompileLib(L"..\\CodeGenHLSL\\lib_cs_entry.hlsl", &pEntryLib);
  130. CComPtr<IDxcLinker> pLinker;
  131. CreateLinker(&pLinker);
  132. LPCWSTR libName = L"entry";
  133. RegisterDxcModule(libName, pEntryLib, pLinker);
  134. LPCWSTR libResName = L"res";
  135. RegisterDxcModule(libResName, pResLib, pLinker);
  136. Link(L"entry", L"cs_6_0", pLinker, {libResName, libName}, {} ,{});
  137. }
  138. TEST_F(LinkerTest, RunLinkAllProfiles) {
  139. CComPtr<IDxcLinker> pLinker;
  140. CreateLinker(&pLinker);
  141. LPCWSTR libName = L"entry";
  142. LPCWSTR option[] = { L"-Zi" };
  143. CComPtr<IDxcBlob> pEntryLib;
  144. CompileLib(L"..\\CodeGenHLSL\\lib_entries2.hlsl", &pEntryLib, option, 1);
  145. RegisterDxcModule(libName, pEntryLib, pLinker);
  146. Link(L"vs_main", L"vs_6_0", pLinker, {libName}, {},{});
  147. Link(L"hs_main", L"hs_6_0", pLinker, {libName}, {},{});
  148. Link(L"ds_main", L"ds_6_0", pLinker, {libName}, {},{});
  149. Link(L"gs_main", L"gs_6_0", pLinker, {libName}, {},{});
  150. Link(L"ps_main", L"ps_6_0", pLinker, {libName}, {},{});
  151. CComPtr<IDxcBlob> pResLib;
  152. CompileLib(L"..\\CodeGenHLSL\\lib_resource2.hlsl", &pResLib);
  153. LPCWSTR libResName = L"res";
  154. RegisterDxcModule(libResName, pResLib, pLinker);
  155. Link(L"cs_main", L"cs_6_0", pLinker, {libName, libResName}, {},{});
  156. }
  157. TEST_F(LinkerTest, RunLinkFailNoDefine) {
  158. CComPtr<IDxcBlob> pEntryLib;
  159. CompileLib(L"..\\CodeGenHLSL\\lib_cs_entry.hlsl", &pEntryLib);
  160. CComPtr<IDxcLinker> pLinker;
  161. CreateLinker(&pLinker);
  162. LPCWSTR libName = L"entry";
  163. RegisterDxcModule(libName, pEntryLib, pLinker);
  164. LinkCheckMsg(L"entry", L"cs_6_0", pLinker, {libName},
  165. {"Cannot find definition of function"});
  166. }
  167. TEST_F(LinkerTest, RunLinkFailReDefine) {
  168. CComPtr<IDxcBlob> pEntryLib;
  169. CompileLib(L"..\\CodeGenHLSL\\lib_cs_entry.hlsl", &pEntryLib);
  170. CComPtr<IDxcLinker> pLinker;
  171. CreateLinker(&pLinker);
  172. LPCWSTR libName = L"entry";
  173. RegisterDxcModule(libName, pEntryLib, pLinker);
  174. LPCWSTR libName2 = L"entry2";
  175. RegisterDxcModule(libName2, pEntryLib, pLinker);
  176. LinkCheckMsg(L"entry", L"cs_6_0", pLinker, {libName, libName2},
  177. {"Definition already exists for function"});
  178. }
  179. TEST_F(LinkerTest, RunLinkGlobalInit) {
  180. CComPtr<IDxcBlob> pEntryLib;
  181. CompileLib(L"..\\CodeGenHLSL\\lib_global.hlsl", &pEntryLib);
  182. CComPtr<IDxcLinker> pLinker;
  183. CreateLinker(&pLinker);
  184. LPCWSTR libName = L"entry";
  185. RegisterDxcModule(libName, pEntryLib, pLinker);
  186. Link(L"test", L"ps_6_0", pLinker, {libName},
  187. // Make sure cbuffer load is generated.
  188. {"dx.op.cbufferLoad"},{});
  189. }
  190. TEST_F(LinkerTest, RunLinkFailReDefineGlobal) {
  191. CComPtr<IDxcBlob> pEntryLib;
  192. CompileLib(L"..\\CodeGenHLSL\\lib_global2.hlsl", &pEntryLib);
  193. CComPtr<IDxcBlob> pLib0;
  194. CompileLib(L"..\\CodeGenHLSL\\lib_global3.hlsl", &pLib0);
  195. CComPtr<IDxcBlob> pLib1;
  196. CompileLib(L"..\\CodeGenHLSL\\lib_global4.hlsl", &pLib1);
  197. CComPtr<IDxcLinker> pLinker;
  198. CreateLinker(&pLinker);
  199. LPCWSTR libName = L"entry";
  200. RegisterDxcModule(libName, pEntryLib, pLinker);
  201. LPCWSTR libName1 = L"lib0";
  202. RegisterDxcModule(libName1, pLib0, pLinker);
  203. LPCWSTR libName2 = L"lib1";
  204. RegisterDxcModule(libName2, pLib1, pLinker);
  205. LinkCheckMsg(L"entry", L"cs_6_0", pLinker, {libName, libName1, libName2},
  206. {"Definition already exists for global variable", "Resource already exists"});
  207. }
  208. TEST_F(LinkerTest, RunLinkFailProfileMismatch) {
  209. CComPtr<IDxcBlob> pEntryLib;
  210. CompileLib(L"..\\CodeGenHLSL\\lib_global.hlsl", &pEntryLib);
  211. CComPtr<IDxcLinker> pLinker;
  212. CreateLinker(&pLinker);
  213. LPCWSTR libName = L"entry";
  214. RegisterDxcModule(libName, pEntryLib, pLinker);
  215. LinkCheckMsg(L"test", L"cs_6_0", pLinker, {libName},
  216. {"Profile mismatch between entry function and target profile"});
  217. }
  218. TEST_F(LinkerTest, RunLinkFailEntryNoProps) {
  219. CComPtr<IDxcBlob> pEntryLib;
  220. CompileLib(L"..\\CodeGenHLSL\\lib_global.hlsl", &pEntryLib);
  221. CComPtr<IDxcLinker> pLinker;
  222. CreateLinker(&pLinker);
  223. LPCWSTR libName = L"entry";
  224. RegisterDxcModule(libName, pEntryLib, pLinker);
  225. LinkCheckMsg(L"\01?update@@YAXXZ", L"cs_6_0", pLinker, {libName},
  226. {"Cannot find function property for entry function"});
  227. }
  228. TEST_F(LinkerTest, RunLinkNoAlloca) {
  229. CComPtr<IDxcBlob> pEntryLib;
  230. CompileLib(L"..\\CodeGenHLSL\\lib_no_alloca.hlsl", &pEntryLib);
  231. CComPtr<IDxcBlob> pLib;
  232. CompileLib(L"..\\CodeGenHLSL\\lib_no_alloca.h", &pLib);
  233. CComPtr<IDxcLinker> pLinker;
  234. CreateLinker(&pLinker);
  235. LPCWSTR libName = L"ps_main";
  236. RegisterDxcModule(libName, pEntryLib, pLinker);
  237. LPCWSTR libName2 = L"test";
  238. RegisterDxcModule(libName2, pLib, pLinker);
  239. Link(L"ps_main", L"ps_6_0", pLinker, {libName, libName2}, {}, {"alloca"});
  240. }
  241. TEST_F(LinkerTest, RunLinkResRet) {
  242. CComPtr<IDxcBlob> pEntryLib;
  243. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_out_param_res.hlsl", &pEntryLib);
  244. CComPtr<IDxcBlob> pLib;
  245. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_out_param_res_imp.hlsl", &pLib);
  246. CComPtr<IDxcLinker> pLinker;
  247. CreateLinker(&pLinker);
  248. LPCWSTR libName = L"ps_main";
  249. RegisterDxcModule(libName, pEntryLib, pLinker);
  250. LPCWSTR libName2 = L"test";
  251. RegisterDxcModule(libName2, pLib, pLinker);
  252. Link(L"test", L"ps_6_0", pLinker, {libName, libName2}, {}, {"alloca"});
  253. }
  254. TEST_F(LinkerTest, RunLinkToLib) {
  255. LPCWSTR option[] = {L"-Zi"};
  256. CComPtr<IDxcBlob> pEntryLib;
  257. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_out_param_res.hlsl",
  258. &pEntryLib, option, 1);
  259. CComPtr<IDxcBlob> pLib;
  260. CompileLib(
  261. L"..\\CodeGenHLSL\\shader-compat-suite\\lib_out_param_res_imp.hlsl",
  262. &pLib, option, 1);
  263. CComPtr<IDxcLinker> pLinker;
  264. CreateLinker(&pLinker);
  265. LPCWSTR libName = L"ps_main";
  266. RegisterDxcModule(libName, pEntryLib, pLinker);
  267. LPCWSTR libName2 = L"test";
  268. RegisterDxcModule(libName2, pLib, pLinker);
  269. Link(L"", L"lib_6_2", pLinker, {libName, libName2}, {"!llvm.dbg.cu"}, {});
  270. }
  271. TEST_F(LinkerTest, RunLinkToLibExport) {
  272. CComPtr<IDxcBlob> pEntryLib;
  273. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_out_param_res.hlsl",
  274. &pEntryLib);
  275. CComPtr<IDxcBlob> pLib;
  276. CompileLib(
  277. L"..\\CodeGenHLSL\\shader-compat-suite\\lib_out_param_res_imp.hlsl",
  278. &pLib);
  279. CComPtr<IDxcLinker> pLinker;
  280. CreateLinker(&pLinker);
  281. LPCWSTR libName = L"ps_main";
  282. RegisterDxcModule(libName, pEntryLib, pLinker);
  283. LPCWSTR libName2 = L"test";
  284. RegisterDxcModule(libName2, pLib, pLinker);
  285. Link(L"", L"lib_6_3", pLinker, {libName, libName2},
  286. { "@\"\\01?renamed_test@@","@\"\\01?cloned_test@@","@test" },
  287. { "@\"\\01?GetBuf", "@renamed_test", "@cloned_test" },
  288. {L"-exports", L"renamed_test,cloned_test=\\01?test@@YA?AV?$vector@M$03@@I@Z;test"});
  289. }
  290. TEST_F(LinkerTest, RunLinkFailSelectRes) {
  291. if (m_ver.SkipDxilVersion(1, 3)) return;
  292. CComPtr<IDxcBlob> pEntryLib;
  293. CompileLib(L"..\\CodeGenHLSL\\lib_select_res_entry.hlsl", &pEntryLib);
  294. CComPtr<IDxcBlob> pLib;
  295. CompileLib(L"..\\CodeGenHLSL\\lib_select_res.hlsl", &pLib);
  296. CComPtr<IDxcLinker> pLinker;
  297. CreateLinker(&pLinker);
  298. LPCWSTR libName = L"main";
  299. RegisterDxcModule(libName, pEntryLib, pLinker);
  300. LPCWSTR libName2 = L"test";
  301. RegisterDxcModule(libName2, pLib, pLinker);
  302. LinkCheckMsg(L"main", L"ps_6_0", pLinker, {libName, libName2},
  303. {"Local resource must map to global resource"});
  304. }
  305. TEST_F(LinkerTest, RunLinkToLibWithUnresolvedFunctions) {
  306. LPCWSTR option[] = { L"-Zi" };
  307. CComPtr<IDxcBlob> pLib1;
  308. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func1.hlsl",
  309. &pLib1, option, 1);
  310. CComPtr<IDxcBlob> pLib2;
  311. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func2.hlsl",
  312. &pLib2, option, 1);
  313. CComPtr<IDxcLinker> pLinker;
  314. CreateLinker(&pLinker);
  315. LPCWSTR libName1 = L"lib1";
  316. RegisterDxcModule(libName1, pLib1, pLinker);
  317. LPCWSTR libName2 = L"lib2";
  318. RegisterDxcModule(libName2, pLib2, pLinker);
  319. Link(L"", L"lib_6_2", pLinker, { libName1, libName2 }, {
  320. "declare float @\"\\01?external_fn1@@YAMXZ\"()",
  321. "declare float @\"\\01?external_fn2@@YAMXZ\"()",
  322. "declare float @\"\\01?external_fn@@YAMXZ\"()",
  323. "define float @\"\\01?lib1_fn@@YAMXZ\"()",
  324. "define float @\"\\01?lib2_fn@@YAMXZ\"()",
  325. "define float @\"\\01?call_lib1@@YAMXZ\"()",
  326. "define float @\"\\01?call_lib2@@YAMXZ\"()"
  327. }, {"declare float @\"\\01?unused_fn1", "declare float @\"\\01?unused_fn2"});
  328. }
  329. TEST_F(LinkerTest, RunLinkToLibWithUnresolvedFunctionsExports) {
  330. LPCWSTR option[] = { L"-Zi" };
  331. CComPtr<IDxcBlob> pLib1;
  332. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func1.hlsl",
  333. &pLib1, option, 1);
  334. CComPtr<IDxcBlob> pLib2;
  335. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func2.hlsl",
  336. &pLib2, option, 1);
  337. CComPtr<IDxcLinker> pLinker;
  338. CreateLinker(&pLinker);
  339. LPCWSTR libName1 = L"lib1";
  340. RegisterDxcModule(libName1, pLib1, pLinker);
  341. LPCWSTR libName2 = L"lib2";
  342. RegisterDxcModule(libName2, pLib2, pLinker);
  343. Link(L"", L"lib_6_3", pLinker, { libName1, libName2 },
  344. { "declare float @\"\\01?external_fn1@@YAMXZ\"()",
  345. "declare float @\"\\01?external_fn2@@YAMXZ\"()",
  346. "declare float @\"\\01?external_fn@@YAMXZ\"()",
  347. "define float @\"\\01?renamed_lib1@@YAMXZ\"()",
  348. "define float @\"\\01?call_lib2@@YAMXZ\"()"
  349. },
  350. { "float @\"\\01?unused_fn1", "float @\"\\01?unused_fn2",
  351. "float @\"\\01?lib1_fn", "float @\"\\01?lib2_fn",
  352. "float @\"\\01?call_lib1"
  353. },
  354. { L"-exports", L"renamed_lib1=call_lib1",
  355. L"-exports", L"call_lib2"
  356. });
  357. }
  358. TEST_F(LinkerTest, RunLinkToLibWithExportNamesSwapped) {
  359. LPCWSTR option[] = { L"-Zi" };
  360. CComPtr<IDxcBlob> pLib1;
  361. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func1.hlsl",
  362. &pLib1, option, 1);
  363. CComPtr<IDxcBlob> pLib2;
  364. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func2.hlsl",
  365. &pLib2, option, 1);
  366. CComPtr<IDxcLinker> pLinker;
  367. CreateLinker(&pLinker);
  368. LPCWSTR libName1 = L"lib1";
  369. RegisterDxcModule(libName1, pLib1, pLinker);
  370. LPCWSTR libName2 = L"lib2";
  371. RegisterDxcModule(libName2, pLib2, pLinker);
  372. Link(L"", L"lib_6_3", pLinker, { libName1, libName2 },
  373. { "declare float @\"\\01?external_fn1@@YAMXZ\"()",
  374. "declare float @\"\\01?external_fn2@@YAMXZ\"()",
  375. "declare float @\"\\01?external_fn@@YAMXZ\"()",
  376. "define float @\"\\01?call_lib1@@YAMXZ\"()",
  377. "define float @\"\\01?call_lib2@@YAMXZ\"()"
  378. },
  379. { "float @\"\\01?unused_fn1", "float @\"\\01?unused_fn2",
  380. "float @\"\\01?lib1_fn", "float @\"\\01?lib2_fn"
  381. },
  382. { L"-exports", L"call_lib2=call_lib1;call_lib1=call_lib2" });
  383. }
  384. TEST_F(LinkerTest, RunLinkToLibWithExportCollision) {
  385. LPCWSTR option[] = { L"-Zi" };
  386. CComPtr<IDxcBlob> pLib1;
  387. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func1.hlsl",
  388. &pLib1, option, 1);
  389. CComPtr<IDxcBlob> pLib2;
  390. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func2.hlsl",
  391. &pLib2, option, 1);
  392. CComPtr<IDxcLinker> pLinker;
  393. CreateLinker(&pLinker);
  394. LPCWSTR libName1 = L"lib1";
  395. RegisterDxcModule(libName1, pLib1, pLinker);
  396. LPCWSTR libName2 = L"lib2";
  397. RegisterDxcModule(libName2, pLib2, pLinker);
  398. LinkCheckMsg(L"", L"lib_6_3", pLinker, { libName1, libName2 },
  399. { "Export name collides with another export: \\01?call_lib2@@YAMXZ"
  400. },
  401. { L"-exports", L"call_lib2=call_lib1;call_lib2" });
  402. }
  403. TEST_F(LinkerTest, RunLinkToLibWithUnusedExport) {
  404. LPCWSTR option[] = { L"-Zi" };
  405. CComPtr<IDxcBlob> pLib1;
  406. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func1.hlsl",
  407. &pLib1, option, 1);
  408. CComPtr<IDxcBlob> pLib2;
  409. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func2.hlsl",
  410. &pLib2, option, 1);
  411. CComPtr<IDxcLinker> pLinker;
  412. CreateLinker(&pLinker);
  413. LPCWSTR libName1 = L"lib1";
  414. RegisterDxcModule(libName1, pLib1, pLinker);
  415. LPCWSTR libName2 = L"lib2";
  416. RegisterDxcModule(libName2, pLib2, pLinker);
  417. LinkCheckMsg(L"", L"lib_6_3", pLinker, { libName1, libName2 },
  418. { "Could not find target for export: call_lib"
  419. },
  420. { L"-exports", L"call_lib2=call_lib;call_lib1" });
  421. }
  422. TEST_F(LinkerTest, RunLinkToLibWithNoExports) {
  423. LPCWSTR option[] = { L"-Zi" };
  424. CComPtr<IDxcBlob> pLib1;
  425. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func1.hlsl",
  426. &pLib1, option, 1);
  427. CComPtr<IDxcBlob> pLib2;
  428. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_unresolved_func2.hlsl",
  429. &pLib2, option, 1);
  430. CComPtr<IDxcLinker> pLinker;
  431. CreateLinker(&pLinker);
  432. LPCWSTR libName1 = L"lib1";
  433. RegisterDxcModule(libName1, pLib1, pLinker);
  434. LPCWSTR libName2 = L"lib2";
  435. RegisterDxcModule(libName2, pLib2, pLinker);
  436. LinkCheckMsg(L"", L"lib_6_3", pLinker, { libName1, libName2 },
  437. { "Library has no functions to export"
  438. },
  439. { L"-exports", L"call_lib2=call_lib" });
  440. }
  441. TEST_F(LinkerTest, RunLinkWithPotentialIntrinsicNameCollisions) {
  442. LPCWSTR option[] = { L"-Zi" };
  443. CComPtr<IDxcBlob> pLib1;
  444. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\createHandle_multi.hlsl",
  445. &pLib1, option, 1);
  446. CComPtr<IDxcBlob> pLib2;
  447. CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\createHandle_multi2.hlsl",
  448. &pLib2, option, 1);
  449. CComPtr<IDxcLinker> pLinker;
  450. CreateLinker(&pLinker);
  451. LPCWSTR libName1 = L"lib1";
  452. RegisterDxcModule(libName1, pLib1, pLinker);
  453. LPCWSTR libName2 = L"lib2";
  454. RegisterDxcModule(libName2, pLib2, pLinker);
  455. Link(L"", L"lib_6_2", pLinker, { libName1, libName2 }, {
  456. "declare %dx.types.Handle @\"dx.op.createHandleFromResourceStructForLib.class.Texture2D<vector<float, 4> >\"(i32, %\"class.Texture2D<vector<float, 4> >\")",
  457. "declare %dx.types.Handle @\"dx.op.createHandleFromResourceStructForLib.class.Texture2D<float>\"(i32, %\"class.Texture2D<float>\")"
  458. }, { });
  459. }