ir_loader_test.cpp 48 KB

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