ir_loader_test.cpp 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528
  1. // Copyright (c) 2016 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <algorithm>
  15. #include <memory>
  16. #include <unordered_set>
  17. #include <utility>
  18. #include <vector>
  19. #include "gmock/gmock.h"
  20. #include "source/opt/build_module.h"
  21. #include "source/opt/def_use_manager.h"
  22. #include "source/opt/ir_context.h"
  23. #include "spirv-tools/libspirv.hpp"
  24. namespace spvtools {
  25. namespace opt {
  26. namespace {
  27. using ::testing::ContainerEq;
  28. constexpr uint32_t kOpLineOperandLineIndex = 1;
  29. void DoRoundTripCheck(const std::string& text) {
  30. SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  31. std::unique_ptr<IRContext> context =
  32. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
  33. ASSERT_NE(nullptr, context) << "Failed to assemble\n" << text;
  34. std::vector<uint32_t> binary;
  35. context->module()->ToBinary(&binary, /* skip_nop = */ false);
  36. std::string disassembled_text;
  37. EXPECT_TRUE(t.Disassemble(binary, &disassembled_text));
  38. EXPECT_EQ(text, disassembled_text);
  39. }
  40. TEST(IrBuilder, RoundTrip) {
  41. // #version 310 es
  42. // int add(int a, int b) { return a + b; }
  43. // void main() { add(1, 2); }
  44. DoRoundTripCheck(
  45. // clang-format off
  46. "OpCapability Shader\n"
  47. "%1 = OpExtInstImport \"GLSL.std.450\"\n"
  48. "OpMemoryModel Logical GLSL450\n"
  49. "OpEntryPoint Vertex %main \"main\"\n"
  50. "OpSource ESSL 310\n"
  51. "OpSourceExtension \"GL_GOOGLE_cpp_style_line_directive\"\n"
  52. "OpSourceExtension \"GL_GOOGLE_include_directive\"\n"
  53. "OpName %main \"main\"\n"
  54. "OpName %add_i1_i1_ \"add(i1;i1;\"\n"
  55. "OpName %a \"a\"\n"
  56. "OpName %b \"b\"\n"
  57. "OpName %param \"param\"\n"
  58. "OpName %param_0 \"param\"\n"
  59. "%void = OpTypeVoid\n"
  60. "%9 = OpTypeFunction %void\n"
  61. "%int = OpTypeInt 32 1\n"
  62. "%_ptr_Function_int = OpTypePointer Function %int\n"
  63. "%12 = OpTypeFunction %int %_ptr_Function_int %_ptr_Function_int\n"
  64. "%int_1 = OpConstant %int 1\n"
  65. "%int_2 = OpConstant %int 2\n"
  66. "%main = OpFunction %void None %9\n"
  67. "%15 = OpLabel\n"
  68. "%param = OpVariable %_ptr_Function_int Function\n"
  69. "%param_0 = OpVariable %_ptr_Function_int Function\n"
  70. "OpStore %param %int_1\n"
  71. "OpStore %param_0 %int_2\n"
  72. "%16 = OpFunctionCall %int %add_i1_i1_ %param %param_0\n"
  73. "OpReturn\n"
  74. "OpFunctionEnd\n"
  75. "%add_i1_i1_ = OpFunction %int None %12\n"
  76. "%a = OpFunctionParameter %_ptr_Function_int\n"
  77. "%b = OpFunctionParameter %_ptr_Function_int\n"
  78. "%17 = OpLabel\n"
  79. "%18 = OpLoad %int %a\n"
  80. "%19 = OpLoad %int %b\n"
  81. "%20 = OpIAdd %int %18 %19\n"
  82. "OpReturnValue %20\n"
  83. "OpFunctionEnd\n");
  84. // clang-format on
  85. }
  86. TEST(IrBuilder, RoundTripIncompleteBasicBlock) {
  87. DoRoundTripCheck(
  88. "%2 = OpFunction %1 None %3\n"
  89. "%4 = OpLabel\n"
  90. "OpNop\n");
  91. }
  92. TEST(IrBuilder, RoundTripIncompleteFunction) {
  93. DoRoundTripCheck("%2 = OpFunction %1 None %3\n");
  94. }
  95. TEST(IrBuilder, RoundTripFunctionPointer) {
  96. DoRoundTripCheck(
  97. "OpCapability Linkage\n"
  98. "OpCapability FunctionPointersINTEL\n"
  99. "OpName %some_function \"some_function\"\n"
  100. "OpName %ptr_to_function \"ptr_to_function\"\n"
  101. "OpDecorate %some_function LinkageAttributes \"some_function\" Import\n"
  102. "%float = OpTypeFloat 32\n"
  103. "%4 = OpTypeFunction %float %float\n"
  104. "%_ptr_Function_4 = OpTypePointer Function %4\n"
  105. "%ptr_to_function = OpConstantFunctionPointerINTEL %_ptr_Function_4 "
  106. "%some_function\n"
  107. "%some_function = OpFunction %float Const %4\n"
  108. "%6 = OpFunctionParameter %float\n"
  109. "OpFunctionEnd\n");
  110. }
  111. TEST(IrBuilder, KeepLineDebugInfo) {
  112. // #version 310 es
  113. // void main() {}
  114. DoRoundTripCheck(
  115. // clang-format off
  116. "OpCapability Shader\n"
  117. "%1 = OpExtInstImport \"GLSL.std.450\"\n"
  118. "OpMemoryModel Logical GLSL450\n"
  119. "OpEntryPoint Vertex %main \"main\"\n"
  120. "%3 = OpString \"minimal.vert\"\n"
  121. "OpSource ESSL 310\n"
  122. "OpName %main \"main\"\n"
  123. "OpLine %3 10 10\n"
  124. "%void = OpTypeVoid\n"
  125. "OpLine %3 100 100\n"
  126. "%5 = OpTypeFunction %void\n"
  127. "%main = OpFunction %void None %5\n"
  128. "OpLine %3 1 1\n"
  129. "OpNoLine\n"
  130. "OpLine %3 2 2\n"
  131. "OpLine %3 3 3\n"
  132. "%6 = OpLabel\n"
  133. "OpLine %3 4 4\n"
  134. "OpNoLine\n"
  135. "OpReturn\n"
  136. "OpFunctionEnd\n");
  137. // clang-format on
  138. }
  139. TEST(IrBuilder, DistributeLineDebugInfo) {
  140. const std::string text =
  141. // clang-format off
  142. "OpCapability Shader\n"
  143. "%1 = OpExtInstImport \"GLSL.std.450\"\n"
  144. "OpMemoryModel Logical GLSL450\n"
  145. "OpEntryPoint Vertex %main \"main\"\n"
  146. "OpSource ESSL 310\n"
  147. "%file = OpString \"test\"\n"
  148. "OpName %main \"main\"\n"
  149. "OpName %f_ \"f(\"\n"
  150. "OpName %gv1 \"gv1\"\n"
  151. "OpName %gv2 \"gv2\"\n"
  152. "OpName %lv1 \"lv1\"\n"
  153. "OpName %lv2 \"lv2\"\n"
  154. "OpName %lv1_0 \"lv1\"\n"
  155. "%void = OpTypeVoid\n"
  156. "%10 = OpTypeFunction %void\n"
  157. "OpLine %file 10 0\n"
  158. "%float = OpTypeFloat 32\n"
  159. "%12 = OpTypeFunction %float\n"
  160. "%_ptr_Private_float = OpTypePointer Private %float\n"
  161. "%gv1 = OpVariable %_ptr_Private_float Private\n"
  162. "%float_10 = OpConstant %float 10\n"
  163. "%gv2 = OpVariable %_ptr_Private_float Private\n"
  164. "%float_100 = OpConstant %float 100\n"
  165. "%_ptr_Function_float = OpTypePointer Function %float\n"
  166. "%main = OpFunction %void None %10\n"
  167. "%17 = OpLabel\n"
  168. "%lv1_0 = OpVariable %_ptr_Function_float Function\n"
  169. "OpStore %gv1 %float_10\n"
  170. "OpStore %gv2 %float_100\n"
  171. "OpLine %file 1 0\n"
  172. "OpNoLine\n"
  173. "OpLine %file 2 0\n"
  174. "%18 = OpLoad %float %gv1\n"
  175. "%19 = OpLoad %float %gv2\n"
  176. "%20 = OpFSub %float %18 %19\n"
  177. "OpStore %lv1_0 %20\n"
  178. "OpReturn\n"
  179. "OpFunctionEnd\n"
  180. "%f_ = OpFunction %float None %12\n"
  181. "%21 = OpLabel\n"
  182. "%lv1 = OpVariable %_ptr_Function_float Function\n"
  183. "%lv2 = OpVariable %_ptr_Function_float Function\n"
  184. "OpLine %file 3 0\n"
  185. "OpLine %file 4 0\n"
  186. "%22 = OpLoad %float %gv1\n"
  187. "%23 = OpLoad %float %gv2\n"
  188. "%24 = OpFAdd %float %22 %23\n"
  189. "OpStore %lv1 %24\n"
  190. "OpLine %file 5 0\n"
  191. "OpLine %file 6 0\n"
  192. "OpNoLine\n"
  193. "%25 = OpLoad %float %gv1\n"
  194. "%26 = OpLoad %float %gv2\n"
  195. "%27 = OpFMul %float %25 %26\n"
  196. "OpBranch %28\n"
  197. "%28 = OpLabel\n"
  198. "OpStore %lv2 %27\n"
  199. "%29 = OpLoad %float %lv1\n"
  200. "OpLine %file 7 0\n"
  201. "%30 = OpLoad %float %lv2\n"
  202. "%31 = OpFDiv %float %28 %29\n"
  203. "OpReturnValue %30\n"
  204. "OpFunctionEnd\n";
  205. // clang-format on
  206. std::unique_ptr<IRContext> context =
  207. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  208. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  209. ASSERT_NE(nullptr, context);
  210. struct LineInstrCheck {
  211. uint32_t id;
  212. std::vector<uint32_t> line_numbers;
  213. };
  214. const uint32_t kNoLine = 0;
  215. const LineInstrCheck line_checks[] = {
  216. {12, {10}}, {18, {1, kNoLine, 2}},
  217. {19, {2}}, {20, {2}},
  218. {22, {3, 4}}, {23, {4}},
  219. {24, {4}}, {25, {5, 6, kNoLine}},
  220. {26, {}}, {27, {}},
  221. {28, {}}, {29, {}},
  222. {30, {7}}, {31, {7}},
  223. };
  224. spvtools::opt::analysis::DefUseManager* def_use_mgr =
  225. context->get_def_use_mgr();
  226. for (const LineInstrCheck& check : line_checks) {
  227. auto& lines = def_use_mgr->GetDef(check.id)->dbg_line_insts();
  228. for (uint32_t i = 0; i < check.line_numbers.size(); ++i) {
  229. if (check.line_numbers[i] == kNoLine) {
  230. EXPECT_EQ(lines[i].opcode(), spv::Op::OpNoLine);
  231. continue;
  232. }
  233. EXPECT_EQ(lines[i].opcode(), spv::Op::OpLine);
  234. EXPECT_EQ(lines[i].GetSingleWordOperand(kOpLineOperandLineIndex),
  235. check.line_numbers[i]);
  236. }
  237. }
  238. }
  239. TEST(IrBuilder, BuildModule_WithoutExtraLines) {
  240. const std::string text = R"(OpCapability Shader
  241. OpMemoryModel Logical Simple
  242. OpEntryPoint Vertex %main "main"
  243. %file = OpString "my file"
  244. %void = OpTypeVoid
  245. %voidfn = OpTypeFunction %void
  246. %float = OpTypeFloat 32
  247. %float_1 = OpConstant %float 1
  248. %main = OpFunction %void None %voidfn
  249. %100 = OpLabel
  250. %1 = OpFAdd %float %float_1 %float_1
  251. OpLine %file 1 0
  252. %2 = OpFMul %float %1 %1
  253. %3 = OpFSub %float %2 %2
  254. OpReturn
  255. OpFunctionEnd
  256. )";
  257. std::vector<uint32_t> binary;
  258. SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  259. ASSERT_TRUE(t.Assemble(text, &binary,
  260. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS));
  261. // This is the function we're testing.
  262. std::unique_ptr<IRContext> context = BuildModule(
  263. SPV_ENV_UNIVERSAL_1_5, nullptr, binary.data(), binary.size(), false);
  264. ASSERT_NE(nullptr, context);
  265. spvtools::opt::analysis::DefUseManager* def_use_mgr =
  266. context->get_def_use_mgr();
  267. std::vector<spv::Op> opcodes;
  268. for (auto* inst = def_use_mgr->GetDef(1);
  269. inst && (inst->opcode() != spv::Op::OpFunctionEnd);
  270. inst = inst->NextNode()) {
  271. inst->ForEachInst(
  272. [&opcodes](spvtools::opt::Instruction* sub_inst) {
  273. opcodes.push_back(sub_inst->opcode());
  274. },
  275. true);
  276. }
  277. EXPECT_THAT(opcodes, ContainerEq(std::vector<spv::Op>{
  278. spv::Op::OpFAdd, spv::Op::OpLine, spv::Op::OpFMul,
  279. spv::Op::OpFSub, spv::Op::OpReturn}));
  280. }
  281. TEST(IrBuilder, BuildModule_WithExtraLines_IsDefault) {
  282. const std::string text = R"(OpCapability Shader
  283. OpMemoryModel Logical Simple
  284. OpEntryPoint Vertex %main "main"
  285. %file = OpString "my file"
  286. %void = OpTypeVoid
  287. %voidfn = OpTypeFunction %void
  288. %float = OpTypeFloat 32
  289. %float_1 = OpConstant %float 1
  290. %main = OpFunction %void None %voidfn
  291. %100 = OpLabel
  292. %1 = OpFAdd %float %float_1 %float_1
  293. OpLine %file 1 0
  294. %2 = OpFMul %float %1 %1
  295. %3 = OpFSub %float %2 %2
  296. OpReturn
  297. OpFunctionEnd
  298. )";
  299. std::vector<uint32_t> binary;
  300. SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  301. ASSERT_TRUE(t.Assemble(text, &binary,
  302. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS));
  303. // This is the function we're testing.
  304. std::unique_ptr<IRContext> context =
  305. BuildModule(SPV_ENV_UNIVERSAL_1_5, nullptr, binary.data(), binary.size());
  306. spvtools::opt::analysis::DefUseManager* def_use_mgr =
  307. context->get_def_use_mgr();
  308. std::vector<spv::Op> opcodes;
  309. for (auto* inst = def_use_mgr->GetDef(1);
  310. inst && (inst->opcode() != spv::Op::OpFunctionEnd);
  311. inst = inst->NextNode()) {
  312. inst->ForEachInst(
  313. [&opcodes](spvtools::opt::Instruction* sub_inst) {
  314. opcodes.push_back(sub_inst->opcode());
  315. },
  316. true);
  317. }
  318. EXPECT_THAT(opcodes, ContainerEq(std::vector<spv::Op>{
  319. spv::Op::OpFAdd, spv::Op::OpLine, spv::Op::OpFMul,
  320. spv::Op::OpLine, spv::Op::OpFSub, spv::Op::OpLine,
  321. spv::Op::OpReturn}));
  322. }
  323. TEST(IrBuilder, ConsumeDebugInfoInst) {
  324. // /* HLSL */
  325. //
  326. // struct VS_OUTPUT {
  327. // float4 pos : SV_POSITION;
  328. // float4 color : COLOR;
  329. // };
  330. //
  331. // VS_OUTPUT main(float4 pos : POSITION,
  332. // float4 color : COLOR) {
  333. // VS_OUTPUT vout;
  334. // vout.pos = pos;
  335. // vout.color = color;
  336. // return vout;
  337. // }
  338. DoRoundTripCheck(R"(OpCapability Shader
  339. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  340. OpMemoryModel Logical GLSL450
  341. OpEntryPoint Vertex %main "main" %pos %color %gl_Position %out_var_COLOR
  342. %7 = OpString "simple_vs.hlsl"
  343. %8 = OpString "#line 1 \"simple_vs.hlsl\"
  344. struct VS_OUTPUT {
  345. float4 pos : SV_POSITION;
  346. float4 color : COLOR;
  347. };
  348. VS_OUTPUT main(float4 pos : POSITION,
  349. float4 color : COLOR) {
  350. VS_OUTPUT vout;
  351. vout.pos = pos;
  352. vout.color = color;
  353. return vout;
  354. }
  355. "
  356. OpSource HLSL 600 %7 "#line 1 \"simple_vs.hlsl\"
  357. struct VS_OUTPUT {
  358. float4 pos : SV_POSITION;
  359. float4 color : COLOR;
  360. };
  361. VS_OUTPUT main(float4 pos : POSITION,
  362. float4 color : COLOR) {
  363. VS_OUTPUT vout;
  364. vout.pos = pos;
  365. vout.color = color;
  366. return vout;
  367. }
  368. "
  369. %9 = OpString "struct VS_OUTPUT"
  370. %10 = OpString "float"
  371. %11 = OpString "pos : SV_POSITION"
  372. %12 = OpString "color : COLOR"
  373. %13 = OpString "VS_OUTPUT"
  374. %14 = OpString "main"
  375. %15 = OpString "VS_OUTPUT_main_v4f_v4f"
  376. %16 = OpString "pos : POSITION"
  377. %17 = OpString "color : COLOR"
  378. %18 = OpString "vout"
  379. OpName %out_var_COLOR "out.var.COLOR"
  380. OpName %main "main"
  381. OpName %VS_OUTPUT "VS_OUTPUT"
  382. OpMemberName %VS_OUTPUT 0 "pos"
  383. OpMemberName %VS_OUTPUT 1 "color"
  384. OpName %pos "pos"
  385. OpName %color "color"
  386. OpName %vout "vout"
  387. OpDecorate %gl_Position BuiltIn Position
  388. OpDecorate %pos Location 0
  389. OpDecorate %color Location 1
  390. OpDecorate %out_var_COLOR Location 0
  391. %int = OpTypeInt 32 1
  392. %int_0 = OpConstant %int 0
  393. %int_1 = OpConstant %int 1
  394. %int_32 = OpConstant %int 32
  395. %int_128 = OpConstant %int 128
  396. %float = OpTypeFloat 32
  397. %v4float = OpTypeVector %float 4
  398. %_ptr_Input_v4float = OpTypePointer Input %v4float
  399. %_ptr_Output_v4float = OpTypePointer Output %v4float
  400. %void = OpTypeVoid
  401. %31 = OpTypeFunction %void
  402. %_ptr_Function_v4float = OpTypePointer Function %v4float
  403. %VS_OUTPUT = OpTypeStruct %v4float %v4float
  404. %_ptr_Function_VS_OUTPUT = OpTypePointer Function %VS_OUTPUT
  405. OpLine %7 6 23
  406. %pos = OpVariable %_ptr_Input_v4float Input
  407. OpLine %7 7 23
  408. %color = OpVariable %_ptr_Input_v4float Input
  409. OpLine %7 2 16
  410. %gl_Position = OpVariable %_ptr_Output_v4float Output
  411. OpLine %7 3 18
  412. %out_var_COLOR = OpVariable %_ptr_Output_v4float Output
  413. %34 = OpExtInst %void %1 DebugSource %7 %8
  414. %35 = OpExtInst %void %1 DebugCompilationUnit 2 4 %34 HLSL
  415. %36 = OpExtInst %void %1 DebugTypeComposite %9 Structure %34 1 1 %35 %13 %int_128 FlagIsProtected|FlagIsPrivate %37 %38
  416. %39 = OpExtInst %void %1 DebugTypeBasic %10 %int_32 Float
  417. %40 = OpExtInst %void %1 DebugTypeVector %39 4
  418. %37 = OpExtInst %void %1 DebugTypeMember %11 %40 %34 2 3 %36 %int_0 %int_128 FlagIsProtected|FlagIsPrivate
  419. %38 = OpExtInst %void %1 DebugTypeMember %12 %40 %34 3 3 %36 %int_128 %int_128 FlagIsProtected|FlagIsPrivate
  420. %41 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %36 %40 %40
  421. %42 = OpExtInst %void %1 DebugExpression
  422. %43 = OpExtInst %void %1 DebugFunction %14 %41 %34 6 1 %35 %15 FlagIsProtected|FlagIsPrivate 7 %main
  423. %44 = OpExtInst %void %1 DebugLocalVariable %16 %40 %34 6 16 %43 FlagIsLocal 0
  424. %45 = OpExtInst %void %1 DebugLocalVariable %17 %40 %34 7 16 %43 FlagIsLocal 1
  425. %46 = OpExtInst %void %1 DebugLocalVariable %18 %36 %34 8 3 %43 FlagIsLocal
  426. OpLine %7 6 1
  427. %main = OpFunction %void None %31
  428. %47 = OpLabel
  429. %60 = OpExtInst %void %1 DebugScope %43
  430. OpLine %7 8 13
  431. %vout = OpVariable %_ptr_Function_VS_OUTPUT Function
  432. %49 = OpExtInst %void %1 DebugDeclare %46 %vout %42
  433. OpLine %7 9 14
  434. %50 = OpLoad %v4float %pos
  435. OpLine %7 9 3
  436. %51 = OpAccessChain %_ptr_Function_v4float %vout %int_0
  437. %52 = OpExtInst %void %1 DebugValue %46 %51 %42 %int_0
  438. OpStore %51 %50
  439. OpLine %7 10 16
  440. %53 = OpLoad %v4float %color
  441. OpLine %7 10 3
  442. %54 = OpAccessChain %_ptr_Function_v4float %vout %int_1
  443. %55 = OpExtInst %void %1 DebugValue %46 %54 %42 %int_1
  444. OpStore %54 %53
  445. OpLine %7 11 10
  446. %56 = OpLoad %VS_OUTPUT %vout
  447. OpLine %7 11 3
  448. %57 = OpCompositeExtract %v4float %56 0
  449. OpStore %gl_Position %57
  450. %58 = OpCompositeExtract %v4float %56 1
  451. OpStore %out_var_COLOR %58
  452. %61 = OpExtInst %void %1 DebugNoScope
  453. OpReturn
  454. OpFunctionEnd
  455. )");
  456. }
  457. TEST(IrBuilder, ConsumeDebugInfoLexicalScopeInst) {
  458. // /* HLSL */
  459. //
  460. // float4 func2(float arg2) { // func2_block
  461. // return float4(arg2, 0, 0, 0);
  462. // }
  463. //
  464. // float4 func1(float arg1) { // func1_block
  465. // if (arg1 > 1) { // if_true_block
  466. // return float4(0, 0, 0, 0);
  467. // }
  468. // return func2(arg1); // if_merge_block
  469. // }
  470. //
  471. // float4 main(float pos : POSITION) : SV_POSITION { // main
  472. // return func1(pos);
  473. // }
  474. DoRoundTripCheck(R"(OpCapability Shader
  475. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  476. OpMemoryModel Logical GLSL450
  477. OpEntryPoint Vertex %main "main" %pos %gl_Position
  478. %5 = OpString "block/block.hlsl"
  479. %6 = OpString "#line 1 \"block/block.hlsl\"
  480. float4 func2(float arg2) {
  481. return float4(arg2, 0, 0, 0);
  482. }
  483. float4 func1(float arg1) {
  484. if (arg1 > 1) {
  485. return float4(0, 0, 0, 0);
  486. }
  487. return func2(arg1);
  488. }
  489. float4 main(float pos : POSITION) : SV_POSITION {
  490. return func1(pos);
  491. }
  492. "
  493. OpSource HLSL 600 %5 "#line 1 \"block/block.hlsl\"
  494. float4 func2(float arg2) {
  495. return float4(arg2, 0, 0, 0);
  496. }
  497. float4 func1(float arg1) {
  498. if (arg1 > 1) {
  499. return float4(0, 0, 0, 0);
  500. }
  501. return func2(arg1);
  502. }
  503. float4 main(float pos : POSITION) : SV_POSITION {
  504. return func1(pos);
  505. }
  506. "
  507. %7 = OpString "float"
  508. %8 = OpString "main"
  509. %9 = OpString "v4f_main_f"
  510. %10 = OpString "v4f_func1_f"
  511. %11 = OpString "v4f_func2_f"
  512. %12 = OpString "pos : POSITION"
  513. %13 = OpString "func1"
  514. %14 = OpString "func2"
  515. OpName %main "main"
  516. OpName %pos "pos"
  517. OpName %bb_entry "bb.entry"
  518. OpName %param_var_arg1 "param.var.arg1"
  519. OpName %func1 "func1"
  520. OpName %arg1 "arg1"
  521. OpName %bb_entry_0 "bb.entry"
  522. OpName %param_var_arg2 "param.var.arg2"
  523. OpName %if_true "if.true"
  524. OpName %if_merge "if.merge"
  525. OpName %func2 "func2"
  526. OpName %arg2 "arg2"
  527. OpName %bb_entry_1 "bb.entry"
  528. OpDecorate %gl_Position BuiltIn Position
  529. OpDecorate %pos Location 0
  530. %float = OpTypeFloat 32
  531. %int = OpTypeInt 32 1
  532. %float_1 = OpConstant %float 1
  533. %float_0 = OpConstant %float 0
  534. %int_32 = OpConstant %int 32
  535. %v4float = OpTypeVector %float 4
  536. %32 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  537. %_ptr_Input_float = OpTypePointer Input %float
  538. %_ptr_Output_v4float = OpTypePointer Output %v4float
  539. %void = OpTypeVoid
  540. %36 = OpTypeFunction %void
  541. %_ptr_Function_float = OpTypePointer Function %float
  542. %38 = OpTypeFunction %v4float %_ptr_Function_float
  543. %bool = OpTypeBool
  544. OpLine %5 12 25
  545. %pos = OpVariable %_ptr_Input_float Input
  546. OpLine %5 12 37
  547. %gl_Position = OpVariable %_ptr_Output_v4float Output
  548. %40 = OpExtInst %void %1 DebugSource %5 %6
  549. %41 = OpExtInst %void %1 DebugCompilationUnit 2 4 %40 HLSL
  550. %42 = OpExtInst %void %1 DebugTypeBasic %7 %int_32 Float
  551. %43 = OpExtInst %void %1 DebugTypeVector %42 4
  552. %44 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
  553. %45 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
  554. %46 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
  555. %47 = OpExtInst %void %1 DebugFunction %8 %44 %40 12 1 %41 %9 FlagIsProtected|FlagIsPrivate 13 %main
  556. %48 = OpExtInst %void %1 DebugFunction %13 %45 %40 5 1 %41 %10 FlagIsProtected|FlagIsPrivate 13 %func1
  557. %49 = OpExtInst %void %1 DebugFunction %14 %46 %40 1 1 %41 %11 FlagIsProtected|FlagIsPrivate 13 %func2
  558. %50 = OpExtInst %void %1 DebugLexicalBlock %40 6 17 %48
  559. %51 = OpExtInst %void %1 DebugLexicalBlock %40 9 3 %48
  560. OpLine %5 12 1
  561. %main = OpFunction %void None %36
  562. %bb_entry = OpLabel
  563. %70 = OpExtInst %void %1 DebugScope %47
  564. OpLine %5 13 16
  565. %param_var_arg1 = OpVariable %_ptr_Function_float Function
  566. %53 = OpLoad %float %pos
  567. OpStore %param_var_arg1 %53
  568. OpLine %5 13 10
  569. %54 = OpFunctionCall %v4float %func1 %param_var_arg1
  570. OpLine %5 13 3
  571. OpStore %gl_Position %54
  572. %71 = OpExtInst %void %1 DebugNoScope
  573. OpReturn
  574. OpFunctionEnd
  575. OpLine %5 5 1
  576. %func1 = OpFunction %v4float None %38
  577. OpLine %5 5 20
  578. %arg1 = OpFunctionParameter %_ptr_Function_float
  579. %bb_entry_0 = OpLabel
  580. %72 = OpExtInst %void %1 DebugScope %48
  581. OpLine %5 9 16
  582. %param_var_arg2 = OpVariable %_ptr_Function_float Function
  583. OpLine %5 6 7
  584. %57 = OpLoad %float %arg1
  585. OpLine %5 6 12
  586. %58 = OpFOrdGreaterThan %bool %57 %float_1
  587. OpLine %5 6 17
  588. %73 = OpExtInst %void %1 DebugNoScope
  589. OpSelectionMerge %if_merge None
  590. OpBranchConditional %58 %if_true %if_merge
  591. %if_true = OpLabel
  592. %74 = OpExtInst %void %1 DebugScope %50
  593. OpLine %5 7 5
  594. %75 = OpExtInst %void %1 DebugNoScope
  595. OpReturnValue %32
  596. %if_merge = OpLabel
  597. %76 = OpExtInst %void %1 DebugScope %51
  598. OpLine %5 9 16
  599. %63 = OpLoad %float %arg1
  600. OpStore %param_var_arg2 %63
  601. OpLine %5 9 10
  602. %64 = OpFunctionCall %v4float %func2 %param_var_arg2
  603. OpLine %5 9 3
  604. %77 = OpExtInst %void %1 DebugNoScope
  605. OpReturnValue %64
  606. OpFunctionEnd
  607. OpLine %5 1 1
  608. %func2 = OpFunction %v4float None %38
  609. OpLine %5 1 20
  610. %arg2 = OpFunctionParameter %_ptr_Function_float
  611. %bb_entry_1 = OpLabel
  612. %78 = OpExtInst %void %1 DebugScope %49
  613. OpLine %5 2 17
  614. %67 = OpLoad %float %arg2
  615. %68 = OpCompositeConstruct %v4float %67 %float_0 %float_0 %float_0
  616. OpLine %5 2 3
  617. %79 = OpExtInst %void %1 DebugNoScope
  618. OpReturnValue %68
  619. OpFunctionEnd
  620. )");
  621. }
  622. TEST(IrBuilder, ConsumeDebugInlinedAt) {
  623. // /* HLSL */
  624. //
  625. // float4 func2(float arg2) { // func2_block
  626. // return float4(arg2, 0, 0, 0);
  627. // }
  628. //
  629. // float4 func1(float arg1) { // func1_block
  630. // if (arg1 > 1) { // if_true_block
  631. // return float4(0, 0, 0, 0);
  632. // }
  633. // return func2(arg1); // if_merge_block
  634. // }
  635. //
  636. // float4 main(float pos : POSITION) : SV_POSITION { // main
  637. // return func1(pos);
  638. // }
  639. //
  640. // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/533): In the following
  641. // SPIRV code, we use DebugInfoNone to reference opted-out function from
  642. // DebugFunction similar to opted-out global variable for DebugGlobalVariable,
  643. // but this is not a part of the spec yet. We are still in discussion and we
  644. // must correct it if our decision is different.
  645. DoRoundTripCheck(R"(OpCapability Shader
  646. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  647. OpMemoryModel Logical GLSL450
  648. OpEntryPoint Vertex %main "main" %pos %gl_Position
  649. %5 = OpString "block/block.hlsl"
  650. %6 = OpString "#line 1 \"block/block.hlsl\"
  651. float4 func2(float arg2) {
  652. return float4(arg2, 0, 0, 0);
  653. }
  654. float4 func1(float arg1) {
  655. if (arg1 > 1) {
  656. return float4(0, 0, 0, 0);
  657. }
  658. return func2(arg1);
  659. }
  660. float4 main(float pos : POSITION) : SV_POSITION {
  661. return func1(pos);
  662. }
  663. "
  664. OpSource HLSL 600 %5 "#line 1 \"block/block.hlsl\"
  665. float4 func2(float arg2) {
  666. return float4(arg2, 0, 0, 0);
  667. }
  668. float4 func1(float arg1) {
  669. if (arg1 > 1) {
  670. return float4(0, 0, 0, 0);
  671. }
  672. return func2(arg1);
  673. }
  674. float4 main(float pos : POSITION) : SV_POSITION {
  675. return func1(pos);
  676. }
  677. "
  678. %7 = OpString "float"
  679. %8 = OpString "main"
  680. %9 = OpString "v4f_main_f"
  681. %10 = OpString "v4f_func1_f"
  682. %11 = OpString "v4f_func2_f"
  683. %12 = OpString "pos : POSITION"
  684. %13 = OpString "func1"
  685. %14 = OpString "func2"
  686. OpName %main "main"
  687. OpName %pos "pos"
  688. OpName %bb_entry "bb.entry"
  689. OpName %if_true "if.true"
  690. OpName %if_merge "if.merge"
  691. OpDecorate %gl_Position BuiltIn Position
  692. OpDecorate %pos Location 0
  693. %float = OpTypeFloat 32
  694. %int = OpTypeInt 32 1
  695. %float_1 = OpConstant %float 1
  696. %float_0 = OpConstant %float 0
  697. %int_32 = OpConstant %int 32
  698. %v4float = OpTypeVector %float 4
  699. %24 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  700. %_ptr_Input_float = OpTypePointer Input %float
  701. %_ptr_Output_v4float = OpTypePointer Output %v4float
  702. %void = OpTypeVoid
  703. %28 = OpTypeFunction %void
  704. %_ptr_Function_float = OpTypePointer Function %float
  705. %30 = OpTypeFunction %v4float %_ptr_Function_float
  706. %bool = OpTypeBool
  707. OpLine %5 12 25
  708. %pos = OpVariable %_ptr_Input_float Input
  709. OpLine %5 12 37
  710. %gl_Position = OpVariable %_ptr_Output_v4float Output
  711. %32 = OpExtInst %void %1 DebugInfoNone
  712. %33 = OpExtInst %void %1 DebugSource %5 %6
  713. %34 = OpExtInst %void %1 DebugCompilationUnit 2 4 %33 HLSL
  714. %35 = OpExtInst %void %1 DebugTypeBasic %7 %int_32 Float
  715. %36 = OpExtInst %void %1 DebugTypeVector %35 4
  716. %37 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %36 %35
  717. %38 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %36 %35
  718. %39 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %36 %35
  719. %40 = OpExtInst %void %1 DebugFunction %8 %37 %33 12 1 %34 %9 FlagIsProtected|FlagIsPrivate 13 %main
  720. %41 = OpExtInst %void %1 DebugFunction %13 %38 %33 5 1 %34 %10 FlagIsProtected|FlagIsPrivate 13 %32
  721. %42 = OpExtInst %void %1 DebugFunction %14 %39 %33 1 1 %34 %11 FlagIsProtected|FlagIsPrivate 13 %32
  722. %43 = OpExtInst %void %1 DebugLexicalBlock %33 12 49 %40
  723. %44 = OpExtInst %void %1 DebugLexicalBlock %33 5 26 %41
  724. %45 = OpExtInst %void %1 DebugLexicalBlock %33 1 26 %42
  725. %46 = OpExtInst %void %1 DebugLexicalBlock %33 6 17 %44
  726. %47 = OpExtInst %void %1 DebugLexicalBlock %33 9 3 %44
  727. %48 = OpExtInst %void %1 DebugInlinedAt 9 %47
  728. %49 = OpExtInst %void %1 DebugInlinedAt 13 %43
  729. %50 = OpExtInst %void %1 DebugInlinedAt 13 %43 %48
  730. OpLine %5 12 1
  731. %main = OpFunction %void None %28
  732. %bb_entry = OpLabel
  733. %62 = OpExtInst %void %1 DebugScope %44 %49
  734. OpLine %5 6 7
  735. %52 = OpLoad %float %pos
  736. OpLine %5 6 12
  737. %53 = OpFOrdGreaterThan %bool %52 %float_1
  738. OpLine %5 6 17
  739. %63 = OpExtInst %void %1 DebugNoScope
  740. OpSelectionMerge %if_merge None
  741. OpBranchConditional %53 %if_true %if_merge
  742. %if_true = OpLabel
  743. %64 = OpExtInst %void %1 DebugScope %46 %49
  744. OpLine %5 7 5
  745. OpStore %gl_Position %24
  746. %65 = OpExtInst %void %1 DebugNoScope
  747. OpReturn
  748. %if_merge = OpLabel
  749. %66 = OpExtInst %void %1 DebugScope %45 %50
  750. OpLine %5 2 17
  751. %58 = OpLoad %float %pos
  752. OpLine %5 2 10
  753. %59 = OpCompositeConstruct %v4float %58 %float_0 %float_0 %float_0
  754. %67 = OpExtInst %void %1 DebugScope %43
  755. OpLine %5 13 3
  756. OpStore %gl_Position %59
  757. %68 = OpExtInst %void %1 DebugNoScope
  758. OpReturn
  759. OpFunctionEnd
  760. )");
  761. }
  762. TEST(IrBuilder, DebugInfoInstInFunctionOutOfBlock) {
  763. // /* HLSL */
  764. //
  765. // float4 func2(float arg2) { // func2_block
  766. // return float4(arg2, 0, 0, 0);
  767. // }
  768. //
  769. // float4 func1(float arg1) { // func1_block
  770. // if (arg1 > 1) { // if_true_block
  771. // return float4(0, 0, 0, 0);
  772. // }
  773. // return func2(arg1); // if_merge_block
  774. // }
  775. //
  776. // float4 main(float pos : POSITION) : SV_POSITION { // main
  777. // return func1(pos);
  778. // }
  779. const std::string text = R"(OpCapability Shader
  780. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  781. OpMemoryModel Logical GLSL450
  782. OpEntryPoint Vertex %main "main" %pos %gl_Position
  783. %5 = OpString "block/block.hlsl"
  784. %6 = OpString "#line 1 \"block/block.hlsl\"
  785. float4 func2(float arg2) {
  786. return float4(arg2, 0, 0, 0);
  787. }
  788. float4 func1(float arg1) {
  789. if (arg1 > 1) {
  790. return float4(0, 0, 0, 0);
  791. }
  792. return func2(arg1);
  793. }
  794. float4 main(float pos : POSITION) : SV_POSITION {
  795. return func1(pos);
  796. }
  797. "
  798. OpSource HLSL 600 %5 "#line 1 \"block/block.hlsl\"
  799. float4 func2(float arg2) {
  800. return float4(arg2, 0, 0, 0);
  801. }
  802. float4 func1(float arg1) {
  803. if (arg1 > 1) {
  804. return float4(0, 0, 0, 0);
  805. }
  806. return func2(arg1);
  807. }
  808. float4 main(float pos : POSITION) : SV_POSITION {
  809. return func1(pos);
  810. }
  811. "
  812. %7 = OpString "float"
  813. %8 = OpString "main"
  814. %9 = OpString "v4f_main_f"
  815. %10 = OpString "v4f_func1_f"
  816. %11 = OpString "v4f_func2_f"
  817. %12 = OpString "pos : POSITION"
  818. %13 = OpString "func1"
  819. %14 = OpString "func2"
  820. OpName %main "main"
  821. OpName %pos "pos"
  822. OpName %bb_entry "bb.entry"
  823. OpName %param_var_arg1 "param.var.arg1"
  824. OpName %func1 "func1"
  825. OpName %arg1 "arg1"
  826. OpName %bb_entry_0 "bb.entry"
  827. OpName %param_var_arg2 "param.var.arg2"
  828. OpName %if_true "if.true"
  829. OpName %if_merge "if.merge"
  830. OpName %func2 "func2"
  831. OpName %arg2 "arg2"
  832. OpName %bb_entry_1 "bb.entry"
  833. OpDecorate %gl_Position BuiltIn Position
  834. OpDecorate %pos Location 0
  835. %float = OpTypeFloat 32
  836. %int = OpTypeInt 32 1
  837. %float_1 = OpConstant %float 1
  838. %float_0 = OpConstant %float 0
  839. %int_32 = OpConstant %int 32
  840. %v4float = OpTypeVector %float 4
  841. %32 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  842. %_ptr_Input_float = OpTypePointer Input %float
  843. %_ptr_Output_v4float = OpTypePointer Output %v4float
  844. %void = OpTypeVoid
  845. %36 = OpTypeFunction %void
  846. %_ptr_Function_float = OpTypePointer Function %float
  847. %38 = OpTypeFunction %v4float %_ptr_Function_float
  848. %bool = OpTypeBool
  849. OpLine %5 12 25
  850. %pos = OpVariable %_ptr_Input_float Input
  851. OpLine %5 12 37
  852. %gl_Position = OpVariable %_ptr_Output_v4float Output
  853. %40 = OpExtInst %void %1 DebugSource %5 %6
  854. %41 = OpExtInst %void %1 DebugCompilationUnit 2 4 %40 HLSL
  855. %42 = OpExtInst %void %1 DebugTypeBasic %7 %int_32 Float
  856. %43 = OpExtInst %void %1 DebugTypeVector %42 4
  857. %44 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
  858. %45 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
  859. %46 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
  860. %47 = OpExtInst %void %1 DebugFunction %8 %44 %40 12 1 %41 %9 FlagIsProtected|FlagIsPrivate 13 %main
  861. %48 = OpExtInst %void %1 DebugFunction %13 %45 %40 5 1 %41 %10 FlagIsProtected|FlagIsPrivate 13 %func1
  862. %49 = OpExtInst %void %1 DebugFunction %14 %46 %40 1 1 %41 %11 FlagIsProtected|FlagIsPrivate 13 %func2
  863. %50 = OpExtInst %void %1 DebugLexicalBlock %40 6 17 %48
  864. %51 = OpExtInst %void %1 DebugLexicalBlock %40 9 3 %48
  865. OpLine %5 12 1
  866. %main = OpFunction %void None %36
  867. %bb_entry = OpLabel
  868. %70 = OpExtInst %void %1 DebugScope %47
  869. OpLine %5 13 16
  870. %param_var_arg1 = OpVariable %_ptr_Function_float Function
  871. %53 = OpLoad %float %pos
  872. OpStore %param_var_arg1 %53
  873. OpLine %5 13 10
  874. %54 = OpFunctionCall %v4float %func1 %param_var_arg1
  875. OpLine %5 13 3
  876. OpStore %gl_Position %54
  877. %71 = OpExtInst %void %1 DebugNoScope
  878. OpReturn
  879. OpFunctionEnd
  880. OpLine %5 5 1
  881. %func1 = OpFunction %v4float None %38
  882. OpLine %5 5 20
  883. %arg1 = OpFunctionParameter %_ptr_Function_float
  884. %bb_entry_0 = OpLabel
  885. %72 = OpExtInst %void %1 DebugScope %48
  886. OpLine %5 9 16
  887. %param_var_arg2 = OpVariable %_ptr_Function_float Function
  888. OpLine %5 6 7
  889. %57 = OpLoad %float %arg1
  890. OpLine %5 6 12
  891. %58 = OpFOrdGreaterThan %bool %57 %float_1
  892. OpLine %5 6 17
  893. %73 = OpExtInst %void %1 DebugNoScope
  894. OpSelectionMerge %if_merge None
  895. OpBranchConditional %58 %if_true %if_merge
  896. %if_true = OpLabel
  897. %74 = OpExtInst %void %1 DebugScope %50
  898. OpLine %5 7 5
  899. %75 = OpExtInst %void %1 DebugNoScope
  900. OpReturnValue %32
  901. %if_merge = OpLabel
  902. %76 = OpExtInst %void %1 DebugScope %51
  903. OpLine %5 9 16
  904. %63 = OpLoad %float %arg1
  905. OpStore %param_var_arg2 %63
  906. OpLine %5 9 10
  907. %64 = OpFunctionCall %v4float %func2 %param_var_arg2
  908. OpLine %5 9 3
  909. %77 = OpExtInst %void %1 DebugNoScope
  910. OpReturnValue %64
  911. OpFunctionEnd
  912. OpLine %5 1 1
  913. %func2 = OpFunction %v4float None %38
  914. OpLine %5 1 20
  915. %arg2 = OpFunctionParameter %_ptr_Function_float
  916. %bb_entry_1 = OpLabel
  917. %78 = OpExtInst %void %1 DebugScope %49
  918. OpLine %5 2 17
  919. %67 = OpLoad %float %arg2
  920. %68 = OpCompositeConstruct %v4float %67 %float_0 %float_0 %float_0
  921. OpLine %5 2 3
  922. %79 = OpExtInst %void %1 DebugNoScope
  923. OpReturnValue %68
  924. OpFunctionEnd
  925. )";
  926. SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  927. std::unique_ptr<IRContext> context =
  928. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
  929. ASSERT_NE(nullptr, context);
  930. std::vector<uint32_t> binary;
  931. context->module()->ToBinary(&binary, /* skip_nop = */ false);
  932. std::string disassembled_text;
  933. EXPECT_TRUE(t.Disassemble(binary, &disassembled_text));
  934. EXPECT_EQ(text, disassembled_text);
  935. }
  936. TEST(IrBuilder, DebugInfoInstInFunctionOutOfBlock2) {
  937. // /* HLSL */
  938. //
  939. // struct VS_OUTPUT {
  940. // float4 pos : SV_POSITION;
  941. // float4 color : COLOR;
  942. // };
  943. //
  944. // VS_OUTPUT main(float4 pos : POSITION,
  945. // float4 color : COLOR) {
  946. // VS_OUTPUT vout;
  947. // vout.pos = pos;
  948. // vout.color = color;
  949. // return vout;
  950. // }
  951. const std::string text = R"(OpCapability Shader
  952. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  953. OpMemoryModel Logical GLSL450
  954. OpEntryPoint Vertex %main "main" %in_var_POSITION %in_var_COLOR %gl_Position %out_var_COLOR
  955. %7 = OpString "vs.hlsl"
  956. OpSource HLSL 600 %7 "#line 1 \"vs.hlsl\"
  957. struct VS_OUTPUT {
  958. float4 pos : SV_POSITION;
  959. float4 color : COLOR;
  960. };
  961. VS_OUTPUT main(float4 pos : POSITION,
  962. float4 color : COLOR) {
  963. VS_OUTPUT vout;
  964. vout.pos = pos;
  965. vout.color = color;
  966. return vout;
  967. }
  968. "
  969. %8 = OpString "#line 1 \"vs.hlsl\"
  970. struct VS_OUTPUT {
  971. float4 pos : SV_POSITION;
  972. float4 color : COLOR;
  973. };
  974. VS_OUTPUT main(float4 pos : POSITION,
  975. float4 color : COLOR) {
  976. VS_OUTPUT vout;
  977. vout.pos = pos;
  978. vout.color = color;
  979. return vout;
  980. }
  981. "
  982. %9 = OpString "VS_OUTPUT"
  983. %10 = OpString "float"
  984. %11 = OpString "src.main"
  985. %12 = OpString "pos"
  986. %13 = OpString "color"
  987. %14 = OpString "vout"
  988. OpName %in_var_POSITION "in.var.POSITION"
  989. OpName %in_var_COLOR "in.var.COLOR"
  990. OpName %out_var_COLOR "out.var.COLOR"
  991. OpName %main "main"
  992. OpName %param_var_pos "param.var.pos"
  993. OpName %param_var_color "param.var.color"
  994. OpName %VS_OUTPUT "VS_OUTPUT"
  995. OpMemberName %VS_OUTPUT 0 "pos"
  996. OpMemberName %VS_OUTPUT 1 "color"
  997. OpName %src_main "src.main"
  998. OpName %pos "pos"
  999. OpName %color "color"
  1000. OpName %bb_entry "bb.entry"
  1001. OpName %vout "vout"
  1002. OpDecorate %gl_Position BuiltIn Position
  1003. OpDecorate %in_var_POSITION Location 0
  1004. OpDecorate %in_var_COLOR Location 1
  1005. OpDecorate %out_var_COLOR Location 0
  1006. %int = OpTypeInt 32 1
  1007. %int_0 = OpConstant %int 0
  1008. %int_1 = OpConstant %int 1
  1009. %uint = OpTypeInt 32 0
  1010. %uint_32 = OpConstant %uint 32
  1011. %float = OpTypeFloat 32
  1012. %v4float = OpTypeVector %float 4
  1013. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1014. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1015. %void = OpTypeVoid
  1016. %uint_256 = OpConstant %uint 256
  1017. %uint_0 = OpConstant %uint 0
  1018. %uint_128 = OpConstant %uint 128
  1019. %36 = OpTypeFunction %void
  1020. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1021. %VS_OUTPUT = OpTypeStruct %v4float %v4float
  1022. %38 = OpTypeFunction %VS_OUTPUT %_ptr_Function_v4float %_ptr_Function_v4float
  1023. %_ptr_Function_VS_OUTPUT = OpTypePointer Function %VS_OUTPUT
  1024. OpLine %7 6 29
  1025. %in_var_POSITION = OpVariable %_ptr_Input_v4float Input
  1026. OpLine %7 7 31
  1027. %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
  1028. OpLine %7 2 16
  1029. %gl_Position = OpVariable %_ptr_Output_v4float Output
  1030. OpLine %7 3 18
  1031. %out_var_COLOR = OpVariable %_ptr_Output_v4float Output
  1032. %40 = OpExtInst %void %1 DebugExpression
  1033. %41 = OpExtInst %void %1 DebugSource %7 %8
  1034. %42 = OpExtInst %void %1 DebugCompilationUnit 1 4 %41 HLSL
  1035. %43 = OpExtInst %void %1 DebugTypeComposite %9 Structure %41 1 1 %42 %9 %uint_256 FlagIsProtected|FlagIsPrivate %44 %45
  1036. %46 = OpExtInst %void %1 DebugTypeBasic %10 %uint_32 Float
  1037. %47 = OpExtInst %void %1 DebugTypeVector %46 4
  1038. %48 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %47 %47
  1039. %49 = OpExtInst %void %1 DebugFunction %11 %48 %41 6 1 %42 %11 FlagIsProtected|FlagIsPrivate 7 %src_main
  1040. %50 = OpExtInst %void %1 DebugLocalVariable %12 %47 %41 6 23 %49 FlagIsLocal 0
  1041. %51 = OpExtInst %void %1 DebugLocalVariable %13 %47 %41 7 23 %49 FlagIsLocal 1
  1042. %52 = OpExtInst %void %1 DebugLexicalBlock %41 7 38 %49
  1043. %53 = OpExtInst %void %1 DebugLocalVariable %14 %43 %41 8 13 %52 FlagIsLocal
  1044. %44 = OpExtInst %void %1 DebugTypeMember %12 %47 %41 2 3 %43 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  1045. %45 = OpExtInst %void %1 DebugTypeMember %13 %47 %41 3 3 %43 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
  1046. OpLine %7 6 1
  1047. %main = OpFunction %void None %36
  1048. %54 = OpLabel
  1049. %74 = OpExtInst %void %1 DebugScope %42
  1050. OpLine %7 6 23
  1051. %param_var_pos = OpVariable %_ptr_Function_v4float Function
  1052. OpLine %7 7 23
  1053. %param_var_color = OpVariable %_ptr_Function_v4float Function
  1054. OpLine %7 6 23
  1055. %56 = OpLoad %v4float %in_var_POSITION
  1056. OpStore %param_var_pos %56
  1057. OpLine %7 7 23
  1058. %57 = OpLoad %v4float %in_var_COLOR
  1059. OpStore %param_var_color %57
  1060. OpLine %7 6 1
  1061. %58 = OpFunctionCall %VS_OUTPUT %src_main %param_var_pos %param_var_color
  1062. OpLine %7 6 11
  1063. %59 = OpCompositeExtract %v4float %58 0
  1064. OpLine %7 2 16
  1065. OpStore %gl_Position %59
  1066. OpLine %7 6 11
  1067. %60 = OpCompositeExtract %v4float %58 1
  1068. OpLine %7 3 18
  1069. OpStore %out_var_COLOR %60
  1070. %75 = OpExtInst %void %1 DebugNoScope
  1071. OpReturn
  1072. OpFunctionEnd
  1073. OpLine %7 6 1
  1074. %src_main = OpFunction %VS_OUTPUT None %38
  1075. %76 = OpExtInst %void %1 DebugScope %49
  1076. OpLine %7 6 23
  1077. %pos = OpFunctionParameter %_ptr_Function_v4float
  1078. OpLine %7 7 23
  1079. %color = OpFunctionParameter %_ptr_Function_v4float
  1080. %63 = OpExtInst %void %1 DebugDeclare %50 %pos %40
  1081. %64 = OpExtInst %void %1 DebugDeclare %51 %color %40
  1082. %77 = OpExtInst %void %1 DebugNoScope
  1083. %bb_entry = OpLabel
  1084. %78 = OpExtInst %void %1 DebugScope %52
  1085. OpLine %7 8 13
  1086. %vout = OpVariable %_ptr_Function_VS_OUTPUT Function
  1087. %67 = OpExtInst %void %1 DebugDeclare %53 %vout %40
  1088. OpLine %7 9 14
  1089. %68 = OpLoad %v4float %pos
  1090. OpLine %7 9 3
  1091. %69 = OpAccessChain %_ptr_Function_v4float %vout %int_0
  1092. OpStore %69 %68
  1093. OpLine %7 10 16
  1094. %70 = OpLoad %v4float %color
  1095. OpLine %7 10 3
  1096. %71 = OpAccessChain %_ptr_Function_v4float %vout %int_1
  1097. OpStore %71 %70
  1098. OpLine %7 11 10
  1099. %72 = OpLoad %VS_OUTPUT %vout
  1100. OpLine %7 11 3
  1101. %79 = OpExtInst %void %1 DebugNoScope
  1102. OpReturnValue %72
  1103. OpFunctionEnd
  1104. )";
  1105. SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  1106. std::unique_ptr<IRContext> context =
  1107. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
  1108. ASSERT_NE(nullptr, context);
  1109. std::vector<uint32_t> binary;
  1110. context->module()->ToBinary(&binary, /* skip_nop = */ false);
  1111. std::string disassembled_text;
  1112. EXPECT_TRUE(t.Disassemble(binary, &disassembled_text));
  1113. EXPECT_EQ(text, disassembled_text);
  1114. }
  1115. TEST(IrBuilder, DebugInfoForTerminationInsts) {
  1116. // Check that DebugScope instructions for termination instructions are
  1117. // preserved.
  1118. DoRoundTripCheck(R"(OpCapability Shader
  1119. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  1120. OpMemoryModel Logical GLSL450
  1121. OpEntryPoint Fragment %main "main"
  1122. OpExecutionMode %main OriginUpperLeft
  1123. %3 = OpString "simple_vs.hlsl"
  1124. OpSource HLSL 600 %3
  1125. OpName %main "main"
  1126. %void = OpTypeVoid
  1127. %5 = OpTypeFunction %void
  1128. %6 = OpExtInst %void %1 DebugSource %3
  1129. %7 = OpExtInst %void %1 DebugCompilationUnit 2 4 %6 HLSL
  1130. %main = OpFunction %void None %5
  1131. %8 = OpLabel
  1132. %20 = OpExtInst %void %1 DebugScope %7
  1133. OpBranch %10
  1134. %21 = OpExtInst %void %1 DebugNoScope
  1135. %10 = OpLabel
  1136. %22 = OpExtInst %void %1 DebugScope %7
  1137. OpKill
  1138. %23 = OpExtInst %void %1 DebugNoScope
  1139. %14 = OpLabel
  1140. %24 = OpExtInst %void %1 DebugScope %7
  1141. OpUnreachable
  1142. %25 = OpExtInst %void %1 DebugNoScope
  1143. %17 = OpLabel
  1144. %26 = OpExtInst %void %1 DebugScope %7
  1145. OpReturn
  1146. %27 = OpExtInst %void %1 DebugNoScope
  1147. OpFunctionEnd
  1148. )");
  1149. }
  1150. TEST(IrBuilder, LocalGlobalVariables) {
  1151. // #version 310 es
  1152. //
  1153. // float gv1 = 10.;
  1154. // float gv2 = 100.;
  1155. //
  1156. // float f() {
  1157. // float lv1 = gv1 + gv2;
  1158. // float lv2 = gv1 * gv2;
  1159. // return lv1 / lv2;
  1160. // }
  1161. //
  1162. // void main() {
  1163. // float lv1 = gv1 - gv2;
  1164. // }
  1165. DoRoundTripCheck(
  1166. // clang-format off
  1167. "OpCapability Shader\n"
  1168. "%1 = OpExtInstImport \"GLSL.std.450\"\n"
  1169. "OpMemoryModel Logical GLSL450\n"
  1170. "OpEntryPoint Vertex %main \"main\"\n"
  1171. "OpSource ESSL 310\n"
  1172. "OpName %main \"main\"\n"
  1173. "OpName %f_ \"f(\"\n"
  1174. "OpName %gv1 \"gv1\"\n"
  1175. "OpName %gv2 \"gv2\"\n"
  1176. "OpName %lv1 \"lv1\"\n"
  1177. "OpName %lv2 \"lv2\"\n"
  1178. "OpName %lv1_0 \"lv1\"\n"
  1179. "%void = OpTypeVoid\n"
  1180. "%10 = OpTypeFunction %void\n"
  1181. "%float = OpTypeFloat 32\n"
  1182. "%12 = OpTypeFunction %float\n"
  1183. "%_ptr_Private_float = OpTypePointer Private %float\n"
  1184. "%gv1 = OpVariable %_ptr_Private_float Private\n"
  1185. "%float_10 = OpConstant %float 10\n"
  1186. "%gv2 = OpVariable %_ptr_Private_float Private\n"
  1187. "%float_100 = OpConstant %float 100\n"
  1188. "%_ptr_Function_float = OpTypePointer Function %float\n"
  1189. "%main = OpFunction %void None %10\n"
  1190. "%17 = OpLabel\n"
  1191. "%lv1_0 = OpVariable %_ptr_Function_float Function\n"
  1192. "OpStore %gv1 %float_10\n"
  1193. "OpStore %gv2 %float_100\n"
  1194. "%18 = OpLoad %float %gv1\n"
  1195. "%19 = OpLoad %float %gv2\n"
  1196. "%20 = OpFSub %float %18 %19\n"
  1197. "OpStore %lv1_0 %20\n"
  1198. "OpReturn\n"
  1199. "OpFunctionEnd\n"
  1200. "%f_ = OpFunction %float None %12\n"
  1201. "%21 = OpLabel\n"
  1202. "%lv1 = OpVariable %_ptr_Function_float Function\n"
  1203. "%lv2 = OpVariable %_ptr_Function_float Function\n"
  1204. "%22 = OpLoad %float %gv1\n"
  1205. "%23 = OpLoad %float %gv2\n"
  1206. "%24 = OpFAdd %float %22 %23\n"
  1207. "OpStore %lv1 %24\n"
  1208. "%25 = OpLoad %float %gv1\n"
  1209. "%26 = OpLoad %float %gv2\n"
  1210. "%27 = OpFMul %float %25 %26\n"
  1211. "OpStore %lv2 %27\n"
  1212. "%28 = OpLoad %float %lv1\n"
  1213. "%29 = OpLoad %float %lv2\n"
  1214. "%30 = OpFDiv %float %28 %29\n"
  1215. "OpReturnValue %30\n"
  1216. "OpFunctionEnd\n");
  1217. // clang-format on
  1218. }
  1219. TEST(IrBuilder, OpUndefOutsideFunction) {
  1220. // #version 310 es
  1221. // void main() {}
  1222. const std::string text =
  1223. // clang-format off
  1224. "OpMemoryModel Logical GLSL450\n"
  1225. "%int = OpTypeInt 32 1\n"
  1226. "%uint = OpTypeInt 32 0\n"
  1227. "%float = OpTypeFloat 32\n"
  1228. "%4 = OpUndef %int\n"
  1229. "%int_10 = OpConstant %int 10\n"
  1230. "%6 = OpUndef %uint\n"
  1231. "%bool = OpTypeBool\n"
  1232. "%8 = OpUndef %float\n"
  1233. "%double = OpTypeFloat 64\n";
  1234. // clang-format on
  1235. SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  1236. std::unique_ptr<IRContext> context =
  1237. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
  1238. ASSERT_NE(nullptr, context);
  1239. const auto opundef_count = std::count_if(
  1240. context->module()->types_values_begin(),
  1241. context->module()->types_values_end(), [](const Instruction& inst) {
  1242. return inst.opcode() == spv::Op::OpUndef;
  1243. });
  1244. EXPECT_EQ(3, opundef_count);
  1245. std::vector<uint32_t> binary;
  1246. context->module()->ToBinary(&binary, /* skip_nop = */ false);
  1247. std::string disassembled_text;
  1248. EXPECT_TRUE(t.Disassemble(binary, &disassembled_text));
  1249. EXPECT_EQ(text, disassembled_text);
  1250. }
  1251. TEST(IrBuilder, OpUndefInBasicBlock) {
  1252. DoRoundTripCheck(
  1253. // clang-format off
  1254. "OpMemoryModel Logical GLSL450\n"
  1255. "OpName %main \"main\"\n"
  1256. "%void = OpTypeVoid\n"
  1257. "%uint = OpTypeInt 32 0\n"
  1258. "%double = OpTypeFloat 64\n"
  1259. "%5 = OpTypeFunction %void\n"
  1260. "%main = OpFunction %void None %5\n"
  1261. "%6 = OpLabel\n"
  1262. "%7 = OpUndef %uint\n"
  1263. "%8 = OpUndef %double\n"
  1264. "OpReturn\n"
  1265. "OpFunctionEnd\n");
  1266. // clang-format on
  1267. }
  1268. TEST(IrBuilder, KeepLineDebugInfoBeforeType) {
  1269. DoRoundTripCheck(
  1270. // clang-format off
  1271. "OpCapability Shader\n"
  1272. "OpMemoryModel Logical GLSL450\n"
  1273. "%1 = OpString \"minimal.vert\"\n"
  1274. "OpLine %1 1 1\n"
  1275. "OpNoLine\n"
  1276. "%void = OpTypeVoid\n"
  1277. "OpLine %1 2 2\n"
  1278. "%3 = OpTypeFunction %void\n");
  1279. // clang-format on
  1280. }
  1281. TEST(IrBuilder, KeepLineDebugInfoBeforeLabel) {
  1282. DoRoundTripCheck(
  1283. // clang-format off
  1284. "OpCapability Shader\n"
  1285. "OpMemoryModel Logical GLSL450\n"
  1286. "%1 = OpString \"minimal.vert\"\n"
  1287. "%void = OpTypeVoid\n"
  1288. "%3 = OpTypeFunction %void\n"
  1289. "%4 = OpFunction %void None %3\n"
  1290. "%5 = OpLabel\n"
  1291. "OpBranch %6\n"
  1292. "OpLine %1 1 1\n"
  1293. "OpLine %1 2 2\n"
  1294. "%6 = OpLabel\n"
  1295. "OpBranch %7\n"
  1296. "OpLine %1 100 100\n"
  1297. "%7 = OpLabel\n"
  1298. "OpReturn\n"
  1299. "OpFunctionEnd\n");
  1300. // clang-format on
  1301. }
  1302. TEST(IrBuilder, KeepLineDebugInfoBeforeFunctionEnd) {
  1303. DoRoundTripCheck(
  1304. // clang-format off
  1305. "OpCapability Shader\n"
  1306. "OpMemoryModel Logical GLSL450\n"
  1307. "%1 = OpString \"minimal.vert\"\n"
  1308. "%void = OpTypeVoid\n"
  1309. "%3 = OpTypeFunction %void\n"
  1310. "%4 = OpFunction %void None %3\n"
  1311. "OpLine %1 1 1\n"
  1312. "OpLine %1 2 2\n"
  1313. "OpFunctionEnd\n");
  1314. // clang-format on
  1315. }
  1316. TEST(IrBuilder, KeepModuleProcessedInRightPlace) {
  1317. DoRoundTripCheck(
  1318. // clang-format off
  1319. "OpCapability Shader\n"
  1320. "OpMemoryModel Logical GLSL450\n"
  1321. "%1 = OpString \"minimal.vert\"\n"
  1322. "OpName %void \"void\"\n"
  1323. "OpModuleProcessed \"Made it faster\"\n"
  1324. "OpModuleProcessed \".. and smaller\"\n"
  1325. "%void = OpTypeVoid\n");
  1326. // clang-format on
  1327. }
  1328. // Checks the given |error_message| is reported when trying to build a module
  1329. // from the given |assembly|.
  1330. void DoErrorMessageCheck(const std::string& assembly,
  1331. const std::string& error_message, uint32_t line_num) {
  1332. auto consumer = [error_message, line_num](spv_message_level_t, const char*,
  1333. const spv_position_t& position,
  1334. const char* m) {
  1335. EXPECT_EQ(error_message, m);
  1336. EXPECT_EQ(line_num, position.line);
  1337. };
  1338. SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  1339. std::unique_ptr<IRContext> context =
  1340. BuildModule(SPV_ENV_UNIVERSAL_1_1, std::move(consumer), assembly);
  1341. EXPECT_EQ(nullptr, context);
  1342. }
  1343. TEST(IrBuilder, FunctionInsideFunction) {
  1344. DoErrorMessageCheck("%2 = OpFunction %1 None %3\n%5 = OpFunction %4 None %6",
  1345. "function inside function", 2);
  1346. }
  1347. TEST(IrBuilder, MismatchOpFunctionEnd) {
  1348. DoErrorMessageCheck("OpFunctionEnd",
  1349. "OpFunctionEnd without corresponding OpFunction", 1);
  1350. }
  1351. TEST(IrBuilder, OpFunctionEndInsideBasicBlock) {
  1352. DoErrorMessageCheck(
  1353. "%2 = OpFunction %1 None %3\n"
  1354. "%4 = OpLabel\n"
  1355. "OpFunctionEnd",
  1356. "OpFunctionEnd inside basic block", 3);
  1357. }
  1358. TEST(IrBuilder, BasicBlockOutsideFunction) {
  1359. DoErrorMessageCheck("OpCapability Shader\n%1 = OpLabel",
  1360. "OpLabel outside function", 2);
  1361. }
  1362. TEST(IrBuilder, OpLabelInsideBasicBlock) {
  1363. DoErrorMessageCheck(
  1364. "%2 = OpFunction %1 None %3\n"
  1365. "%4 = OpLabel\n"
  1366. "%5 = OpLabel",
  1367. "OpLabel inside basic block", 3);
  1368. }
  1369. TEST(IrBuilder, TerminatorOutsideFunction) {
  1370. DoErrorMessageCheck("OpReturn", "terminator instruction outside function", 1);
  1371. }
  1372. TEST(IrBuilder, TerminatorOutsideBasicBlock) {
  1373. DoErrorMessageCheck("%2 = OpFunction %1 None %3\nOpReturn",
  1374. "terminator instruction outside basic block", 2);
  1375. }
  1376. TEST(IrBuilder, NotAllowedInstAppearingInFunction) {
  1377. DoErrorMessageCheck("%2 = OpFunction %1 None %3\n%5 = OpVariable %4 Function",
  1378. "Non-OpFunctionParameter (opcode: 59) found inside "
  1379. "function but outside basic block",
  1380. 2);
  1381. }
  1382. TEST(IrBuilder, UniqueIds) {
  1383. const std::string text =
  1384. // clang-format off
  1385. "OpCapability Shader\n"
  1386. "%1 = OpExtInstImport \"GLSL.std.450\"\n"
  1387. "OpMemoryModel Logical GLSL450\n"
  1388. "OpEntryPoint Vertex %main \"main\"\n"
  1389. "OpSource ESSL 310\n"
  1390. "OpName %main \"main\"\n"
  1391. "OpName %f_ \"f(\"\n"
  1392. "OpName %gv1 \"gv1\"\n"
  1393. "OpName %gv2 \"gv2\"\n"
  1394. "OpName %lv1 \"lv1\"\n"
  1395. "OpName %lv2 \"lv2\"\n"
  1396. "OpName %lv1_0 \"lv1\"\n"
  1397. "%void = OpTypeVoid\n"
  1398. "%10 = OpTypeFunction %void\n"
  1399. "%float = OpTypeFloat 32\n"
  1400. "%12 = OpTypeFunction %float\n"
  1401. "%_ptr_Private_float = OpTypePointer Private %float\n"
  1402. "%gv1 = OpVariable %_ptr_Private_float Private\n"
  1403. "%float_10 = OpConstant %float 10\n"
  1404. "%gv2 = OpVariable %_ptr_Private_float Private\n"
  1405. "%float_100 = OpConstant %float 100\n"
  1406. "%_ptr_Function_float = OpTypePointer Function %float\n"
  1407. "%main = OpFunction %void None %10\n"
  1408. "%17 = OpLabel\n"
  1409. "%lv1_0 = OpVariable %_ptr_Function_float Function\n"
  1410. "OpStore %gv1 %float_10\n"
  1411. "OpStore %gv2 %float_100\n"
  1412. "%18 = OpLoad %float %gv1\n"
  1413. "%19 = OpLoad %float %gv2\n"
  1414. "%20 = OpFSub %float %18 %19\n"
  1415. "OpStore %lv1_0 %20\n"
  1416. "OpReturn\n"
  1417. "OpFunctionEnd\n"
  1418. "%f_ = OpFunction %float None %12\n"
  1419. "%21 = OpLabel\n"
  1420. "%lv1 = OpVariable %_ptr_Function_float Function\n"
  1421. "%lv2 = OpVariable %_ptr_Function_float Function\n"
  1422. "%22 = OpLoad %float %gv1\n"
  1423. "%23 = OpLoad %float %gv2\n"
  1424. "%24 = OpFAdd %float %22 %23\n"
  1425. "OpStore %lv1 %24\n"
  1426. "%25 = OpLoad %float %gv1\n"
  1427. "%26 = OpLoad %float %gv2\n"
  1428. "%27 = OpFMul %float %25 %26\n"
  1429. "OpStore %lv2 %27\n"
  1430. "%28 = OpLoad %float %lv1\n"
  1431. "%29 = OpLoad %float %lv2\n"
  1432. "%30 = OpFDiv %float %28 %29\n"
  1433. "OpReturnValue %30\n"
  1434. "OpFunctionEnd\n";
  1435. // clang-format on
  1436. std::unique_ptr<IRContext> context =
  1437. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
  1438. ASSERT_NE(nullptr, context);
  1439. std::unordered_set<uint32_t> ids;
  1440. context->module()->ForEachInst([&ids](const Instruction* inst) {
  1441. EXPECT_TRUE(ids.insert(inst->unique_id()).second);
  1442. });
  1443. }
  1444. } // namespace
  1445. } // namespace opt
  1446. } // namespace spvtools