ir_loader_test.cpp 48 KB

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