fold_spec_const_op_composite_test.cpp 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395
  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 <sstream>
  15. #include <string>
  16. #include <vector>
  17. #include "test/opt/assembly_builder.h"
  18. #include "test/opt/pass_fixture.h"
  19. #include "test/opt/pass_utils.h"
  20. namespace spvtools {
  21. namespace opt {
  22. namespace {
  23. using FoldSpecConstantOpAndCompositePassBasicTest = PassTest<::testing::Test>;
  24. TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, Empty) {
  25. SinglePassRunAndCheck<FoldSpecConstantOpAndCompositePass>(
  26. "", "", /* skip_nop = */ true);
  27. }
  28. // A test of the basic functionality of FoldSpecConstantOpAndCompositePass.
  29. // A spec constant defined with an integer addition operation should be folded
  30. // to a normal constant with fixed value.
  31. TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, Basic) {
  32. AssemblyBuilder builder;
  33. builder.AppendTypesConstantsGlobals({
  34. // clang-format off
  35. "%int = OpTypeInt 32 1",
  36. "%frozen_spec_const_int = OpConstant %int 1",
  37. "%const_int = OpConstant %int 2",
  38. // Folding target:
  39. "%spec_add = OpSpecConstantOp %int IAdd %frozen_spec_const_int %const_int",
  40. // clang-format on
  41. });
  42. std::vector<const char*> expected = {
  43. // clang-format off
  44. "OpCapability Shader",
  45. "OpCapability Float64",
  46. "%1 = OpExtInstImport \"GLSL.std.450\"",
  47. "OpMemoryModel Logical GLSL450",
  48. "OpEntryPoint Vertex %main \"main\"",
  49. "OpName %void \"void\"",
  50. "OpName %main_func_type \"main_func_type\"",
  51. "OpName %main \"main\"",
  52. "OpName %main_func_entry_block \"main_func_entry_block\"",
  53. "OpName %int \"int\"",
  54. "OpName %frozen_spec_const_int \"frozen_spec_const_int\"",
  55. "OpName %const_int \"const_int\"",
  56. "OpName %spec_add \"spec_add\"",
  57. "%void = OpTypeVoid",
  58. "%main_func_type = OpTypeFunction %void",
  59. "%int = OpTypeInt 32 1",
  60. "%frozen_spec_const_int = OpConstant %int 1",
  61. "%const_int = OpConstant %int 2",
  62. // The SpecConstantOp IAdd instruction should be replace by OpConstant
  63. // instruction:
  64. "%spec_add = OpConstant %int 3",
  65. "%main = OpFunction %void None %main_func_type",
  66. "%main_func_entry_block = OpLabel",
  67. "OpReturn",
  68. "OpFunctionEnd",
  69. // clang-format on
  70. };
  71. SinglePassRunAndCheck<FoldSpecConstantOpAndCompositePass>(
  72. builder.GetCode(), JoinAllInsts(expected), /* skip_nop = */ true);
  73. }
  74. // A test of skipping folding an instruction when the instruction result type
  75. // has decorations.
  76. TEST_F(FoldSpecConstantOpAndCompositePassBasicTest,
  77. SkipWhenTypeHasDecorations) {
  78. AssemblyBuilder builder;
  79. builder
  80. .AppendAnnotations({
  81. // clang-format off
  82. "OpDecorate %int RelaxedPrecision",
  83. // clang-format on
  84. })
  85. .AppendTypesConstantsGlobals({
  86. // clang-format off
  87. "%int = OpTypeInt 32 1",
  88. "%frozen_spec_const_int = OpConstant %int 1",
  89. "%const_int = OpConstant %int 2",
  90. // The following spec constant should not be folded as the result type
  91. // has relaxed precision decoration.
  92. "%spec_add = OpSpecConstantOp %int IAdd %frozen_spec_const_int %const_int",
  93. // clang-format on
  94. });
  95. SinglePassRunAndCheck<FoldSpecConstantOpAndCompositePass>(
  96. builder.GetCode(), builder.GetCode(), /* skip_nop = */ true);
  97. }
  98. // All types and some common constants that are potentially required in
  99. // FoldSpecConstantOpAndCompositeTest.
  100. std::vector<std::string> CommonTypesAndConstants() {
  101. return std::vector<std::string>{
  102. // clang-format off
  103. // scalar types
  104. "%bool = OpTypeBool",
  105. "%uint = OpTypeInt 32 0",
  106. "%int = OpTypeInt 32 1",
  107. "%float = OpTypeFloat 32",
  108. "%double = OpTypeFloat 64",
  109. // vector types
  110. "%v2bool = OpTypeVector %bool 2",
  111. "%v2uint = OpTypeVector %uint 2",
  112. "%v2int = OpTypeVector %int 2",
  113. "%v3int = OpTypeVector %int 3",
  114. "%v4int = OpTypeVector %int 4",
  115. "%v2float = OpTypeVector %float 2",
  116. "%v2double = OpTypeVector %double 2",
  117. // variable pointer types
  118. "%_pf_bool = OpTypePointer Function %bool",
  119. "%_pf_uint = OpTypePointer Function %uint",
  120. "%_pf_int = OpTypePointer Function %int",
  121. "%_pf_float = OpTypePointer Function %float",
  122. "%_pf_double = OpTypePointer Function %double",
  123. "%_pf_v2int = OpTypePointer Function %v2int",
  124. "%_pf_v2float = OpTypePointer Function %v2float",
  125. "%_pf_v2double = OpTypePointer Function %v2double",
  126. // struct types
  127. "%inner_struct = OpTypeStruct %bool %int %float",
  128. "%outer_struct = OpTypeStruct %inner_struct %int",
  129. "%flat_struct = OpTypeStruct %bool %int %float",
  130. // common constants
  131. // scalar constants:
  132. "%bool_true = OpConstantTrue %bool",
  133. "%bool_false = OpConstantFalse %bool",
  134. "%bool_null = OpConstantNull %bool",
  135. "%signed_zero = OpConstant %int 0",
  136. "%unsigned_zero = OpConstant %uint 0",
  137. "%signed_one = OpConstant %int 1",
  138. "%unsigned_one = OpConstant %uint 1",
  139. "%signed_two = OpConstant %int 2",
  140. "%unsigned_two = OpConstant %uint 2",
  141. "%signed_three = OpConstant %int 3",
  142. "%unsigned_three = OpConstant %uint 3",
  143. "%signed_null = OpConstantNull %int",
  144. "%unsigned_null = OpConstantNull %uint",
  145. // vector constants:
  146. "%bool_true_vec = OpConstantComposite %v2bool %bool_true %bool_true",
  147. "%bool_false_vec = OpConstantComposite %v2bool %bool_false %bool_false",
  148. "%bool_null_vec = OpConstantNull %v2bool",
  149. "%signed_zero_vec = OpConstantComposite %v2int %signed_zero %signed_zero",
  150. "%unsigned_zero_vec = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
  151. "%signed_one_vec = OpConstantComposite %v2int %signed_one %signed_one",
  152. "%unsigned_one_vec = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
  153. "%signed_two_vec = OpConstantComposite %v2int %signed_two %signed_two",
  154. "%unsigned_two_vec = OpConstantComposite %v2uint %unsigned_two %unsigned_two",
  155. "%signed_three_vec = OpConstantComposite %v2int %signed_three %signed_three",
  156. "%unsigned_three_vec = OpConstantComposite %v2uint %unsigned_three %unsigned_three",
  157. "%signed_null_vec = OpConstantNull %v2int",
  158. "%unsigned_null_vec = OpConstantNull %v2uint",
  159. "%v4int_0_1_2_3 = OpConstantComposite %v4int %signed_zero %signed_one %signed_two %signed_three",
  160. // clang-format on
  161. };
  162. }
  163. // A helper function to strip OpName instructions from the given string of
  164. // disassembly code. Returns the string with all OpName instruction stripped.
  165. std::string StripOpNameInstructions(const std::string& str) {
  166. std::stringstream ss(str);
  167. std::ostringstream oss;
  168. std::string inst_str;
  169. while (std::getline(ss, inst_str, '\n')) {
  170. if (inst_str.find("OpName %") == std::string::npos) {
  171. oss << inst_str << '\n';
  172. }
  173. }
  174. return oss.str();
  175. }
  176. struct FoldSpecConstantOpAndCompositePassTestCase {
  177. // Original constants with unfolded spec constants.
  178. std::vector<std::string> original;
  179. // Expected cosntants after folding.
  180. std::vector<std::string> expected;
  181. };
  182. using FoldSpecConstantOpAndCompositePassTest = PassTest<
  183. ::testing::TestWithParam<FoldSpecConstantOpAndCompositePassTestCase>>;
  184. TEST_P(FoldSpecConstantOpAndCompositePassTest, ParamTestCase) {
  185. AssemblyBuilder test_code_builder, expected_code_builder;
  186. const auto& tc = GetParam();
  187. test_code_builder.AppendTypesConstantsGlobals(CommonTypesAndConstants());
  188. test_code_builder.AppendTypesConstantsGlobals(tc.original);
  189. expected_code_builder.AppendTypesConstantsGlobals(CommonTypesAndConstants());
  190. expected_code_builder.AppendTypesConstantsGlobals(tc.expected);
  191. const std::string original = test_code_builder.GetCode();
  192. const std::string expected = expected_code_builder.GetCode();
  193. // Run the optimization and get the result code in disassembly.
  194. std::string optimized;
  195. auto status = Pass::Status::SuccessWithoutChange;
  196. std::tie(optimized, status) =
  197. SinglePassRunAndDisassemble<FoldSpecConstantOpAndCompositePass>(
  198. original, /* skip_nop = */ true, /* do_validation = */ false);
  199. // Check the optimized code, but ignore the OpName instructions.
  200. EXPECT_NE(Pass::Status::Failure, status);
  201. EXPECT_EQ(
  202. StripOpNameInstructions(expected) == StripOpNameInstructions(original),
  203. status == Pass::Status::SuccessWithoutChange);
  204. EXPECT_EQ(StripOpNameInstructions(expected),
  205. StripOpNameInstructions(optimized));
  206. }
  207. // Tests that OpSpecConstantComposite opcodes are replace with
  208. // OpConstantComposite correctly.
  209. INSTANTIATE_TEST_SUITE_P(
  210. Composite, FoldSpecConstantOpAndCompositePassTest,
  211. ::testing::ValuesIn(std::vector<
  212. FoldSpecConstantOpAndCompositePassTestCase>({
  213. // clang-format off
  214. // normal vector
  215. {
  216. // original
  217. {
  218. "%spec_v2bool = OpSpecConstantComposite %v2bool %bool_true %bool_false",
  219. "%spec_v2uint = OpSpecConstantComposite %v2uint %unsigned_one %unsigned_one",
  220. "%spec_v2int_a = OpSpecConstantComposite %v2int %signed_one %signed_two",
  221. // Spec constants whose value can not be fully resolved should
  222. // not be processed.
  223. "%spec_int = OpSpecConstant %int 99",
  224. "%spec_v2int_b = OpSpecConstantComposite %v2int %signed_one %spec_int",
  225. },
  226. // expected
  227. {
  228. "%spec_v2bool = OpConstantComposite %v2bool %bool_true %bool_false",
  229. "%spec_v2uint = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
  230. "%spec_v2int_a = OpConstantComposite %v2int %signed_one %signed_two",
  231. "%spec_int = OpSpecConstant %int 99",
  232. "%spec_v2int_b = OpSpecConstantComposite %v2int %signed_one %spec_int",
  233. },
  234. },
  235. // vector with null constants
  236. {
  237. // original
  238. {
  239. "%null_bool = OpConstantNull %bool",
  240. "%null_int = OpConstantNull %int",
  241. "%spec_v2bool = OpSpecConstantComposite %v2bool %null_bool %null_bool",
  242. "%spec_v3int = OpSpecConstantComposite %v3int %null_int %null_int %null_int",
  243. "%spec_v4int = OpSpecConstantComposite %v4int %null_int %null_int %null_int %null_int",
  244. },
  245. // expected
  246. {
  247. "%null_bool = OpConstantNull %bool",
  248. "%null_int = OpConstantNull %int",
  249. "%spec_v2bool = OpConstantComposite %v2bool %null_bool %null_bool",
  250. "%spec_v3int = OpConstantComposite %v3int %null_int %null_int %null_int",
  251. "%spec_v4int = OpConstantComposite %v4int %null_int %null_int %null_int %null_int",
  252. },
  253. },
  254. // flat struct
  255. {
  256. // original
  257. {
  258. "%float_1 = OpConstant %float 1",
  259. "%flat_1 = OpSpecConstantComposite %flat_struct %bool_true %signed_null %float_1",
  260. // following struct should not be folded as the value of
  261. // %spec_float is not determined.
  262. "%spec_float = OpSpecConstant %float 1",
  263. "%flat_2 = OpSpecConstantComposite %flat_struct %bool_true %signed_one %spec_float",
  264. },
  265. // expected
  266. {
  267. "%float_1 = OpConstant %float 1",
  268. "%flat_1 = OpConstantComposite %flat_struct %bool_true %signed_null %float_1",
  269. "%spec_float = OpSpecConstant %float 1",
  270. "%flat_2 = OpSpecConstantComposite %flat_struct %bool_true %signed_one %spec_float",
  271. }
  272. },
  273. // nested struct
  274. {
  275. // original
  276. {
  277. "%float_1 = OpConstant %float 1",
  278. "%inner_1 = OpSpecConstantComposite %inner_struct %bool_true %signed_null %float_1",
  279. "%outer_1 = OpSpecConstantComposite %outer_struct %inner_1 %signed_one",
  280. // following structs should not be folded as the value of
  281. // %spec_float is not determined.
  282. "%spec_float = OpSpecConstant %float 1",
  283. "%inner_2 = OpSpecConstantComposite %inner_struct %bool_true %signed_null %spec_float",
  284. "%outer_2 = OpSpecConstantComposite %outer_struct %inner_2 %signed_one",
  285. },
  286. // expected
  287. {
  288. "%float_1 = OpConstant %float 1",
  289. "%inner_1 = OpConstantComposite %inner_struct %bool_true %signed_null %float_1",
  290. "%outer_1 = OpConstantComposite %outer_struct %inner_1 %signed_one",
  291. "%spec_float = OpSpecConstant %float 1",
  292. "%inner_2 = OpSpecConstantComposite %inner_struct %bool_true %signed_null %spec_float",
  293. "%outer_2 = OpSpecConstantComposite %outer_struct %inner_2 %signed_one",
  294. }
  295. },
  296. // composite constants touched by OpUndef should be skipped
  297. {
  298. // original
  299. {
  300. "%undef = OpUndef %float",
  301. "%inner = OpConstantComposite %inner_struct %bool_true %signed_one %undef",
  302. "%outer = OpSpecConstantComposite %outer_struct %inner %signed_one",
  303. },
  304. // expected
  305. {
  306. "%undef = OpUndef %float",
  307. "%inner = OpConstantComposite %inner_struct %bool_true %signed_one %undef",
  308. "%outer = OpSpecConstantComposite %outer_struct %inner %signed_one",
  309. },
  310. }
  311. // clang-format on
  312. })));
  313. // Tests for operations that resulting in different types.
  314. INSTANTIATE_TEST_SUITE_P(
  315. Cast, FoldSpecConstantOpAndCompositePassTest,
  316. ::testing::ValuesIn(
  317. std::vector<FoldSpecConstantOpAndCompositePassTestCase>({
  318. // clang-format off
  319. // int -> bool scalar
  320. {
  321. // original
  322. {
  323. "%spec_bool_t = OpSpecConstantOp %bool INotEqual %signed_three %signed_zero",
  324. "%spec_bool_f = OpSpecConstantOp %bool INotEqual %signed_zero %signed_zero",
  325. "%spec_bool_from_null = OpSpecConstantOp %bool INotEqual %signed_null %signed_zero",
  326. },
  327. // expected
  328. {
  329. "%spec_bool_t = OpConstantTrue %bool",
  330. "%spec_bool_f = OpConstantFalse %bool",
  331. "%spec_bool_from_null = OpConstantFalse %bool",
  332. },
  333. },
  334. // uint -> bool scalar
  335. {
  336. // original
  337. {
  338. "%spec_bool_t = OpSpecConstantOp %bool INotEqual %unsigned_three %unsigned_zero",
  339. "%spec_bool_f = OpSpecConstantOp %bool INotEqual %unsigned_zero %unsigned_zero",
  340. "%spec_bool_from_null = OpSpecConstantOp %bool INotEqual %unsigned_null %unsigned_zero",
  341. },
  342. // expected
  343. {
  344. "%spec_bool_t = OpConstantTrue %bool",
  345. "%spec_bool_f = OpConstantFalse %bool",
  346. "%spec_bool_from_null = OpConstantFalse %bool",
  347. },
  348. },
  349. // bool -> int scalar
  350. {
  351. // original
  352. {
  353. "%spec_int_one = OpSpecConstantOp %int Select %bool_true %signed_one %signed_zero",
  354. "%spec_int_zero = OpSpecConstantOp %int Select %bool_false %signed_one %signed_zero",
  355. "%spec_int_from_null = OpSpecConstantOp %int Select %bool_null %signed_one %signed_zero",
  356. },
  357. // expected
  358. {
  359. "%spec_int_one = OpConstant %int 1",
  360. "%spec_int_zero = OpConstant %int 0",
  361. "%spec_int_from_null = OpConstant %int 0",
  362. },
  363. },
  364. // uint -> int scalar
  365. {
  366. // original
  367. {
  368. "%spec_int_one = OpSpecConstantOp %int IAdd %unsigned_one %signed_zero",
  369. "%spec_int_zero = OpSpecConstantOp %int IAdd %unsigned_zero %signed_zero",
  370. "%spec_int_from_null = OpSpecConstantOp %int IAdd %unsigned_null %unsigned_zero",
  371. },
  372. // expected
  373. {
  374. "%spec_int_one = OpConstant %int 1",
  375. "%spec_int_zero = OpConstant %int 0",
  376. "%spec_int_from_null = OpConstant %int 0",
  377. },
  378. },
  379. // bool -> uint scalar
  380. {
  381. // original
  382. {
  383. "%spec_uint_one = OpSpecConstantOp %uint Select %bool_true %unsigned_one %unsigned_zero",
  384. "%spec_uint_zero = OpSpecConstantOp %uint Select %bool_false %unsigned_one %unsigned_zero",
  385. "%spec_uint_from_null = OpSpecConstantOp %uint Select %bool_null %unsigned_one %unsigned_zero",
  386. },
  387. // expected
  388. {
  389. "%spec_uint_one = OpConstant %uint 1",
  390. "%spec_uint_zero = OpConstant %uint 0",
  391. "%spec_uint_from_null = OpConstant %uint 0",
  392. },
  393. },
  394. // int -> uint scalar
  395. {
  396. // original
  397. {
  398. "%spec_uint_one = OpSpecConstantOp %uint IAdd %signed_one %unsigned_zero",
  399. "%spec_uint_zero = OpSpecConstantOp %uint IAdd %signed_zero %unsigned_zero",
  400. "%spec_uint_from_null = OpSpecConstantOp %uint IAdd %signed_null %unsigned_zero",
  401. },
  402. // expected
  403. {
  404. "%spec_uint_one = OpConstant %uint 1",
  405. "%spec_uint_zero = OpConstant %uint 0",
  406. "%spec_uint_from_null = OpConstant %uint 0",
  407. },
  408. },
  409. // int -> bool vector
  410. {
  411. // original
  412. {
  413. "%spec_bool_t_vec = OpSpecConstantOp %v2bool INotEqual %signed_three_vec %signed_zero_vec",
  414. "%spec_bool_f_vec = OpSpecConstantOp %v2bool INotEqual %signed_zero_vec %signed_zero_vec",
  415. "%spec_bool_from_null = OpSpecConstantOp %v2bool INotEqual %signed_null_vec %signed_zero_vec",
  416. },
  417. // expected
  418. {
  419. "%true = OpConstantTrue %bool",
  420. "%true_0 = OpConstantTrue %bool",
  421. "%spec_bool_t_vec = OpConstantComposite %v2bool %bool_true %bool_true",
  422. "%false = OpConstantFalse %bool",
  423. "%false_0 = OpConstantFalse %bool",
  424. "%spec_bool_f_vec = OpConstantComposite %v2bool %bool_false %bool_false",
  425. "%false_1 = OpConstantFalse %bool",
  426. "%false_2 = OpConstantFalse %bool",
  427. "%spec_bool_from_null = OpConstantComposite %v2bool %bool_false %bool_false",
  428. },
  429. },
  430. // uint -> bool vector
  431. {
  432. // original
  433. {
  434. "%spec_bool_t_vec = OpSpecConstantOp %v2bool INotEqual %unsigned_three_vec %unsigned_zero_vec",
  435. "%spec_bool_f_vec = OpSpecConstantOp %v2bool INotEqual %unsigned_zero_vec %unsigned_zero_vec",
  436. "%spec_bool_from_null = OpSpecConstantOp %v2bool INotEqual %unsigned_null_vec %unsigned_zero_vec",
  437. },
  438. // expected
  439. {
  440. "%true = OpConstantTrue %bool",
  441. "%true_0 = OpConstantTrue %bool",
  442. "%spec_bool_t_vec = OpConstantComposite %v2bool %bool_true %bool_true",
  443. "%false = OpConstantFalse %bool",
  444. "%false_0 = OpConstantFalse %bool",
  445. "%spec_bool_f_vec = OpConstantComposite %v2bool %bool_false %bool_false",
  446. "%false_1 = OpConstantFalse %bool",
  447. "%false_2 = OpConstantFalse %bool",
  448. "%spec_bool_from_null = OpConstantComposite %v2bool %bool_false %bool_false",
  449. },
  450. },
  451. // bool -> int vector
  452. {
  453. // original
  454. {
  455. "%spec_int_one_vec = OpSpecConstantOp %v2int Select %bool_true_vec %signed_one_vec %signed_zero_vec",
  456. "%spec_int_zero_vec = OpSpecConstantOp %v2int Select %bool_false_vec %signed_one_vec %signed_zero_vec",
  457. "%spec_int_from_null = OpSpecConstantOp %v2int Select %bool_null_vec %signed_one_vec %signed_zero_vec",
  458. },
  459. // expected
  460. {
  461. "%int_1 = OpConstant %int 1",
  462. "%int_1_0 = OpConstant %int 1",
  463. "%spec_int_one_vec = OpConstantComposite %v2int %signed_one %signed_one",
  464. "%int_0 = OpConstant %int 0",
  465. "%int_0_0 = OpConstant %int 0",
  466. "%spec_int_zero_vec = OpConstantComposite %v2int %signed_zero %signed_zero",
  467. "%int_0_1 = OpConstant %int 0",
  468. "%int_0_2 = OpConstant %int 0",
  469. "%spec_int_from_null = OpConstantComposite %v2int %signed_zero %signed_zero",
  470. },
  471. },
  472. // uint -> int vector
  473. {
  474. // original
  475. {
  476. "%spec_int_one_vec = OpSpecConstantOp %v2int IAdd %unsigned_one_vec %signed_zero_vec",
  477. "%spec_int_zero_vec = OpSpecConstantOp %v2int IAdd %unsigned_zero_vec %signed_zero_vec",
  478. "%spec_int_from_null = OpSpecConstantOp %v2int IAdd %unsigned_null_vec %signed_zero_vec",
  479. },
  480. // expected
  481. {
  482. "%int_1 = OpConstant %int 1",
  483. "%int_1_0 = OpConstant %int 1",
  484. "%spec_int_one_vec = OpConstantComposite %v2int %signed_one %signed_one",
  485. "%int_0 = OpConstant %int 0",
  486. "%int_0_0 = OpConstant %int 0",
  487. "%spec_int_zero_vec = OpConstantComposite %v2int %signed_zero %signed_zero",
  488. "%int_0_1 = OpConstant %int 0",
  489. "%int_0_2 = OpConstant %int 0",
  490. "%spec_int_from_null = OpConstantComposite %v2int %signed_zero %signed_zero",
  491. },
  492. },
  493. // bool -> uint vector
  494. {
  495. // original
  496. {
  497. "%spec_uint_one_vec = OpSpecConstantOp %v2uint Select %bool_true_vec %unsigned_one_vec %unsigned_zero_vec",
  498. "%spec_uint_zero_vec = OpSpecConstantOp %v2uint Select %bool_false_vec %unsigned_one_vec %unsigned_zero_vec",
  499. "%spec_uint_from_null = OpSpecConstantOp %v2uint Select %bool_null_vec %unsigned_one_vec %unsigned_zero_vec",
  500. },
  501. // expected
  502. {
  503. "%uint_1 = OpConstant %uint 1",
  504. "%uint_1_0 = OpConstant %uint 1",
  505. "%spec_uint_one_vec = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
  506. "%uint_0 = OpConstant %uint 0",
  507. "%uint_0_0 = OpConstant %uint 0",
  508. "%spec_uint_zero_vec = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
  509. "%uint_0_1 = OpConstant %uint 0",
  510. "%uint_0_2 = OpConstant %uint 0",
  511. "%spec_uint_from_null = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
  512. },
  513. },
  514. // int -> uint vector
  515. {
  516. // original
  517. {
  518. "%spec_uint_one_vec = OpSpecConstantOp %v2uint IAdd %signed_one_vec %unsigned_zero_vec",
  519. "%spec_uint_zero_vec = OpSpecConstantOp %v2uint IAdd %signed_zero_vec %unsigned_zero_vec",
  520. "%spec_uint_from_null = OpSpecConstantOp %v2uint IAdd %signed_null_vec %unsigned_zero_vec",
  521. },
  522. // expected
  523. {
  524. "%uint_1 = OpConstant %uint 1",
  525. "%uint_1_0 = OpConstant %uint 1",
  526. "%spec_uint_one_vec = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
  527. "%uint_0 = OpConstant %uint 0",
  528. "%uint_0_0 = OpConstant %uint 0",
  529. "%spec_uint_zero_vec = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
  530. "%uint_0_1 = OpConstant %uint 0",
  531. "%uint_0_2 = OpConstant %uint 0",
  532. "%spec_uint_from_null = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
  533. },
  534. },
  535. // clang-format on
  536. })));
  537. // Tests about boolean scalar logical operations and comparison operations with
  538. // scalar int/uint type.
  539. INSTANTIATE_TEST_SUITE_P(
  540. Logical, FoldSpecConstantOpAndCompositePassTest,
  541. ::testing::ValuesIn(std::vector<
  542. FoldSpecConstantOpAndCompositePassTestCase>({
  543. // clang-format off
  544. // scalar integer comparison
  545. {
  546. // original
  547. {
  548. "%int_minus_1 = OpConstant %int -1",
  549. "%slt_0_1 = OpSpecConstantOp %bool SLessThan %signed_zero %signed_one",
  550. "%sgt_0_1 = OpSpecConstantOp %bool SGreaterThan %signed_zero %signed_one",
  551. "%sle_2_2 = OpSpecConstantOp %bool SLessThanEqual %signed_two %signed_two",
  552. "%sge_2_1 = OpSpecConstantOp %bool SGreaterThanEqual %signed_two %signed_one",
  553. "%sge_2_null = OpSpecConstantOp %bool SGreaterThanEqual %signed_two %signed_null",
  554. "%sge_minus_1_null = OpSpecConstantOp %bool SGreaterThanEqual %int_minus_1 %signed_null",
  555. "%ult_0_1 = OpSpecConstantOp %bool ULessThan %unsigned_zero %unsigned_one",
  556. "%ugt_0_1 = OpSpecConstantOp %bool UGreaterThan %unsigned_zero %unsigned_one",
  557. "%ule_2_3 = OpSpecConstantOp %bool ULessThanEqual %unsigned_two %unsigned_three",
  558. "%uge_1_1 = OpSpecConstantOp %bool UGreaterThanEqual %unsigned_one %unsigned_one",
  559. "%uge_2_null = OpSpecConstantOp %bool UGreaterThanEqual %unsigned_two %unsigned_null",
  560. "%uge_minus_1_null = OpSpecConstantOp %bool UGreaterThanEqual %int_minus_1 %unsigned_null",
  561. },
  562. // expected
  563. {
  564. "%int_minus_1 = OpConstant %int -1",
  565. "%slt_0_1 = OpConstantTrue %bool",
  566. "%sgt_0_1 = OpConstantFalse %bool",
  567. "%sle_2_2 = OpConstantTrue %bool",
  568. "%sge_2_1 = OpConstantTrue %bool",
  569. "%sge_2_null = OpConstantTrue %bool",
  570. "%sge_minus_1_null = OpConstantFalse %bool",
  571. "%ult_0_1 = OpConstantTrue %bool",
  572. "%ugt_0_1 = OpConstantFalse %bool",
  573. "%ule_2_3 = OpConstantTrue %bool",
  574. "%uge_1_1 = OpConstantTrue %bool",
  575. "%uge_2_null = OpConstantTrue %bool",
  576. "%uge_minus_1_null = OpConstantTrue %bool",
  577. },
  578. },
  579. // Logical and, or, xor.
  580. {
  581. // original
  582. {
  583. "%logical_or = OpSpecConstantOp %bool LogicalOr %bool_true %bool_false",
  584. "%logical_and = OpSpecConstantOp %bool LogicalAnd %bool_true %bool_false",
  585. "%logical_not = OpSpecConstantOp %bool LogicalNot %bool_true",
  586. "%logical_eq = OpSpecConstantOp %bool LogicalEqual %bool_true %bool_true",
  587. "%logical_neq = OpSpecConstantOp %bool LogicalNotEqual %bool_true %bool_true",
  588. "%logical_and_null = OpSpecConstantOp %bool LogicalAnd %bool_true %bool_null",
  589. },
  590. // expected
  591. {
  592. "%logical_or = OpConstantTrue %bool",
  593. "%logical_and = OpConstantFalse %bool",
  594. "%logical_not = OpConstantFalse %bool",
  595. "%logical_eq = OpConstantTrue %bool",
  596. "%logical_neq = OpConstantFalse %bool",
  597. "%logical_and_null = OpConstantFalse %bool",
  598. },
  599. },
  600. // clang-format on
  601. })));
  602. // Tests about arithmetic operations for scalar int and uint types.
  603. INSTANTIATE_TEST_SUITE_P(
  604. ScalarArithmetic, FoldSpecConstantOpAndCompositePassTest,
  605. ::testing::ValuesIn(std::vector<
  606. FoldSpecConstantOpAndCompositePassTestCase>({
  607. // clang-format off
  608. // scalar integer negate
  609. {
  610. // original
  611. {
  612. "%int_minus_1 = OpSpecConstantOp %int SNegate %signed_one",
  613. "%int_minus_2 = OpSpecConstantOp %int SNegate %signed_two",
  614. "%int_neg_null = OpSpecConstantOp %int SNegate %signed_null",
  615. "%int_max = OpConstant %int 2147483647",
  616. "%int_neg_max = OpSpecConstantOp %int SNegate %int_max",
  617. },
  618. // expected
  619. {
  620. "%int_minus_1 = OpConstant %int -1",
  621. "%int_minus_2 = OpConstant %int -2",
  622. "%int_neg_null = OpConstant %int 0",
  623. "%int_max = OpConstant %int 2147483647",
  624. "%int_neg_max = OpConstant %int -2147483647",
  625. },
  626. },
  627. // scalar integer not
  628. {
  629. // original
  630. {
  631. "%uint_4294967294 = OpSpecConstantOp %uint Not %unsigned_one",
  632. "%uint_4294967293 = OpSpecConstantOp %uint Not %unsigned_two",
  633. "%uint_neg_null = OpSpecConstantOp %uint Not %unsigned_null",
  634. },
  635. // expected
  636. {
  637. "%uint_4294967294 = OpConstant %uint 4294967294",
  638. "%uint_4294967293 = OpConstant %uint 4294967293",
  639. "%uint_neg_null = OpConstant %uint 4294967295",
  640. },
  641. },
  642. // scalar integer add, sub, mul, div
  643. {
  644. // original
  645. {
  646. "%signed_max = OpConstant %int 2147483647",
  647. "%signed_min = OpConstant %int -2147483648",
  648. "%spec_int_iadd = OpSpecConstantOp %int IAdd %signed_three %signed_two",
  649. "%spec_int_isub = OpSpecConstantOp %int ISub %signed_one %spec_int_iadd",
  650. "%spec_int_sdiv = OpSpecConstantOp %int SDiv %spec_int_isub %signed_two",
  651. "%spec_int_imul = OpSpecConstantOp %int IMul %spec_int_sdiv %signed_three",
  652. "%spec_int_iadd_null = OpSpecConstantOp %int IAdd %spec_int_imul %signed_null",
  653. "%spec_int_imul_null = OpSpecConstantOp %int IMul %spec_int_iadd_null %signed_null",
  654. "%spec_int_iadd_overflow = OpSpecConstantOp %int IAdd %signed_max %signed_three",
  655. "%spec_int_isub_overflow = OpSpecConstantOp %int ISub %signed_min %signed_three",
  656. "%spec_uint_iadd = OpSpecConstantOp %uint IAdd %unsigned_three %unsigned_two",
  657. "%spec_uint_isub = OpSpecConstantOp %uint ISub %unsigned_one %spec_uint_iadd",
  658. "%spec_uint_udiv = OpSpecConstantOp %uint UDiv %spec_uint_isub %unsigned_three",
  659. "%spec_uint_imul = OpSpecConstantOp %uint IMul %spec_uint_udiv %unsigned_two",
  660. "%spec_uint_isub_null = OpSpecConstantOp %uint ISub %spec_uint_imul %signed_null",
  661. },
  662. // expected
  663. {
  664. "%signed_max = OpConstant %int 2147483647",
  665. "%signed_min = OpConstant %int -2147483648",
  666. "%spec_int_iadd = OpConstant %int 5",
  667. "%spec_int_isub = OpConstant %int -4",
  668. "%spec_int_sdiv = OpConstant %int -2",
  669. "%spec_int_imul = OpConstant %int -6",
  670. "%spec_int_iadd_null = OpConstant %int -6",
  671. "%spec_int_imul_null = OpConstant %int 0",
  672. "%spec_int_iadd_overflow = OpConstant %int -2147483646",
  673. "%spec_int_isub_overflow = OpConstant %int 2147483645",
  674. "%spec_uint_iadd = OpConstant %uint 5",
  675. "%spec_uint_isub = OpConstant %uint 4294967292",
  676. "%spec_uint_udiv = OpConstant %uint 1431655764",
  677. "%spec_uint_imul = OpConstant %uint 2863311528",
  678. "%spec_uint_isub_null = OpConstant %uint 2863311528",
  679. },
  680. },
  681. // scalar integer rem, mod
  682. {
  683. // original
  684. {
  685. // common constants
  686. "%int_7 = OpConstant %int 7",
  687. "%uint_7 = OpConstant %uint 7",
  688. "%int_minus_7 = OpConstant %int -7",
  689. "%int_minus_3 = OpConstant %int -3",
  690. // srem
  691. "%7_srem_3 = OpSpecConstantOp %int SRem %int_7 %signed_three",
  692. "%minus_7_srem_3 = OpSpecConstantOp %int SRem %int_minus_7 %signed_three",
  693. "%7_srem_minus_3 = OpSpecConstantOp %int SRem %int_7 %int_minus_3",
  694. "%minus_7_srem_minus_3 = OpSpecConstantOp %int SRem %int_minus_7 %int_minus_3",
  695. // smod
  696. "%7_smod_3 = OpSpecConstantOp %int SMod %int_7 %signed_three",
  697. "%minus_7_smod_3 = OpSpecConstantOp %int SMod %int_minus_7 %signed_three",
  698. "%7_smod_minus_3 = OpSpecConstantOp %int SMod %int_7 %int_minus_3",
  699. "%minus_7_smod_minus_3 = OpSpecConstantOp %int SMod %int_minus_7 %int_minus_3",
  700. // umod
  701. "%7_umod_3 = OpSpecConstantOp %uint UMod %uint_7 %unsigned_three",
  702. // null constant
  703. "%null_srem_3 = OpSpecConstantOp %int SRem %signed_null %signed_three",
  704. "%null_smod_3 = OpSpecConstantOp %int SMod %signed_null %signed_three",
  705. "%null_umod_3 = OpSpecConstantOp %uint UMod %unsigned_null %unsigned_three",
  706. },
  707. // expected
  708. {
  709. // common constants
  710. "%int_7 = OpConstant %int 7",
  711. "%uint_7 = OpConstant %uint 7",
  712. "%int_minus_7 = OpConstant %int -7",
  713. "%int_minus_3 = OpConstant %int -3",
  714. // srem
  715. "%7_srem_3 = OpConstant %int 1",
  716. "%minus_7_srem_3 = OpConstant %int -1",
  717. "%7_srem_minus_3 = OpConstant %int 1",
  718. "%minus_7_srem_minus_3 = OpConstant %int -1",
  719. // smod
  720. "%7_smod_3 = OpConstant %int 1",
  721. "%minus_7_smod_3 = OpConstant %int 2",
  722. "%7_smod_minus_3 = OpConstant %int -2",
  723. "%minus_7_smod_minus_3 = OpConstant %int -1",
  724. // umod
  725. "%7_umod_3 = OpConstant %uint 1",
  726. // null constant
  727. "%null_srem_3 = OpConstant %int 0",
  728. "%null_smod_3 = OpConstant %int 0",
  729. "%null_umod_3 = OpConstant %uint 0",
  730. },
  731. },
  732. // scalar integer bitwise and shift
  733. {
  734. // original
  735. {
  736. // bitwise
  737. "%xor_1_3 = OpSpecConstantOp %int BitwiseXor %signed_one %signed_three",
  738. "%and_1_2 = OpSpecConstantOp %int BitwiseAnd %signed_one %xor_1_3",
  739. "%or_1_2 = OpSpecConstantOp %int BitwiseOr %signed_one %xor_1_3",
  740. "%xor_3_null = OpSpecConstantOp %int BitwiseXor %or_1_2 %signed_null",
  741. // shift
  742. "%unsigned_31 = OpConstant %uint 31",
  743. "%unsigned_left_shift_max = OpSpecConstantOp %uint ShiftLeftLogical %unsigned_one %unsigned_31",
  744. "%unsigned_right_shift_logical = OpSpecConstantOp %uint ShiftRightLogical %unsigned_left_shift_max %unsigned_31",
  745. "%signed_right_shift_arithmetic = OpSpecConstantOp %int ShiftRightArithmetic %unsigned_left_shift_max %unsigned_31",
  746. "%left_shift_null_31 = OpSpecConstantOp %uint ShiftLeftLogical %unsigned_null %unsigned_31",
  747. "%right_shift_31_null = OpSpecConstantOp %uint ShiftRightLogical %unsigned_31 %unsigned_null",
  748. },
  749. // expected
  750. {
  751. "%xor_1_3 = OpConstant %int 2",
  752. "%and_1_2 = OpConstant %int 0",
  753. "%or_1_2 = OpConstant %int 3",
  754. "%xor_3_null = OpConstant %int 3",
  755. "%unsigned_31 = OpConstant %uint 31",
  756. "%unsigned_left_shift_max = OpConstant %uint 2147483648",
  757. "%unsigned_right_shift_logical = OpConstant %uint 1",
  758. "%signed_right_shift_arithmetic = OpConstant %int -1",
  759. "%left_shift_null_31 = OpConstant %uint 0",
  760. "%right_shift_31_null = OpConstant %uint 31",
  761. },
  762. },
  763. // Skip folding if any operands have undetermined value.
  764. {
  765. // original
  766. {
  767. "%spec_int = OpSpecConstant %int 1",
  768. "%spec_iadd = OpSpecConstantOp %int IAdd %signed_three %spec_int",
  769. },
  770. // expected
  771. {
  772. "%spec_int = OpSpecConstant %int 1",
  773. "%spec_iadd = OpSpecConstantOp %int IAdd %signed_three %spec_int",
  774. },
  775. },
  776. // clang-format on
  777. })));
  778. // Tests about arithmetic operations for vector int and uint types.
  779. INSTANTIATE_TEST_SUITE_P(
  780. VectorArithmetic, FoldSpecConstantOpAndCompositePassTest,
  781. ::testing::ValuesIn(std::vector<
  782. FoldSpecConstantOpAndCompositePassTestCase>({
  783. // clang-format off
  784. // vector integer negate
  785. {
  786. // original
  787. {
  788. "%v2int_minus_1 = OpSpecConstantOp %v2int SNegate %signed_one_vec",
  789. "%v2int_minus_2 = OpSpecConstantOp %v2int SNegate %signed_two_vec",
  790. "%v2int_neg_null = OpSpecConstantOp %v2int SNegate %signed_null_vec",
  791. },
  792. // expected
  793. {
  794. "%int_n1 = OpConstant %int -1",
  795. "%int_n1_0 = OpConstant %int -1",
  796. "%v2int_minus_1 = OpConstantComposite %v2int %int_n1 %int_n1",
  797. "%int_n2 = OpConstant %int -2",
  798. "%int_n2_0 = OpConstant %int -2",
  799. "%v2int_minus_2 = OpConstantComposite %v2int %int_n2 %int_n2",
  800. "%int_0 = OpConstant %int 0",
  801. "%int_0_0 = OpConstant %int 0",
  802. "%v2int_neg_null = OpConstantComposite %v2int %signed_zero %signed_zero",
  803. },
  804. },
  805. // vector integer (including null vetors) add, sub, div, mul
  806. {
  807. // original
  808. {
  809. "%spec_v2int_iadd = OpSpecConstantOp %v2int IAdd %signed_three_vec %signed_two_vec",
  810. "%spec_v2int_isub = OpSpecConstantOp %v2int ISub %signed_one_vec %spec_v2int_iadd",
  811. "%spec_v2int_sdiv = OpSpecConstantOp %v2int SDiv %spec_v2int_isub %signed_two_vec",
  812. "%spec_v2int_imul = OpSpecConstantOp %v2int IMul %spec_v2int_sdiv %signed_three_vec",
  813. "%spec_v2int_iadd_null = OpSpecConstantOp %v2int IAdd %spec_v2int_imul %signed_null_vec",
  814. "%spec_v2uint_iadd = OpSpecConstantOp %v2uint IAdd %unsigned_three_vec %unsigned_two_vec",
  815. "%spec_v2uint_isub = OpSpecConstantOp %v2uint ISub %unsigned_one_vec %spec_v2uint_iadd",
  816. "%spec_v2uint_udiv = OpSpecConstantOp %v2uint UDiv %spec_v2uint_isub %unsigned_three_vec",
  817. "%spec_v2uint_imul = OpSpecConstantOp %v2uint IMul %spec_v2uint_udiv %unsigned_two_vec",
  818. "%spec_v2uint_isub_null = OpSpecConstantOp %v2uint ISub %spec_v2uint_imul %signed_null_vec",
  819. },
  820. // expected
  821. {
  822. "%int_5 = OpConstant %int 5",
  823. "%int_5_0 = OpConstant %int 5",
  824. "%spec_v2int_iadd = OpConstantComposite %v2int %int_5 %int_5",
  825. "%int_n4 = OpConstant %int -4",
  826. "%int_n4_0 = OpConstant %int -4",
  827. "%spec_v2int_isub = OpConstantComposite %v2int %int_n4 %int_n4",
  828. "%int_n2 = OpConstant %int -2",
  829. "%int_n2_0 = OpConstant %int -2",
  830. "%spec_v2int_sdiv = OpConstantComposite %v2int %int_n2 %int_n2",
  831. "%int_n6 = OpConstant %int -6",
  832. "%int_n6_0 = OpConstant %int -6",
  833. "%spec_v2int_imul = OpConstantComposite %v2int %int_n6 %int_n6",
  834. "%int_n6_1 = OpConstant %int -6",
  835. "%int_n6_2 = OpConstant %int -6",
  836. "%spec_v2int_iadd_null = OpConstantComposite %v2int %int_n6 %int_n6",
  837. "%uint_5 = OpConstant %uint 5",
  838. "%uint_5_0 = OpConstant %uint 5",
  839. "%spec_v2uint_iadd = OpConstantComposite %v2uint %uint_5 %uint_5",
  840. "%uint_4294967292 = OpConstant %uint 4294967292",
  841. "%uint_4294967292_0 = OpConstant %uint 4294967292",
  842. "%spec_v2uint_isub = OpConstantComposite %v2uint %uint_4294967292 %uint_4294967292",
  843. "%uint_1431655764 = OpConstant %uint 1431655764",
  844. "%uint_1431655764_0 = OpConstant %uint 1431655764",
  845. "%spec_v2uint_udiv = OpConstantComposite %v2uint %uint_1431655764 %uint_1431655764",
  846. "%uint_2863311528 = OpConstant %uint 2863311528",
  847. "%uint_2863311528_0 = OpConstant %uint 2863311528",
  848. "%spec_v2uint_imul = OpConstantComposite %v2uint %uint_2863311528 %uint_2863311528",
  849. "%uint_2863311528_1 = OpConstant %uint 2863311528",
  850. "%uint_2863311528_2 = OpConstant %uint 2863311528",
  851. "%spec_v2uint_isub_null = OpConstantComposite %v2uint %uint_2863311528 %uint_2863311528",
  852. },
  853. },
  854. // vector integer rem, mod
  855. {
  856. // original
  857. {
  858. // common constants
  859. "%int_7 = OpConstant %int 7",
  860. "%v2int_7 = OpConstantComposite %v2int %int_7 %int_7",
  861. "%uint_7 = OpConstant %uint 7",
  862. "%v2uint_7 = OpConstantComposite %v2uint %uint_7 %uint_7",
  863. "%int_minus_7 = OpConstant %int -7",
  864. "%v2int_minus_7 = OpConstantComposite %v2int %int_minus_7 %int_minus_7",
  865. "%int_minus_3 = OpConstant %int -3",
  866. "%v2int_minus_3 = OpConstantComposite %v2int %int_minus_3 %int_minus_3",
  867. // srem
  868. "%7_srem_3 = OpSpecConstantOp %v2int SRem %v2int_7 %signed_three_vec",
  869. "%minus_7_srem_3 = OpSpecConstantOp %v2int SRem %v2int_minus_7 %signed_three_vec",
  870. "%7_srem_minus_3 = OpSpecConstantOp %v2int SRem %v2int_7 %v2int_minus_3",
  871. "%minus_7_srem_minus_3 = OpSpecConstantOp %v2int SRem %v2int_minus_7 %v2int_minus_3",
  872. // smod
  873. "%7_smod_3 = OpSpecConstantOp %v2int SMod %v2int_7 %signed_three_vec",
  874. "%minus_7_smod_3 = OpSpecConstantOp %v2int SMod %v2int_minus_7 %signed_three_vec",
  875. "%7_smod_minus_3 = OpSpecConstantOp %v2int SMod %v2int_7 %v2int_minus_3",
  876. "%minus_7_smod_minus_3 = OpSpecConstantOp %v2int SMod %v2int_minus_7 %v2int_minus_3",
  877. // umod
  878. "%7_umod_3 = OpSpecConstantOp %v2uint UMod %v2uint_7 %unsigned_three_vec",
  879. },
  880. // expected
  881. {
  882. // common constants
  883. "%int_7 = OpConstant %int 7",
  884. "%v2int_7 = OpConstantComposite %v2int %int_7 %int_7",
  885. "%uint_7 = OpConstant %uint 7",
  886. "%v2uint_7 = OpConstantComposite %v2uint %uint_7 %uint_7",
  887. "%int_minus_7 = OpConstant %int -7",
  888. "%v2int_minus_7 = OpConstantComposite %v2int %int_minus_7 %int_minus_7",
  889. "%int_minus_3 = OpConstant %int -3",
  890. "%v2int_minus_3 = OpConstantComposite %v2int %int_minus_3 %int_minus_3",
  891. // srem
  892. "%int_1 = OpConstant %int 1",
  893. "%int_1_0 = OpConstant %int 1",
  894. "%7_srem_3 = OpConstantComposite %v2int %signed_one %signed_one",
  895. "%int_n1 = OpConstant %int -1",
  896. "%int_n1_0 = OpConstant %int -1",
  897. "%minus_7_srem_3 = OpConstantComposite %v2int %int_n1 %int_n1",
  898. "%int_1_1 = OpConstant %int 1",
  899. "%int_1_2 = OpConstant %int 1",
  900. "%7_srem_minus_3 = OpConstantComposite %v2int %signed_one %signed_one",
  901. "%int_n1_1 = OpConstant %int -1",
  902. "%int_n1_2 = OpConstant %int -1",
  903. "%minus_7_srem_minus_3 = OpConstantComposite %v2int %int_n1 %int_n1",
  904. // smod
  905. "%int_1_3 = OpConstant %int 1",
  906. "%int_1_4 = OpConstant %int 1",
  907. "%7_smod_3 = OpConstantComposite %v2int %signed_one %signed_one",
  908. "%int_2 = OpConstant %int 2",
  909. "%int_2_0 = OpConstant %int 2",
  910. "%minus_7_smod_3 = OpConstantComposite %v2int %signed_two %signed_two",
  911. "%int_n2 = OpConstant %int -2",
  912. "%int_n2_0 = OpConstant %int -2",
  913. "%7_smod_minus_3 = OpConstantComposite %v2int %int_n2 %int_n2",
  914. "%int_n1_3 = OpConstant %int -1",
  915. "%int_n1_4 = OpConstant %int -1",
  916. "%minus_7_smod_minus_3 = OpConstantComposite %v2int %int_n1 %int_n1",
  917. // umod
  918. "%uint_1 = OpConstant %uint 1",
  919. "%uint_1_0 = OpConstant %uint 1",
  920. "%7_umod_3 = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
  921. },
  922. },
  923. // vector integer bitwise, shift
  924. {
  925. // original
  926. {
  927. "%xor_1_3 = OpSpecConstantOp %v2int BitwiseXor %signed_one_vec %signed_three_vec",
  928. "%and_1_2 = OpSpecConstantOp %v2int BitwiseAnd %signed_one_vec %xor_1_3",
  929. "%or_1_2 = OpSpecConstantOp %v2int BitwiseOr %signed_one_vec %xor_1_3",
  930. "%unsigned_31 = OpConstant %uint 31",
  931. "%v2unsigned_31 = OpConstantComposite %v2uint %unsigned_31 %unsigned_31",
  932. "%unsigned_left_shift_max = OpSpecConstantOp %v2uint ShiftLeftLogical %unsigned_one_vec %v2unsigned_31",
  933. "%unsigned_right_shift_logical = OpSpecConstantOp %v2uint ShiftRightLogical %unsigned_left_shift_max %v2unsigned_31",
  934. "%signed_right_shift_arithmetic = OpSpecConstantOp %v2int ShiftRightArithmetic %unsigned_left_shift_max %v2unsigned_31",
  935. },
  936. // expected
  937. {
  938. "%int_2 = OpConstant %int 2",
  939. "%int_2_0 = OpConstant %int 2",
  940. "%xor_1_3 = OpConstantComposite %v2int %signed_two %signed_two",
  941. "%int_0 = OpConstant %int 0",
  942. "%int_0_0 = OpConstant %int 0",
  943. "%and_1_2 = OpConstantComposite %v2int %signed_zero %signed_zero",
  944. "%int_3 = OpConstant %int 3",
  945. "%int_3_0 = OpConstant %int 3",
  946. "%or_1_2 = OpConstantComposite %v2int %signed_three %signed_three",
  947. "%unsigned_31 = OpConstant %uint 31",
  948. "%v2unsigned_31 = OpConstantComposite %v2uint %unsigned_31 %unsigned_31",
  949. "%uint_2147483648 = OpConstant %uint 2147483648",
  950. "%uint_2147483648_0 = OpConstant %uint 2147483648",
  951. "%unsigned_left_shift_max = OpConstantComposite %v2uint %uint_2147483648 %uint_2147483648",
  952. "%uint_1 = OpConstant %uint 1",
  953. "%uint_1_0 = OpConstant %uint 1",
  954. "%unsigned_right_shift_logical = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
  955. "%int_n1 = OpConstant %int -1",
  956. "%int_n1_0 = OpConstant %int -1",
  957. "%signed_right_shift_arithmetic = OpConstantComposite %v2int %int_n1 %int_n1",
  958. },
  959. },
  960. // Skip folding if any vector operands or components of the operands
  961. // have undetermined value.
  962. {
  963. // original
  964. {
  965. "%spec_int = OpSpecConstant %int 1",
  966. "%spec_vec = OpSpecConstantComposite %v2int %signed_zero %spec_int",
  967. "%spec_iadd = OpSpecConstantOp %v2int IAdd %signed_three_vec %spec_vec",
  968. },
  969. // expected
  970. {
  971. "%spec_int = OpSpecConstant %int 1",
  972. "%spec_vec = OpSpecConstantComposite %v2int %signed_zero %spec_int",
  973. "%spec_iadd = OpSpecConstantOp %v2int IAdd %signed_three_vec %spec_vec",
  974. },
  975. },
  976. // Skip folding if any vector operands are defined by OpUndef
  977. {
  978. // original
  979. {
  980. "%undef = OpUndef %int",
  981. "%vec = OpConstantComposite %v2int %undef %signed_one",
  982. "%spec_iadd = OpSpecConstantOp %v2int IAdd %signed_three_vec %vec",
  983. },
  984. // expected
  985. {
  986. "%undef = OpUndef %int",
  987. "%vec = OpConstantComposite %v2int %undef %signed_one",
  988. "%spec_iadd = OpSpecConstantOp %v2int IAdd %signed_three_vec %vec",
  989. },
  990. },
  991. // clang-format on
  992. })));
  993. // Tests for SpecConstantOp CompositeExtract instruction
  994. INSTANTIATE_TEST_SUITE_P(
  995. CompositeExtract, FoldSpecConstantOpAndCompositePassTest,
  996. ::testing::ValuesIn(std::vector<
  997. FoldSpecConstantOpAndCompositePassTestCase>({
  998. // clang-format off
  999. // normal vector
  1000. {
  1001. // original
  1002. {
  1003. "%r = OpSpecConstantOp %int CompositeExtract %signed_three_vec 0",
  1004. "%x = OpSpecConstantOp %int CompositeExtract %v4int_0_1_2_3 0",
  1005. "%y = OpSpecConstantOp %int CompositeExtract %v4int_0_1_2_3 1",
  1006. "%z = OpSpecConstantOp %int CompositeExtract %v4int_0_1_2_3 2",
  1007. "%w = OpSpecConstantOp %int CompositeExtract %v4int_0_1_2_3 3",
  1008. },
  1009. // expected
  1010. {
  1011. "%r = OpConstant %int 3",
  1012. "%x = OpConstant %int 0",
  1013. "%y = OpConstant %int 1",
  1014. "%z = OpConstant %int 2",
  1015. "%w = OpConstant %int 3",
  1016. },
  1017. },
  1018. // null vector
  1019. {
  1020. // original
  1021. {
  1022. "%x = OpSpecConstantOp %int CompositeExtract %signed_null_vec 0",
  1023. "%y = OpSpecConstantOp %int CompositeExtract %signed_null_vec 1",
  1024. "%null_v4int = OpConstantNull %v4int",
  1025. "%z = OpSpecConstantOp %int CompositeExtract %signed_null_vec 2",
  1026. },
  1027. // expected
  1028. {
  1029. "%x = OpConstantNull %int",
  1030. "%y = OpConstantNull %int",
  1031. "%null_v4int = OpConstantNull %v4int",
  1032. "%z = OpConstantNull %int",
  1033. }
  1034. },
  1035. // normal flat struct
  1036. {
  1037. // original
  1038. {
  1039. "%float_1 = OpConstant %float 1",
  1040. "%flat_1 = OpConstantComposite %flat_struct %bool_true %signed_null %float_1",
  1041. "%extract_bool = OpSpecConstantOp %bool CompositeExtract %flat_1 0",
  1042. "%extract_int = OpSpecConstantOp %int CompositeExtract %flat_1 1",
  1043. "%extract_float_1 = OpSpecConstantOp %float CompositeExtract %flat_1 2",
  1044. // foldable composite constants built with OpSpecConstantComposite
  1045. // should also be processed.
  1046. "%flat_2 = OpSpecConstantComposite %flat_struct %bool_true %signed_null %float_1",
  1047. "%extract_float_2 = OpSpecConstantOp %float CompositeExtract %flat_2 2",
  1048. },
  1049. // expected
  1050. {
  1051. "%float_1 = OpConstant %float 1",
  1052. "%flat_1 = OpConstantComposite %flat_struct %bool_true %signed_null %float_1",
  1053. "%extract_bool = OpConstantTrue %bool",
  1054. "%extract_int = OpConstantNull %int",
  1055. "%extract_float_1 = OpConstant %float 1",
  1056. "%flat_2 = OpConstantComposite %flat_struct %bool_true %signed_null %float_1",
  1057. "%extract_float_2 = OpConstant %float 1",
  1058. },
  1059. },
  1060. // null flat struct
  1061. {
  1062. // original
  1063. {
  1064. "%flat = OpConstantNull %flat_struct",
  1065. "%extract_bool = OpSpecConstantOp %bool CompositeExtract %flat 0",
  1066. "%extract_int = OpSpecConstantOp %int CompositeExtract %flat 1",
  1067. "%extract_float = OpSpecConstantOp %float CompositeExtract %flat 2",
  1068. },
  1069. // expected
  1070. {
  1071. "%flat = OpConstantNull %flat_struct",
  1072. "%extract_bool = OpConstantNull %bool",
  1073. "%extract_int = OpConstantNull %int",
  1074. "%extract_float = OpConstantNull %float",
  1075. },
  1076. },
  1077. // normal nested struct
  1078. {
  1079. // original
  1080. {
  1081. "%float_1 = OpConstant %float 1",
  1082. "%inner = OpConstantComposite %inner_struct %bool_true %signed_null %float_1",
  1083. "%outer = OpConstantComposite %outer_struct %inner %signed_one",
  1084. "%extract_inner = OpSpecConstantOp %inner_struct CompositeExtract %outer 0",
  1085. "%extract_int = OpSpecConstantOp %int CompositeExtract %outer 1",
  1086. "%extract_inner_float = OpSpecConstantOp %int CompositeExtract %outer 0 2",
  1087. },
  1088. // expected
  1089. {
  1090. "%float_1 = OpConstant %float 1",
  1091. "%inner = OpConstantComposite %inner_struct %bool_true %signed_null %float_1",
  1092. "%outer = OpConstantComposite %outer_struct %inner %signed_one",
  1093. "%extract_inner = OpConstantComposite %flat_struct %bool_true %signed_null %float_1",
  1094. "%extract_int = OpConstant %int 1",
  1095. "%extract_inner_float = OpConstant %float 1",
  1096. },
  1097. },
  1098. // null nested struct
  1099. {
  1100. // original
  1101. {
  1102. "%outer = OpConstantNull %outer_struct",
  1103. "%extract_inner = OpSpecConstantOp %inner_struct CompositeExtract %outer 0",
  1104. "%extract_int = OpSpecConstantOp %int CompositeExtract %outer 1",
  1105. "%extract_inner_float = OpSpecConstantOp %float CompositeExtract %outer 0 2",
  1106. },
  1107. // expected
  1108. {
  1109. "%outer = OpConstantNull %outer_struct",
  1110. "%extract_inner = OpConstantNull %inner_struct",
  1111. "%extract_int = OpConstantNull %int",
  1112. "%extract_inner_float = OpConstantNull %float",
  1113. },
  1114. },
  1115. // skip folding if the any composite constant's value are not fully
  1116. // determined, even though the extracting target might have
  1117. // determined value.
  1118. {
  1119. // original
  1120. {
  1121. "%float_1 = OpConstant %float 1",
  1122. "%spec_float = OpSpecConstant %float 1",
  1123. "%spec_inner = OpSpecConstantComposite %inner_struct %bool_true %signed_null %spec_float",
  1124. "%spec_outer = OpSpecConstantComposite %outer_struct %spec_inner %signed_one",
  1125. "%spec_vec = OpSpecConstantComposite %v2float %spec_float %float_1",
  1126. "%extract_inner = OpSpecConstantOp %int CompositeExtract %spec_inner 1",
  1127. "%extract_outer = OpSpecConstantOp %int CompositeExtract %spec_outer 1",
  1128. "%extract_vec = OpSpecConstantOp %float CompositeExtract %spec_vec 1",
  1129. },
  1130. // expected
  1131. {
  1132. "%float_1 = OpConstant %float 1",
  1133. "%spec_float = OpSpecConstant %float 1",
  1134. "%spec_inner = OpSpecConstantComposite %inner_struct %bool_true %signed_null %spec_float",
  1135. "%spec_outer = OpSpecConstantComposite %outer_struct %spec_inner %signed_one",
  1136. "%spec_vec = OpSpecConstantComposite %v2float %spec_float %float_1",
  1137. "%extract_inner = OpSpecConstantOp %int CompositeExtract %spec_inner 1",
  1138. "%extract_outer = OpSpecConstantOp %int CompositeExtract %spec_outer 1",
  1139. "%extract_vec = OpSpecConstantOp %float CompositeExtract %spec_vec 1",
  1140. },
  1141. },
  1142. // skip if the composite constant depends on the result of OpUndef,
  1143. // even though the composite extract target element does not depends
  1144. // on the OpUndef.
  1145. {
  1146. // original
  1147. {
  1148. "%undef = OpUndef %float",
  1149. "%inner = OpConstantComposite %inner_struct %bool_true %signed_one %undef",
  1150. "%outer = OpConstantComposite %outer_struct %inner %signed_one",
  1151. "%extract_inner = OpSpecConstantOp %int CompositeExtract %inner 1",
  1152. "%extract_outer = OpSpecConstantOp %int CompositeExtract %outer 1",
  1153. },
  1154. // expected
  1155. {
  1156. "%undef = OpUndef %float",
  1157. "%inner = OpConstantComposite %inner_struct %bool_true %signed_one %undef",
  1158. "%outer = OpConstantComposite %outer_struct %inner %signed_one",
  1159. "%extract_inner = OpSpecConstantOp %int CompositeExtract %inner 1",
  1160. "%extract_outer = OpSpecConstantOp %int CompositeExtract %outer 1",
  1161. },
  1162. },
  1163. // TODO(qining): Add tests for Array and other composite type constants.
  1164. // clang-format on
  1165. })));
  1166. // Tests the swizzle operations for spec const vectors.
  1167. INSTANTIATE_TEST_SUITE_P(
  1168. VectorShuffle, FoldSpecConstantOpAndCompositePassTest,
  1169. ::testing::ValuesIn(std::vector<
  1170. FoldSpecConstantOpAndCompositePassTestCase>({
  1171. // clang-format off
  1172. // normal vector
  1173. {
  1174. // original
  1175. {
  1176. "%xy = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %v4int_0_1_2_3 0 1",
  1177. "%yz = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %v4int_0_1_2_3 1 2",
  1178. "%zw = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %v4int_0_1_2_3 2 3",
  1179. "%wx = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %v4int_0_1_2_3 3 0",
  1180. "%xx = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %v4int_0_1_2_3 0 0",
  1181. "%yyy = OpSpecConstantOp %v3int VectorShuffle %v4int_0_1_2_3 %v4int_0_1_2_3 1 1 1",
  1182. "%wwww = OpSpecConstantOp %v4int VectorShuffle %v4int_0_1_2_3 %v4int_0_1_2_3 2 2 2 2",
  1183. },
  1184. // expected
  1185. {
  1186. "%xy = OpConstantComposite %v2int %signed_zero %signed_one",
  1187. "%yz = OpConstantComposite %v2int %signed_one %signed_two",
  1188. "%zw = OpConstantComposite %v2int %signed_two %signed_three",
  1189. "%wx = OpConstantComposite %v2int %signed_three %signed_zero",
  1190. "%xx = OpConstantComposite %v2int %signed_zero %signed_zero",
  1191. "%yyy = OpConstantComposite %v3int %signed_one %signed_one %signed_one",
  1192. "%wwww = OpConstantComposite %v4int %signed_two %signed_two %signed_two %signed_two",
  1193. },
  1194. },
  1195. // null vector
  1196. {
  1197. // original
  1198. {
  1199. "%a = OpSpecConstantOp %v2int VectorShuffle %signed_null_vec %v4int_0_1_2_3 0 1",
  1200. "%b = OpSpecConstantOp %v2int VectorShuffle %signed_null_vec %v4int_0_1_2_3 2 3",
  1201. "%c = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %signed_null_vec 3 4",
  1202. "%d = OpSpecConstantOp %v2int VectorShuffle %signed_null_vec %signed_null_vec 1 2",
  1203. },
  1204. // expected
  1205. {
  1206. "%60 = OpConstantNull %int",
  1207. "%a = OpConstantComposite %v2int %signed_null %signed_null",
  1208. "%62 = OpConstantNull %int",
  1209. "%b = OpConstantComposite %v2int %signed_zero %signed_one",
  1210. "%64 = OpConstantNull %int",
  1211. "%c = OpConstantComposite %v2int %signed_three %signed_null",
  1212. "%66 = OpConstantNull %int",
  1213. "%d = OpConstantComposite %v2int %signed_null %signed_null",
  1214. }
  1215. },
  1216. // skip if any of the components of the vector operands do not have
  1217. // determined value, even though the result vector might not be
  1218. // built with those undermined values.
  1219. {
  1220. // original
  1221. {
  1222. "%spec_int = OpSpecConstant %int 1",
  1223. "%spec_ivec = OpSpecConstantComposite %v2int %signed_null %spec_int",
  1224. "%a = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %spec_ivec 0 1",
  1225. "%b = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %spec_ivec 3 4",
  1226. },
  1227. // expected
  1228. {
  1229. "%spec_int = OpSpecConstant %int 1",
  1230. "%spec_ivec = OpSpecConstantComposite %v2int %signed_null %spec_int",
  1231. "%a = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %spec_ivec 0 1",
  1232. "%b = OpSpecConstantOp %v2int VectorShuffle %v4int_0_1_2_3 %spec_ivec 3 4",
  1233. },
  1234. },
  1235. // Skip if any components of the two vector operands depend on
  1236. // the result of OpUndef. Even though the selected components do
  1237. // not depend on the OpUndef result.
  1238. {
  1239. // original
  1240. {
  1241. "%undef = OpUndef %int",
  1242. "%vec_1 = OpConstantComposite %v2int %undef %signed_one",
  1243. "%dep = OpSpecConstantOp %v2int VectorShuffle %vec_1 %signed_three_vec 0 3",
  1244. "%not_dep_element = OpSpecConstantOp %v2int VectorShuffle %vec_1 %signed_three_vec 1 3",
  1245. "%no_dep_vector = OpSpecConstantOp %v2int VectorShuffle %vec_1 %signed_three_vec 2 3",
  1246. },
  1247. // expected
  1248. {
  1249. "%undef = OpUndef %int",
  1250. "%vec_1 = OpConstantComposite %v2int %undef %signed_one",
  1251. "%dep = OpSpecConstantOp %v2int VectorShuffle %vec_1 %signed_three_vec 0 3",
  1252. "%not_dep_element = OpSpecConstantOp %v2int VectorShuffle %vec_1 %signed_three_vec 1 3",
  1253. "%no_dep_vector = OpSpecConstantOp %v2int VectorShuffle %vec_1 %signed_three_vec 2 3",
  1254. },
  1255. },
  1256. // clang-format on
  1257. })));
  1258. // Test with long use-def chain.
  1259. INSTANTIATE_TEST_SUITE_P(
  1260. LongDefUseChain, FoldSpecConstantOpAndCompositePassTest,
  1261. ::testing::ValuesIn(std::vector<
  1262. FoldSpecConstantOpAndCompositePassTestCase>({
  1263. // clang-format off
  1264. // Long Def-Use chain with binary operations.
  1265. {
  1266. // original
  1267. {
  1268. "%array_size = OpConstant %int 4",
  1269. "%type_arr_int_4 = OpTypeArray %int %array_size",
  1270. "%spec_int_0 = OpConstant %int 100",
  1271. "%spec_int_1 = OpConstant %int 1",
  1272. "%spec_int_2 = OpSpecConstantOp %int IAdd %spec_int_0 %spec_int_1",
  1273. "%spec_int_3 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_2",
  1274. "%spec_int_4 = OpSpecConstantOp %int IAdd %spec_int_0 %spec_int_3",
  1275. "%spec_int_5 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_4",
  1276. "%spec_int_6 = OpSpecConstantOp %int IAdd %spec_int_0 %spec_int_5",
  1277. "%spec_int_7 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_6",
  1278. "%spec_int_8 = OpSpecConstantOp %int IAdd %spec_int_0 %spec_int_7",
  1279. "%spec_int_9 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_8",
  1280. "%spec_int_10 = OpSpecConstantOp %int IAdd %spec_int_0 %spec_int_9",
  1281. "%spec_int_11 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_10",
  1282. "%spec_int_12 = OpSpecConstantOp %int IAdd %spec_int_0 %spec_int_11",
  1283. "%spec_int_13 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_12",
  1284. "%spec_int_14 = OpSpecConstantOp %int IAdd %spec_int_0 %spec_int_13",
  1285. "%spec_int_15 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_14",
  1286. "%spec_int_16 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_15",
  1287. "%spec_int_17 = OpSpecConstantOp %int IAdd %spec_int_0 %spec_int_16",
  1288. "%spec_int_18 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_17",
  1289. "%spec_int_19 = OpSpecConstantOp %int IAdd %spec_int_0 %spec_int_18",
  1290. "%spec_int_20 = OpSpecConstantOp %int ISub %spec_int_0 %spec_int_19",
  1291. "%used_vec_a = OpSpecConstantComposite %v2int %spec_int_18 %spec_int_19",
  1292. "%used_vec_b = OpSpecConstantOp %v2int IMul %used_vec_a %used_vec_a",
  1293. "%spec_int_21 = OpSpecConstantOp %int CompositeExtract %used_vec_b 0",
  1294. "%array = OpConstantComposite %type_arr_int_4 %spec_int_20 %spec_int_20 %spec_int_21 %spec_int_21",
  1295. // Spec constants whose values can not be fully resolved should
  1296. // not be processed.
  1297. "%spec_int_22 = OpSpecConstant %int 123",
  1298. "%spec_int_23 = OpSpecConstantOp %int IAdd %spec_int_22 %signed_one",
  1299. },
  1300. // expected
  1301. {
  1302. "%array_size = OpConstant %int 4",
  1303. "%type_arr_int_4 = OpTypeArray %int %array_size",
  1304. "%spec_int_0 = OpConstant %int 100",
  1305. "%spec_int_1 = OpConstant %int 1",
  1306. "%spec_int_2 = OpConstant %int 101",
  1307. "%spec_int_3 = OpConstant %int -1",
  1308. "%spec_int_4 = OpConstant %int 99",
  1309. "%spec_int_5 = OpConstant %int 1",
  1310. "%spec_int_6 = OpConstant %int 101",
  1311. "%spec_int_7 = OpConstant %int -1",
  1312. "%spec_int_8 = OpConstant %int 99",
  1313. "%spec_int_9 = OpConstant %int 1",
  1314. "%spec_int_10 = OpConstant %int 101",
  1315. "%spec_int_11 = OpConstant %int -1",
  1316. "%spec_int_12 = OpConstant %int 99",
  1317. "%spec_int_13 = OpConstant %int 1",
  1318. "%spec_int_14 = OpConstant %int 101",
  1319. "%spec_int_15 = OpConstant %int -1",
  1320. "%spec_int_16 = OpConstant %int 101",
  1321. "%spec_int_17 = OpConstant %int 201",
  1322. "%spec_int_18 = OpConstant %int -101",
  1323. "%spec_int_19 = OpConstant %int -1",
  1324. "%spec_int_20 = OpConstant %int 101",
  1325. "%used_vec_a = OpConstantComposite %v2int %spec_int_18 %spec_int_19",
  1326. "%int_10201 = OpConstant %int 10201",
  1327. "%int_1 = OpConstant %int 1",
  1328. "%used_vec_b = OpConstantComposite %v2int %int_10201 %signed_one",
  1329. "%spec_int_21 = OpConstant %int 10201",
  1330. "%array = OpConstantComposite %type_arr_int_4 %spec_int_20 %spec_int_20 %spec_int_21 %spec_int_21",
  1331. "%spec_int_22 = OpSpecConstant %int 123",
  1332. "%spec_int_23 = OpSpecConstantOp %int IAdd %spec_int_22 %signed_one",
  1333. },
  1334. },
  1335. // Long Def-Use chain with swizzle
  1336. })));
  1337. } // namespace
  1338. } // namespace opt
  1339. } // namespace spvtools