val_arithmetics_test.cpp 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  1. // Copyright (c) 2017 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. // Tests for unique type declaration rules validator.
  15. #include <string>
  16. #include "gmock/gmock.h"
  17. #include "test/unit_spirv.h"
  18. #include "test/val/val_fixtures.h"
  19. namespace spvtools {
  20. namespace val {
  21. namespace {
  22. using ::testing::HasSubstr;
  23. using ::testing::Not;
  24. using ValidateArithmetics = spvtest::ValidateBase<bool>;
  25. std::string GenerateCode(const std::string& main_body) {
  26. const std::string prefix =
  27. R"(
  28. OpCapability Shader
  29. OpCapability Int64
  30. OpCapability Float64
  31. OpCapability Matrix
  32. %ext_inst = OpExtInstImport "GLSL.std.450"
  33. OpMemoryModel Logical GLSL450
  34. OpEntryPoint Fragment %main "main"
  35. OpExecutionMode %main OriginUpperLeft
  36. %void = OpTypeVoid
  37. %func = OpTypeFunction %void
  38. %bool = OpTypeBool
  39. %f32 = OpTypeFloat 32
  40. %u32 = OpTypeInt 32 0
  41. %s32 = OpTypeInt 32 1
  42. %f64 = OpTypeFloat 64
  43. %u64 = OpTypeInt 64 0
  44. %s64 = OpTypeInt 64 1
  45. %boolvec2 = OpTypeVector %bool 2
  46. %s32vec2 = OpTypeVector %s32 2
  47. %u32vec2 = OpTypeVector %u32 2
  48. %u64vec2 = OpTypeVector %u64 2
  49. %f32vec2 = OpTypeVector %f32 2
  50. %f64vec2 = OpTypeVector %f64 2
  51. %boolvec3 = OpTypeVector %bool 3
  52. %u32vec3 = OpTypeVector %u32 3
  53. %u64vec3 = OpTypeVector %u64 3
  54. %s32vec3 = OpTypeVector %s32 3
  55. %f32vec3 = OpTypeVector %f32 3
  56. %f64vec3 = OpTypeVector %f64 3
  57. %boolvec4 = OpTypeVector %bool 4
  58. %u32vec4 = OpTypeVector %u32 4
  59. %u64vec4 = OpTypeVector %u64 4
  60. %s32vec4 = OpTypeVector %s32 4
  61. %f32vec4 = OpTypeVector %f32 4
  62. %f64vec4 = OpTypeVector %f64 4
  63. %f32mat22 = OpTypeMatrix %f32vec2 2
  64. %f32mat23 = OpTypeMatrix %f32vec2 3
  65. %f32mat32 = OpTypeMatrix %f32vec3 2
  66. %f32mat33 = OpTypeMatrix %f32vec3 3
  67. %f64mat22 = OpTypeMatrix %f64vec2 2
  68. %struct_f32_f32 = OpTypeStruct %f32 %f32
  69. %struct_u32_u32 = OpTypeStruct %u32 %u32
  70. %struct_u32_u32_u32 = OpTypeStruct %u32 %u32 %u32
  71. %struct_s32_s32 = OpTypeStruct %s32 %s32
  72. %struct_s32_u32 = OpTypeStruct %s32 %u32
  73. %struct_u32vec2_u32vec2 = OpTypeStruct %u32vec2 %u32vec2
  74. %struct_s32vec2_s32vec2 = OpTypeStruct %s32vec2 %s32vec2
  75. %f32_0 = OpConstant %f32 0
  76. %f32_1 = OpConstant %f32 1
  77. %f32_2 = OpConstant %f32 2
  78. %f32_3 = OpConstant %f32 3
  79. %f32_4 = OpConstant %f32 4
  80. %f32_pi = OpConstant %f32 3.14159
  81. %s32_0 = OpConstant %s32 0
  82. %s32_1 = OpConstant %s32 1
  83. %s32_2 = OpConstant %s32 2
  84. %s32_3 = OpConstant %s32 3
  85. %s32_4 = OpConstant %s32 4
  86. %s32_m1 = OpConstant %s32 -1
  87. %u32_0 = OpConstant %u32 0
  88. %u32_1 = OpConstant %u32 1
  89. %u32_2 = OpConstant %u32 2
  90. %u32_3 = OpConstant %u32 3
  91. %u32_4 = OpConstant %u32 4
  92. %f64_0 = OpConstant %f64 0
  93. %f64_1 = OpConstant %f64 1
  94. %f64_2 = OpConstant %f64 2
  95. %f64_3 = OpConstant %f64 3
  96. %f64_4 = OpConstant %f64 4
  97. %s64_0 = OpConstant %s64 0
  98. %s64_1 = OpConstant %s64 1
  99. %s64_2 = OpConstant %s64 2
  100. %s64_3 = OpConstant %s64 3
  101. %s64_4 = OpConstant %s64 4
  102. %s64_m1 = OpConstant %s64 -1
  103. %u64_0 = OpConstant %u64 0
  104. %u64_1 = OpConstant %u64 1
  105. %u64_2 = OpConstant %u64 2
  106. %u64_3 = OpConstant %u64 3
  107. %u64_4 = OpConstant %u64 4
  108. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  109. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  110. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  111. %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
  112. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  113. %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
  114. %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
  115. %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
  116. %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
  117. %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
  118. %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
  119. %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
  120. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  121. %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
  122. %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
  123. %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
  124. %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
  125. %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
  126. %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
  127. %f64vec2_12 = OpConstantComposite %f64vec2 %f64_1 %f64_2
  128. %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
  129. %f64vec3_123 = OpConstantComposite %f64vec3 %f64_1 %f64_2 %f64_3
  130. %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
  131. %f64vec4_1234 = OpConstantComposite %f64vec4 %f64_1 %f64_2 %f64_3 %f64_4
  132. %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
  133. %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
  134. %f32mat32_123123 = OpConstantComposite %f32mat32 %f32vec3_123 %f32vec3_123
  135. %f32mat33_123123123 = OpConstantComposite %f32mat33 %f32vec3_123 %f32vec3_123 %f32vec3_123
  136. %f64mat22_1212 = OpConstantComposite %f64mat22 %f64vec2_12 %f64vec2_12
  137. %main = OpFunction %void None %func
  138. %main_entry = OpLabel)";
  139. const std::string suffix =
  140. R"(
  141. OpReturn
  142. OpFunctionEnd)";
  143. return prefix + main_body + suffix;
  144. }
  145. TEST_F(ValidateArithmetics, F32Success) {
  146. const std::string body = R"(
  147. %val1 = OpFMul %f32 %f32_0 %f32_1
  148. %val2 = OpFSub %f32 %f32_2 %f32_0
  149. %val3 = OpFAdd %f32 %val1 %val2
  150. %val4 = OpFNegate %f32 %val3
  151. %val5 = OpFDiv %f32 %val4 %val1
  152. %val6 = OpFRem %f32 %val4 %f32_2
  153. %val7 = OpFMod %f32 %val4 %f32_2
  154. )";
  155. CompileSuccessfully(GenerateCode(body).c_str());
  156. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  157. }
  158. TEST_F(ValidateArithmetics, F64Success) {
  159. const std::string body = R"(
  160. %val1 = OpFMul %f64 %f64_0 %f64_1
  161. %val2 = OpFSub %f64 %f64_2 %f64_0
  162. %val3 = OpFAdd %f64 %val1 %val2
  163. %val4 = OpFNegate %f64 %val3
  164. %val5 = OpFDiv %f64 %val4 %val1
  165. %val6 = OpFRem %f64 %val4 %f64_2
  166. %val7 = OpFMod %f64 %val4 %f64_2
  167. )";
  168. CompileSuccessfully(GenerateCode(body).c_str());
  169. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  170. }
  171. TEST_F(ValidateArithmetics, Int32Success) {
  172. const std::string body = R"(
  173. %val1 = OpIMul %u32 %s32_0 %u32_1
  174. %val2 = OpIMul %s32 %s32_2 %u32_1
  175. %val3 = OpIAdd %u32 %val1 %val2
  176. %val4 = OpIAdd %s32 %val1 %val2
  177. %val5 = OpISub %u32 %val3 %val4
  178. %val6 = OpISub %s32 %val4 %val3
  179. %val7 = OpSDiv %s32 %val4 %val3
  180. %val8 = OpSNegate %s32 %val7
  181. %val9 = OpSRem %s32 %val4 %val3
  182. %val10 = OpSMod %s32 %val4 %val3
  183. )";
  184. CompileSuccessfully(GenerateCode(body).c_str());
  185. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  186. }
  187. TEST_F(ValidateArithmetics, Int64Success) {
  188. const std::string body = R"(
  189. %val1 = OpIMul %u64 %s64_0 %u64_1
  190. %val2 = OpIMul %s64 %s64_2 %u64_1
  191. %val3 = OpIAdd %u64 %val1 %val2
  192. %val4 = OpIAdd %s64 %val1 %val2
  193. %val5 = OpISub %u64 %val3 %val4
  194. %val6 = OpISub %s64 %val4 %val3
  195. %val7 = OpSDiv %s64 %val4 %val3
  196. %val8 = OpSNegate %s64 %val7
  197. %val9 = OpSRem %s64 %val4 %val3
  198. %val10 = OpSMod %s64 %val4 %val3
  199. )";
  200. CompileSuccessfully(GenerateCode(body).c_str());
  201. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  202. }
  203. TEST_F(ValidateArithmetics, F32Vec2Success) {
  204. const std::string body = R"(
  205. %val1 = OpFMul %f32vec2 %f32vec2_01 %f32vec2_12
  206. %val2 = OpFSub %f32vec2 %f32vec2_12 %f32vec2_01
  207. %val3 = OpFAdd %f32vec2 %val1 %val2
  208. %val4 = OpFNegate %f32vec2 %val3
  209. %val5 = OpFDiv %f32vec2 %val4 %val1
  210. %val6 = OpFRem %f32vec2 %val4 %f32vec2_12
  211. %val7 = OpFMod %f32vec2 %val4 %f32vec2_12
  212. )";
  213. CompileSuccessfully(GenerateCode(body).c_str());
  214. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  215. }
  216. TEST_F(ValidateArithmetics, F64Vec2Success) {
  217. const std::string body = R"(
  218. %val1 = OpFMul %f64vec2 %f64vec2_01 %f64vec2_12
  219. %val2 = OpFSub %f64vec2 %f64vec2_12 %f64vec2_01
  220. %val3 = OpFAdd %f64vec2 %val1 %val2
  221. %val4 = OpFNegate %f64vec2 %val3
  222. %val5 = OpFDiv %f64vec2 %val4 %val1
  223. %val6 = OpFRem %f64vec2 %val4 %f64vec2_12
  224. %val7 = OpFMod %f64vec2 %val4 %f64vec2_12
  225. )";
  226. CompileSuccessfully(GenerateCode(body).c_str());
  227. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  228. }
  229. TEST_F(ValidateArithmetics, U32Vec2Success) {
  230. const std::string body = R"(
  231. %val1 = OpIMul %u32vec2 %u32vec2_01 %u32vec2_12
  232. %val2 = OpISub %u32vec2 %u32vec2_12 %u32vec2_01
  233. %val3 = OpIAdd %u32vec2 %val1 %val2
  234. %val4 = OpSNegate %u32vec2 %val3
  235. %val5 = OpSDiv %u32vec2 %val4 %val1
  236. %val6 = OpSRem %u32vec2 %val4 %u32vec2_12
  237. %val7 = OpSMod %u32vec2 %val4 %u32vec2_12
  238. )";
  239. CompileSuccessfully(GenerateCode(body).c_str());
  240. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  241. }
  242. TEST_F(ValidateArithmetics, FNegateTypeIdU32) {
  243. const std::string body = R"(
  244. %val = OpFNegate %u32 %u32_0
  245. )";
  246. CompileSuccessfully(GenerateCode(body).c_str());
  247. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  248. EXPECT_THAT(
  249. getDiagnosticString(),
  250. HasSubstr(
  251. "Expected floating scalar or vector type as Result Type: FNegate"));
  252. }
  253. TEST_F(ValidateArithmetics, FNegateTypeIdVec2U32) {
  254. const std::string body = R"(
  255. %val = OpFNegate %u32vec2 %u32vec2_01
  256. )";
  257. CompileSuccessfully(GenerateCode(body).c_str());
  258. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  259. EXPECT_THAT(
  260. getDiagnosticString(),
  261. HasSubstr(
  262. "Expected floating scalar or vector type as Result Type: FNegate"));
  263. }
  264. TEST_F(ValidateArithmetics, FNegateWrongOperand) {
  265. const std::string body = R"(
  266. %val = OpFNegate %f32 %u32_0
  267. )";
  268. CompileSuccessfully(GenerateCode(body).c_str());
  269. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  270. EXPECT_THAT(getDiagnosticString(),
  271. HasSubstr("Expected arithmetic operands to be of Result Type: "
  272. "FNegate operand index 2"));
  273. }
  274. TEST_F(ValidateArithmetics, FMulTypeIdU32) {
  275. const std::string body = R"(
  276. %val = OpFMul %u32 %u32_0 %u32_1
  277. )";
  278. CompileSuccessfully(GenerateCode(body).c_str());
  279. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  280. EXPECT_THAT(
  281. getDiagnosticString(),
  282. HasSubstr(
  283. "Expected floating scalar or vector type as Result Type: FMul"));
  284. }
  285. TEST_F(ValidateArithmetics, FMulTypeIdVec2U32) {
  286. const std::string body = R"(
  287. %val = OpFMul %u32vec2 %u32vec2_01 %u32vec2_12
  288. )";
  289. CompileSuccessfully(GenerateCode(body).c_str());
  290. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  291. EXPECT_THAT(
  292. getDiagnosticString(),
  293. HasSubstr(
  294. "Expected floating scalar or vector type as Result Type: FMul"));
  295. }
  296. TEST_F(ValidateArithmetics, FMulWrongOperand1) {
  297. const std::string body = R"(
  298. %val = OpFMul %f32 %u32_0 %f32_1
  299. )";
  300. CompileSuccessfully(GenerateCode(body).c_str());
  301. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  302. EXPECT_THAT(getDiagnosticString(),
  303. HasSubstr("Expected arithmetic operands to be of Result Type: "
  304. "FMul operand index 2"));
  305. }
  306. TEST_F(ValidateArithmetics, FMulWrongOperand2) {
  307. const std::string body = R"(
  308. %val = OpFMul %f32 %f32_0 %u32_1
  309. )";
  310. CompileSuccessfully(GenerateCode(body).c_str());
  311. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  312. EXPECT_THAT(getDiagnosticString(),
  313. HasSubstr("Expected arithmetic operands to be of Result Type: "
  314. "FMul operand index 3"));
  315. }
  316. TEST_F(ValidateArithmetics, FMulWrongVectorOperand1) {
  317. const std::string body = R"(
  318. %val = OpFMul %f64vec3 %f32vec3_123 %f64vec3_012
  319. )";
  320. CompileSuccessfully(GenerateCode(body).c_str());
  321. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  322. EXPECT_THAT(getDiagnosticString(),
  323. HasSubstr("Expected arithmetic operands to be of Result Type: "
  324. "FMul operand index 2"));
  325. }
  326. TEST_F(ValidateArithmetics, FMulWrongVectorOperand2) {
  327. const std::string body = R"(
  328. %val = OpFMul %f32vec3 %f32vec3_123 %f64vec3_012
  329. )";
  330. CompileSuccessfully(GenerateCode(body).c_str());
  331. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  332. EXPECT_THAT(getDiagnosticString(),
  333. HasSubstr("Expected arithmetic operands to be of Result Type: "
  334. "FMul operand index 3"));
  335. }
  336. TEST_F(ValidateArithmetics, IMulFloatTypeId) {
  337. const std::string body = R"(
  338. %val = OpIMul %f32 %u32_0 %s32_1
  339. )";
  340. CompileSuccessfully(GenerateCode(body).c_str());
  341. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  342. EXPECT_THAT(
  343. getDiagnosticString(),
  344. HasSubstr("Expected int scalar or vector type as Result Type: IMul"));
  345. }
  346. TEST_F(ValidateArithmetics, IMulFloatOperand1) {
  347. const std::string body = R"(
  348. %val = OpIMul %u32 %f32_0 %s32_1
  349. )";
  350. CompileSuccessfully(GenerateCode(body).c_str());
  351. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  352. EXPECT_THAT(getDiagnosticString(),
  353. HasSubstr("Expected int scalar or vector type as operand: "
  354. "IMul operand index 2"));
  355. }
  356. TEST_F(ValidateArithmetics, IMulFloatOperand2) {
  357. const std::string body = R"(
  358. %val = OpIMul %u32 %s32_0 %f32_1
  359. )";
  360. CompileSuccessfully(GenerateCode(body).c_str());
  361. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  362. EXPECT_THAT(getDiagnosticString(),
  363. HasSubstr("Expected int scalar or vector type as operand: "
  364. "IMul operand index 3"));
  365. }
  366. TEST_F(ValidateArithmetics, IMulWrongBitWidthOperand1) {
  367. const std::string body = R"(
  368. %val = OpIMul %u64 %u32_0 %s64_1
  369. )";
  370. CompileSuccessfully(GenerateCode(body).c_str());
  371. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  372. EXPECT_THAT(
  373. getDiagnosticString(),
  374. HasSubstr("Expected arithmetic operands to have the same bit width "
  375. "as Result Type: IMul operand index 2"));
  376. }
  377. TEST_F(ValidateArithmetics, IMulWrongBitWidthOperand2) {
  378. const std::string body = R"(
  379. %val = OpIMul %u32 %u32_0 %s64_1
  380. )";
  381. CompileSuccessfully(GenerateCode(body).c_str());
  382. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  383. EXPECT_THAT(
  384. getDiagnosticString(),
  385. HasSubstr("Expected arithmetic operands to have the same bit width "
  386. "as Result Type: IMul operand index 3"));
  387. }
  388. TEST_F(ValidateArithmetics, IMulWrongBitWidthVector) {
  389. const std::string body = R"(
  390. %val = OpIMul %u64vec3 %u32vec3_012 %u32vec3_123
  391. )";
  392. CompileSuccessfully(GenerateCode(body).c_str());
  393. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  394. EXPECT_THAT(
  395. getDiagnosticString(),
  396. HasSubstr("Expected arithmetic operands to have the same bit width "
  397. "as Result Type: IMul operand index 2"));
  398. }
  399. TEST_F(ValidateArithmetics, IMulVectorScalarOperand1) {
  400. const std::string body = R"(
  401. %val = OpIMul %u32vec2 %u32_0 %u32vec2_01
  402. )";
  403. CompileSuccessfully(GenerateCode(body).c_str());
  404. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  405. EXPECT_THAT(
  406. getDiagnosticString(),
  407. HasSubstr("Expected arithmetic operands to have the same dimension "
  408. "as Result Type: IMul operand index 2"));
  409. }
  410. TEST_F(ValidateArithmetics, IMulVectorScalarOperand2) {
  411. const std::string body = R"(
  412. %val = OpIMul %u32vec2 %u32vec2_01 %u32_0
  413. )";
  414. CompileSuccessfully(GenerateCode(body).c_str());
  415. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  416. EXPECT_THAT(
  417. getDiagnosticString(),
  418. HasSubstr("Expected arithmetic operands to have the same dimension "
  419. "as Result Type: IMul operand index 3"));
  420. }
  421. TEST_F(ValidateArithmetics, IMulScalarVectorOperand1) {
  422. const std::string body = R"(
  423. %val = OpIMul %s32 %u32vec2_01 %u32_0
  424. )";
  425. CompileSuccessfully(GenerateCode(body).c_str());
  426. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  427. EXPECT_THAT(
  428. getDiagnosticString(),
  429. HasSubstr("Expected arithmetic operands to have the same dimension "
  430. "as Result Type: IMul operand index 2"));
  431. }
  432. TEST_F(ValidateArithmetics, IMulScalarVectorOperand2) {
  433. const std::string body = R"(
  434. %val = OpIMul %u32 %u32_0 %s32vec2_01
  435. )";
  436. CompileSuccessfully(GenerateCode(body).c_str());
  437. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  438. EXPECT_THAT(
  439. getDiagnosticString(),
  440. HasSubstr("Expected arithmetic operands to have the same dimension "
  441. "as Result Type: IMul operand index 3"));
  442. }
  443. TEST_F(ValidateArithmetics, SNegateFloat) {
  444. const std::string body = R"(
  445. %val = OpSNegate %s32 %f32_1
  446. )";
  447. CompileSuccessfully(GenerateCode(body).c_str());
  448. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  449. EXPECT_THAT(getDiagnosticString(),
  450. HasSubstr("Expected int scalar or vector type as operand: "
  451. "SNegate operand index 2"));
  452. }
  453. TEST_F(ValidateArithmetics, UDivFloatType) {
  454. const std::string body = R"(
  455. %val = OpUDiv %f32 %u32_2 %u32_1
  456. )";
  457. CompileSuccessfully(GenerateCode(body).c_str());
  458. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  459. EXPECT_THAT(
  460. getDiagnosticString(),
  461. HasSubstr(
  462. "Expected unsigned int scalar or vector type as Result Type: UDiv"));
  463. }
  464. TEST_F(ValidateArithmetics, UDivSignedIntType) {
  465. const std::string body = R"(
  466. %val = OpUDiv %s32 %u32_2 %u32_1
  467. )";
  468. CompileSuccessfully(GenerateCode(body).c_str());
  469. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  470. EXPECT_THAT(
  471. getDiagnosticString(),
  472. HasSubstr(
  473. "Expected unsigned int scalar or vector type as Result Type: UDiv"));
  474. }
  475. TEST_F(ValidateArithmetics, UDivWrongOperand1) {
  476. const std::string body = R"(
  477. %val = OpUDiv %u64 %f64_2 %u64_1
  478. )";
  479. CompileSuccessfully(GenerateCode(body).c_str());
  480. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  481. EXPECT_THAT(getDiagnosticString(),
  482. HasSubstr("Expected arithmetic operands to be of Result Type: "
  483. "UDiv operand index 2"));
  484. }
  485. TEST_F(ValidateArithmetics, UDivWrongOperand2) {
  486. const std::string body = R"(
  487. %val = OpUDiv %u64 %u64_2 %u32_1
  488. )";
  489. CompileSuccessfully(GenerateCode(body).c_str());
  490. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  491. EXPECT_THAT(getDiagnosticString(),
  492. HasSubstr("Expected arithmetic operands to be of Result Type: "
  493. "UDiv operand index 3"));
  494. }
  495. TEST_F(ValidateArithmetics, DotSuccess) {
  496. const std::string body = R"(
  497. %val = OpDot %f32 %f32vec2_01 %f32vec2_12
  498. )";
  499. CompileSuccessfully(GenerateCode(body).c_str());
  500. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  501. }
  502. TEST_F(ValidateArithmetics, DotWrongTypeId) {
  503. const std::string body = R"(
  504. %val = OpDot %u32 %u32vec2_01 %u32vec2_12
  505. )";
  506. CompileSuccessfully(GenerateCode(body).c_str());
  507. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  508. EXPECT_THAT(getDiagnosticString(),
  509. HasSubstr("Expected float scalar type as Result Type: Dot"));
  510. }
  511. TEST_F(ValidateArithmetics, DotNotVectorTypeOperand1) {
  512. const std::string body = R"(
  513. %val = OpDot %f32 %f32 %f32vec2_12
  514. )";
  515. CompileSuccessfully(GenerateCode(body).c_str());
  516. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  517. EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 6[%float] cannot be a "
  518. "type"));
  519. }
  520. TEST_F(ValidateArithmetics, DotNotVectorTypeOperand2) {
  521. const std::string body = R"(
  522. %val = OpDot %f32 %f32vec3_012 %f32_1
  523. )";
  524. CompileSuccessfully(GenerateCode(body).c_str());
  525. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  526. EXPECT_THAT(
  527. getDiagnosticString(),
  528. HasSubstr("Expected float vector as operand: Dot operand index 3"));
  529. }
  530. TEST_F(ValidateArithmetics, DotWrongComponentOperand1) {
  531. const std::string body = R"(
  532. %val = OpDot %f64 %f32vec2_01 %f64vec2_12
  533. )";
  534. CompileSuccessfully(GenerateCode(body).c_str());
  535. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  536. EXPECT_THAT(getDiagnosticString(),
  537. HasSubstr("Expected component type to be equal to Result Type: "
  538. "Dot operand index 2"));
  539. }
  540. TEST_F(ValidateArithmetics, DotWrongComponentOperand2) {
  541. const std::string body = R"(
  542. %val = OpDot %f32 %f32vec2_01 %f64vec2_12
  543. )";
  544. CompileSuccessfully(GenerateCode(body).c_str());
  545. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  546. EXPECT_THAT(getDiagnosticString(),
  547. HasSubstr("Expected component type to be equal to Result Type: "
  548. "Dot operand index 3"));
  549. }
  550. TEST_F(ValidateArithmetics, DotDifferentVectorSize) {
  551. const std::string body = R"(
  552. %val = OpDot %f32 %f32vec2_01 %f32vec3_123
  553. )";
  554. CompileSuccessfully(GenerateCode(body).c_str());
  555. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  556. EXPECT_THAT(
  557. getDiagnosticString(),
  558. HasSubstr(
  559. "Expected operands to have the same number of componenets: Dot"));
  560. }
  561. TEST_F(ValidateArithmetics, VectorTimesScalarSuccess) {
  562. const std::string body = R"(
  563. %val = OpVectorTimesScalar %f32vec2 %f32vec2_01 %f32_2
  564. )";
  565. CompileSuccessfully(GenerateCode(body).c_str());
  566. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  567. }
  568. TEST_F(ValidateArithmetics, VectorTimesScalarWrongTypeId) {
  569. const std::string body = R"(
  570. %val = OpVectorTimesScalar %u32vec2 %f32vec2_01 %f32_2
  571. )";
  572. CompileSuccessfully(GenerateCode(body).c_str());
  573. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  574. EXPECT_THAT(getDiagnosticString(),
  575. HasSubstr("Expected float vector type as Result Type: "
  576. "VectorTimesScalar"));
  577. }
  578. TEST_F(ValidateArithmetics, VectorTimesScalarWrongVector) {
  579. const std::string body = R"(
  580. %val = OpVectorTimesScalar %f32vec2 %f32vec3_012 %f32_2
  581. )";
  582. CompileSuccessfully(GenerateCode(body).c_str());
  583. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  584. EXPECT_THAT(
  585. getDiagnosticString(),
  586. HasSubstr("Expected vector operand type to be equal to Result Type: "
  587. "VectorTimesScalar"));
  588. }
  589. TEST_F(ValidateArithmetics, VectorTimesScalarWrongScalar) {
  590. const std::string body = R"(
  591. %val = OpVectorTimesScalar %f32vec2 %f32vec2_01 %f64_2
  592. )";
  593. CompileSuccessfully(GenerateCode(body).c_str());
  594. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  595. EXPECT_THAT(
  596. getDiagnosticString(),
  597. HasSubstr("Expected scalar operand type to be equal to the component "
  598. "type of the vector operand: VectorTimesScalar"));
  599. }
  600. TEST_F(ValidateArithmetics, MatrixTimesScalarSuccess) {
  601. const std::string body = R"(
  602. %val = OpMatrixTimesScalar %f32mat22 %f32mat22_1212 %f32_2
  603. )";
  604. CompileSuccessfully(GenerateCode(body).c_str());
  605. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  606. }
  607. TEST_F(ValidateArithmetics, MatrixTimesScalarWrongTypeId) {
  608. const std::string body = R"(
  609. %val = OpMatrixTimesScalar %f32vec2 %f32mat22_1212 %f32_2
  610. )";
  611. CompileSuccessfully(GenerateCode(body).c_str());
  612. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  613. EXPECT_THAT(getDiagnosticString(),
  614. HasSubstr("Expected float matrix type as Result Type: "
  615. "MatrixTimesScalar"));
  616. }
  617. TEST_F(ValidateArithmetics, MatrixTimesScalarWrongMatrix) {
  618. const std::string body = R"(
  619. %val = OpMatrixTimesScalar %f32mat22 %f32vec2_01 %f32_2
  620. )";
  621. CompileSuccessfully(GenerateCode(body).c_str());
  622. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  623. EXPECT_THAT(
  624. getDiagnosticString(),
  625. HasSubstr("Expected matrix operand type to be equal to Result Type: "
  626. "MatrixTimesScalar"));
  627. }
  628. TEST_F(ValidateArithmetics, MatrixTimesScalarWrongScalar) {
  629. const std::string body = R"(
  630. %val = OpMatrixTimesScalar %f32mat22 %f32mat22_1212 %f64_2
  631. )";
  632. CompileSuccessfully(GenerateCode(body).c_str());
  633. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  634. EXPECT_THAT(
  635. getDiagnosticString(),
  636. HasSubstr("Expected scalar operand type to be equal to the component "
  637. "type of the matrix operand: MatrixTimesScalar"));
  638. }
  639. TEST_F(ValidateArithmetics, VectorTimesMatrix2x22Success) {
  640. const std::string body = R"(
  641. %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f32mat22_1212
  642. )";
  643. CompileSuccessfully(GenerateCode(body).c_str());
  644. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  645. }
  646. TEST_F(ValidateArithmetics, VectorTimesMatrix3x32Success) {
  647. const std::string body = R"(
  648. %val = OpVectorTimesMatrix %f32vec2 %f32vec3_123 %f32mat32_123123
  649. )";
  650. CompileSuccessfully(GenerateCode(body).c_str());
  651. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  652. }
  653. TEST_F(ValidateArithmetics, VectorTimesMatrixWrongTypeId) {
  654. const std::string body = R"(
  655. %val = OpVectorTimesMatrix %f32mat22 %f32vec2_12 %f32mat22_1212
  656. )";
  657. CompileSuccessfully(GenerateCode(body).c_str());
  658. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  659. EXPECT_THAT(getDiagnosticString(),
  660. HasSubstr("Expected float vector type as Result Type: "
  661. "VectorTimesMatrix"));
  662. }
  663. TEST_F(ValidateArithmetics, VectorTimesMatrixNotFloatVector) {
  664. const std::string body = R"(
  665. %val = OpVectorTimesMatrix %f32vec2 %u32vec2_12 %f32mat22_1212
  666. )";
  667. CompileSuccessfully(GenerateCode(body).c_str());
  668. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  669. EXPECT_THAT(getDiagnosticString(),
  670. HasSubstr("Expected float vector type as left operand: "
  671. "VectorTimesMatrix"));
  672. }
  673. TEST_F(ValidateArithmetics, VectorTimesMatrixWrongVectorComponent) {
  674. const std::string body = R"(
  675. %val = OpVectorTimesMatrix %f32vec2 %f64vec2_12 %f32mat22_1212
  676. )";
  677. CompileSuccessfully(GenerateCode(body).c_str());
  678. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  679. EXPECT_THAT(
  680. getDiagnosticString(),
  681. HasSubstr(
  682. "Expected component types of Result Type and vector to be equal: "
  683. "VectorTimesMatrix"));
  684. }
  685. TEST_F(ValidateArithmetics, VectorTimesMatrixWrongMatrix) {
  686. const std::string body = R"(
  687. %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f32vec2_12
  688. )";
  689. CompileSuccessfully(GenerateCode(body).c_str());
  690. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  691. EXPECT_THAT(getDiagnosticString(),
  692. HasSubstr("Expected float matrix type as right operand: "
  693. "VectorTimesMatrix"));
  694. }
  695. TEST_F(ValidateArithmetics, VectorTimesMatrixWrongMatrixComponent) {
  696. const std::string body = R"(
  697. %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f64mat22_1212
  698. )";
  699. CompileSuccessfully(GenerateCode(body).c_str());
  700. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  701. EXPECT_THAT(
  702. getDiagnosticString(),
  703. HasSubstr(
  704. "Expected component types of Result Type and matrix to be equal: "
  705. "VectorTimesMatrix"));
  706. }
  707. TEST_F(ValidateArithmetics, VectorTimesMatrix2eq2x23Fail) {
  708. const std::string body = R"(
  709. %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f32mat23_121212
  710. )";
  711. CompileSuccessfully(GenerateCode(body).c_str());
  712. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  713. EXPECT_THAT(
  714. getDiagnosticString(),
  715. HasSubstr(
  716. "Expected number of columns of the matrix to be equal to Result Type "
  717. "vector size: VectorTimesMatrix"));
  718. }
  719. TEST_F(ValidateArithmetics, VectorTimesMatrix2x32Fail) {
  720. const std::string body = R"(
  721. %val = OpVectorTimesMatrix %f32vec2 %f32vec2_12 %f32mat32_123123
  722. )";
  723. CompileSuccessfully(GenerateCode(body).c_str());
  724. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  725. EXPECT_THAT(
  726. getDiagnosticString(),
  727. HasSubstr(
  728. "Expected number of rows of the matrix to be equal to the vector "
  729. "operand size: VectorTimesMatrix"));
  730. }
  731. TEST_F(ValidateArithmetics, MatrixTimesVector22x2Success) {
  732. const std::string body = R"(
  733. %val = OpMatrixTimesVector %f32vec2 %f32mat22_1212 %f32vec2_12
  734. )";
  735. CompileSuccessfully(GenerateCode(body).c_str());
  736. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  737. }
  738. TEST_F(ValidateArithmetics, MatrixTimesVector23x3Success) {
  739. const std::string body = R"(
  740. %val = OpMatrixTimesVector %f32vec2 %f32mat23_121212 %f32vec3_123
  741. )";
  742. CompileSuccessfully(GenerateCode(body).c_str());
  743. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  744. }
  745. TEST_F(ValidateArithmetics, MatrixTimesVectorWrongTypeId) {
  746. const std::string body = R"(
  747. %val = OpMatrixTimesVector %f32mat22 %f32mat22_1212 %f32vec2_12
  748. )";
  749. CompileSuccessfully(GenerateCode(body).c_str());
  750. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  751. EXPECT_THAT(getDiagnosticString(),
  752. HasSubstr("Expected float vector type as Result Type: "
  753. "MatrixTimesVector"));
  754. }
  755. TEST_F(ValidateArithmetics, MatrixTimesVectorWrongMatrix) {
  756. const std::string body = R"(
  757. %val = OpMatrixTimesVector %f32vec3 %f32vec3_123 %f32vec3_123
  758. )";
  759. CompileSuccessfully(GenerateCode(body).c_str());
  760. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  761. EXPECT_THAT(getDiagnosticString(),
  762. HasSubstr("Expected float matrix type as left operand: "
  763. "MatrixTimesVector"));
  764. }
  765. TEST_F(ValidateArithmetics, MatrixTimesVectorWrongMatrixCol) {
  766. const std::string body = R"(
  767. %val = OpMatrixTimesVector %f32vec3 %f32mat23_121212 %f32vec3_123
  768. )";
  769. CompileSuccessfully(GenerateCode(body).c_str());
  770. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  771. EXPECT_THAT(
  772. getDiagnosticString(),
  773. HasSubstr(
  774. "Expected column type of the matrix to be equal to Result Type: "
  775. "MatrixTimesVector"));
  776. }
  777. TEST_F(ValidateArithmetics, MatrixTimesVectorWrongVector) {
  778. const std::string body = R"(
  779. %val = OpMatrixTimesVector %f32vec2 %f32mat22_1212 %u32vec2_12
  780. )";
  781. CompileSuccessfully(GenerateCode(body).c_str());
  782. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  783. EXPECT_THAT(getDiagnosticString(),
  784. HasSubstr("Expected float vector type as right operand: "
  785. "MatrixTimesVector"));
  786. }
  787. TEST_F(ValidateArithmetics, MatrixTimesVectorDifferentComponents) {
  788. const std::string body = R"(
  789. %val = OpMatrixTimesVector %f32vec2 %f32mat22_1212 %f64vec2_12
  790. )";
  791. CompileSuccessfully(GenerateCode(body).c_str());
  792. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  793. EXPECT_THAT(getDiagnosticString(),
  794. HasSubstr("Expected component types of the operands to be equal: "
  795. "MatrixTimesVector"));
  796. }
  797. TEST_F(ValidateArithmetics, MatrixTimesVector22x3Fail) {
  798. const std::string body = R"(
  799. %val = OpMatrixTimesVector %f32vec2 %f32mat22_1212 %f32vec3_123
  800. )";
  801. CompileSuccessfully(GenerateCode(body).c_str());
  802. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  803. EXPECT_THAT(
  804. getDiagnosticString(),
  805. HasSubstr(
  806. "Expected number of columns of the matrix to be equal to the vector "
  807. "size: MatrixTimesVector"));
  808. }
  809. TEST_F(ValidateArithmetics, MatrixTimesMatrix22x22Success) {
  810. const std::string body = R"(
  811. %val = OpMatrixTimesMatrix %f32mat22 %f32mat22_1212 %f32mat22_1212
  812. )";
  813. CompileSuccessfully(GenerateCode(body).c_str());
  814. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  815. }
  816. TEST_F(ValidateArithmetics, MatrixTimesMatrix23x32Success) {
  817. const std::string body = R"(
  818. %val = OpMatrixTimesMatrix %f32mat22 %f32mat23_121212 %f32mat32_123123
  819. )";
  820. CompileSuccessfully(GenerateCode(body).c_str());
  821. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  822. }
  823. TEST_F(ValidateArithmetics, MatrixTimesMatrix33x33Success) {
  824. const std::string body = R"(
  825. %val = OpMatrixTimesMatrix %f32mat33 %f32mat33_123123123 %f32mat33_123123123
  826. )";
  827. CompileSuccessfully(GenerateCode(body).c_str());
  828. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  829. }
  830. TEST_F(ValidateArithmetics, MatrixTimesMatrixWrongTypeId) {
  831. const std::string body = R"(
  832. %val = OpMatrixTimesMatrix %f32vec2 %f32mat22_1212 %f32mat22_1212
  833. )";
  834. CompileSuccessfully(GenerateCode(body).c_str());
  835. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  836. EXPECT_THAT(
  837. getDiagnosticString(),
  838. HasSubstr(
  839. "Expected float matrix type as Result Type: MatrixTimesMatrix"));
  840. }
  841. TEST_F(ValidateArithmetics, MatrixTimesMatrixWrongLeftOperand) {
  842. const std::string body = R"(
  843. %val = OpMatrixTimesMatrix %f32mat22 %f32vec2_12 %f32mat22_1212
  844. )";
  845. CompileSuccessfully(GenerateCode(body).c_str());
  846. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  847. EXPECT_THAT(
  848. getDiagnosticString(),
  849. HasSubstr(
  850. "Expected float matrix type as left operand: MatrixTimesMatrix"));
  851. }
  852. TEST_F(ValidateArithmetics, MatrixTimesMatrixWrongRightOperand) {
  853. const std::string body = R"(
  854. %val = OpMatrixTimesMatrix %f32mat22 %f32mat22_1212 %f32vec2_12
  855. )";
  856. CompileSuccessfully(GenerateCode(body).c_str());
  857. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  858. EXPECT_THAT(
  859. getDiagnosticString(),
  860. HasSubstr(
  861. "Expected float matrix type as right operand: MatrixTimesMatrix"));
  862. }
  863. TEST_F(ValidateArithmetics, MatrixTimesMatrix32x23Fail) {
  864. const std::string body = R"(
  865. %val = OpMatrixTimesMatrix %f32mat22 %f32mat32_123123 %f32mat23_121212
  866. )";
  867. CompileSuccessfully(GenerateCode(body).c_str());
  868. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  869. EXPECT_THAT(
  870. getDiagnosticString(),
  871. HasSubstr(
  872. "Expected column types of Result Type and left matrix to be equal: "
  873. "MatrixTimesMatrix"));
  874. }
  875. TEST_F(ValidateArithmetics, MatrixTimesMatrixDifferentComponents) {
  876. const std::string body = R"(
  877. %val = OpMatrixTimesMatrix %f32mat22 %f32mat22_1212 %f64mat22_1212
  878. )";
  879. CompileSuccessfully(GenerateCode(body).c_str());
  880. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  881. EXPECT_THAT(getDiagnosticString(),
  882. HasSubstr("Expected component types of Result Type and right "
  883. "matrix to be equal: "
  884. "MatrixTimesMatrix"));
  885. }
  886. TEST_F(ValidateArithmetics, MatrixTimesMatrix23x23Fail) {
  887. const std::string body = R"(
  888. %val = OpMatrixTimesMatrix %f32mat22 %f32mat23_121212 %f32mat23_121212
  889. )";
  890. CompileSuccessfully(GenerateCode(body).c_str());
  891. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  892. EXPECT_THAT(getDiagnosticString(),
  893. HasSubstr("Expected number of columns of Result Type and right "
  894. "matrix to be equal: "
  895. "MatrixTimesMatrix"));
  896. }
  897. TEST_F(ValidateArithmetics, MatrixTimesMatrix23x22Fail) {
  898. const std::string body = R"(
  899. %val = OpMatrixTimesMatrix %f32mat22 %f32mat23_121212 %f32mat22_1212
  900. )";
  901. CompileSuccessfully(GenerateCode(body).c_str());
  902. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  903. EXPECT_THAT(getDiagnosticString(),
  904. HasSubstr("Expected number of columns of left matrix and number "
  905. "of rows of right "
  906. "matrix to be equal: MatrixTimesMatrix"));
  907. }
  908. TEST_F(ValidateArithmetics, OuterProduct2x2Success) {
  909. const std::string body = R"(
  910. %val = OpOuterProduct %f32mat22 %f32vec2_12 %f32vec2_01
  911. )";
  912. CompileSuccessfully(GenerateCode(body).c_str());
  913. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  914. }
  915. TEST_F(ValidateArithmetics, OuterProduct3x2Success) {
  916. const std::string body = R"(
  917. %val = OpOuterProduct %f32mat32 %f32vec3_123 %f32vec2_01
  918. )";
  919. CompileSuccessfully(GenerateCode(body).c_str());
  920. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  921. }
  922. TEST_F(ValidateArithmetics, OuterProduct2x3Success) {
  923. const std::string body = R"(
  924. %val = OpOuterProduct %f32mat23 %f32vec2_01 %f32vec3_123
  925. )";
  926. CompileSuccessfully(GenerateCode(body).c_str());
  927. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  928. }
  929. TEST_F(ValidateArithmetics, OuterProductWrongTypeId) {
  930. const std::string body = R"(
  931. %val = OpOuterProduct %f32vec2 %f32vec2_01 %f32vec3_123
  932. )";
  933. CompileSuccessfully(GenerateCode(body).c_str());
  934. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  935. EXPECT_THAT(getDiagnosticString(),
  936. HasSubstr("Expected float matrix type as Result Type: "
  937. "OuterProduct"));
  938. }
  939. TEST_F(ValidateArithmetics, OuterProductWrongLeftOperand) {
  940. const std::string body = R"(
  941. %val = OpOuterProduct %f32mat22 %f32vec3_123 %f32vec2_01
  942. )";
  943. CompileSuccessfully(GenerateCode(body).c_str());
  944. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  945. EXPECT_THAT(
  946. getDiagnosticString(),
  947. HasSubstr("Expected column type of Result Type to be equal to the type "
  948. "of the left operand: OuterProduct"));
  949. }
  950. TEST_F(ValidateArithmetics, OuterProductRightOperandNotFloatVector) {
  951. const std::string body = R"(
  952. %val = OpOuterProduct %f32mat22 %f32vec2_12 %u32vec2_01
  953. )";
  954. CompileSuccessfully(GenerateCode(body).c_str());
  955. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  956. EXPECT_THAT(
  957. getDiagnosticString(),
  958. HasSubstr("Expected float vector type as right operand: OuterProduct"));
  959. }
  960. TEST_F(ValidateArithmetics, OuterProductRightOperandWrongComponent) {
  961. const std::string body = R"(
  962. %val = OpOuterProduct %f32mat22 %f32vec2_12 %f64vec2_01
  963. )";
  964. CompileSuccessfully(GenerateCode(body).c_str());
  965. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  966. EXPECT_THAT(getDiagnosticString(),
  967. HasSubstr("Expected component types of the operands to be equal: "
  968. "OuterProduct"));
  969. }
  970. TEST_F(ValidateArithmetics, OuterProductRightOperandWrongDimension) {
  971. const std::string body = R"(
  972. %val = OpOuterProduct %f32mat22 %f32vec2_12 %f32vec3_123
  973. )";
  974. CompileSuccessfully(GenerateCode(body).c_str());
  975. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  976. EXPECT_THAT(
  977. getDiagnosticString(),
  978. HasSubstr("Expected number of columns of the matrix to be equal to the "
  979. "vector size of the right operand: OuterProduct"));
  980. }
  981. std::string GenerateCoopMatCode(const std::string& extra_types,
  982. const std::string& main_body) {
  983. const std::string prefix =
  984. R"(
  985. OpCapability Shader
  986. OpCapability Float16
  987. OpCapability CooperativeMatrixNV
  988. OpExtension "SPV_NV_cooperative_matrix"
  989. OpMemoryModel Logical GLSL450
  990. OpEntryPoint GLCompute %main "main"
  991. %void = OpTypeVoid
  992. %func = OpTypeFunction %void
  993. %bool = OpTypeBool
  994. %f16 = OpTypeFloat 16
  995. %f32 = OpTypeFloat 32
  996. %u32 = OpTypeInt 32 0
  997. %s32 = OpTypeInt 32 1
  998. %u32_8 = OpConstant %u32 8
  999. %u32_16 = OpConstant %u32 16
  1000. %u32_4 = OpConstant %u32 4
  1001. %subgroup = OpConstant %u32 3
  1002. %f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
  1003. %u32mat = OpTypeCooperativeMatrixNV %u32 %subgroup %u32_8 %u32_8
  1004. %s32mat = OpTypeCooperativeMatrixNV %s32 %subgroup %u32_8 %u32_8
  1005. %f16_1 = OpConstant %f16 1
  1006. %f32_1 = OpConstant %f32 1
  1007. %u32_1 = OpConstant %u32 1
  1008. %s32_1 = OpConstant %s32 1
  1009. %f16mat_1 = OpConstantComposite %f16mat %f16_1
  1010. %u32mat_1 = OpConstantComposite %u32mat %u32_1
  1011. %s32mat_1 = OpConstantComposite %s32mat %s32_1
  1012. %u32_c1 = OpSpecConstant %u32 1
  1013. %u32_c2 = OpSpecConstant %u32 2
  1014. %f16matc = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_c1 %u32_c2
  1015. %f16matc_1 = OpConstantComposite %f16matc %f16_1
  1016. %mat16x4 = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_16 %u32_4
  1017. %mat4x16 = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_4 %u32_16
  1018. %mat16x16 = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_16 %u32_16
  1019. %f16mat_16x4_1 = OpConstantComposite %mat16x4 %f16_1
  1020. %f16mat_4x16_1 = OpConstantComposite %mat4x16 %f16_1
  1021. %f16mat_16x16_1 = OpConstantComposite %mat16x16 %f16_1)";
  1022. const std::string func_begin =
  1023. R"(
  1024. %main = OpFunction %void None %func
  1025. %main_entry = OpLabel)";
  1026. const std::string suffix =
  1027. R"(
  1028. OpReturn
  1029. OpFunctionEnd)";
  1030. return prefix + extra_types + func_begin + main_body + suffix;
  1031. }
  1032. TEST_F(ValidateArithmetics, CoopMatSuccess) {
  1033. const std::string body = R"(
  1034. %val1 = OpFAdd %f16mat %f16mat_1 %f16mat_1
  1035. %val2 = OpFSub %f16mat %f16mat_1 %f16mat_1
  1036. %val3 = OpFDiv %f16mat %f16mat_1 %f16mat_1
  1037. %val4 = OpFNegate %f16mat %f16mat_1
  1038. %val5 = OpIAdd %u32mat %u32mat_1 %u32mat_1
  1039. %val6 = OpISub %u32mat %u32mat_1 %u32mat_1
  1040. %val7 = OpUDiv %u32mat %u32mat_1 %u32mat_1
  1041. %val8 = OpIAdd %s32mat %s32mat_1 %s32mat_1
  1042. %val9 = OpISub %s32mat %s32mat_1 %s32mat_1
  1043. %val10 = OpSDiv %s32mat %s32mat_1 %s32mat_1
  1044. %val11 = OpSNegate %s32mat %s32mat_1
  1045. %val12 = OpMatrixTimesScalar %f16mat %f16mat_1 %f16_1
  1046. %val13 = OpMatrixTimesScalar %u32mat %u32mat_1 %u32_1
  1047. %val14 = OpMatrixTimesScalar %s32mat %s32mat_1 %s32_1
  1048. %val15 = OpCooperativeMatrixMulAddNV %mat16x16 %f16mat_16x4_1 %f16mat_4x16_1 %f16mat_16x16_1
  1049. %val16 = OpCooperativeMatrixMulAddNV %f16matc %f16matc_1 %f16matc_1 %f16matc_1
  1050. )";
  1051. CompileSuccessfully(GenerateCoopMatCode("", body).c_str());
  1052. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1053. }
  1054. TEST_F(ValidateArithmetics, CoopMatFMulFail) {
  1055. const std::string body = R"(
  1056. %val1 = OpFMul %f16mat %f16mat_1 %f16mat_1
  1057. )";
  1058. CompileSuccessfully(GenerateCoopMatCode("", body).c_str());
  1059. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1060. EXPECT_THAT(
  1061. getDiagnosticString(),
  1062. HasSubstr(
  1063. "Expected floating scalar or vector type as Result Type: FMul"));
  1064. }
  1065. TEST_F(ValidateArithmetics, CoopMatMatrixTimesScalarMismatchFail) {
  1066. const std::string body = R"(
  1067. %val1 = OpMatrixTimesScalar %f16mat %f16mat_1 %f32_1
  1068. )";
  1069. CompileSuccessfully(GenerateCoopMatCode("", body).c_str());
  1070. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1071. EXPECT_THAT(
  1072. getDiagnosticString(),
  1073. HasSubstr("Expected scalar operand type to be equal to the component "
  1074. "type of the matrix operand: MatrixTimesScalar"));
  1075. }
  1076. TEST_F(ValidateArithmetics, CoopMatScopeFail) {
  1077. const std::string types = R"(
  1078. %workgroup = OpConstant %u32 2
  1079. %mat16x16_wg = OpTypeCooperativeMatrixNV %f16 %workgroup %u32_16 %u32_16
  1080. %f16matwg_16x16_1 = OpConstantComposite %mat16x16_wg %f16_1
  1081. )";
  1082. const std::string body = R"(
  1083. %val1 = OpCooperativeMatrixMulAddNV %mat16x16 %f16mat_16x4_1 %f16mat_4x16_1 %f16matwg_16x16_1
  1084. )";
  1085. CompileSuccessfully(GenerateCoopMatCode(types, body).c_str());
  1086. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1087. EXPECT_THAT(
  1088. getDiagnosticString(),
  1089. HasSubstr(
  1090. "Cooperative matrix scopes must match: CooperativeMatrixMulAddNV"));
  1091. }
  1092. TEST_F(ValidateArithmetics, CoopMatDimFail) {
  1093. const std::string body = R"(
  1094. %val1 = OpCooperativeMatrixMulAddNV %mat16x16 %f16mat_4x16_1 %f16mat_16x4_1 %f16mat_16x16_1
  1095. )";
  1096. CompileSuccessfully(GenerateCoopMatCode("", body).c_str());
  1097. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1098. EXPECT_THAT(
  1099. getDiagnosticString(),
  1100. HasSubstr("Cooperative matrix 'M' mismatch: CooperativeMatrixMulAddNV"));
  1101. }
  1102. TEST_F(ValidateArithmetics, IAddCarrySuccess) {
  1103. const std::string body = R"(
  1104. %val1 = OpIAddCarry %struct_u32_u32 %u32_0 %u32_1
  1105. %val2 = OpIAddCarry %struct_u32vec2_u32vec2 %u32vec2_01 %u32vec2_12
  1106. )";
  1107. CompileSuccessfully(GenerateCode(body).c_str());
  1108. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1109. }
  1110. TEST_F(ValidateArithmetics, IAddCarryResultTypeNotStruct) {
  1111. const std::string body = R"(
  1112. %val = OpIAddCarry %u32 %u32_0 %u32_1
  1113. )";
  1114. CompileSuccessfully(GenerateCode(body).c_str());
  1115. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1116. EXPECT_THAT(getDiagnosticString(),
  1117. HasSubstr("Expected a struct as Result Type: IAddCarry"));
  1118. }
  1119. TEST_F(ValidateArithmetics, IAddCarryResultTypeNotTwoMembers) {
  1120. const std::string body = R"(
  1121. %val = OpIAddCarry %struct_u32_u32_u32 %u32_0 %u32_1
  1122. )";
  1123. CompileSuccessfully(GenerateCode(body).c_str());
  1124. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1125. EXPECT_THAT(
  1126. getDiagnosticString(),
  1127. HasSubstr("Expected Result Type struct to have two members: IAddCarry"));
  1128. }
  1129. TEST_F(ValidateArithmetics, IAddCarryResultTypeMemberNotUnsignedInt) {
  1130. const std::string body = R"(
  1131. %val = OpIAddCarry %struct_s32_s32 %s32_0 %s32_1
  1132. )";
  1133. CompileSuccessfully(GenerateCode(body).c_str());
  1134. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1135. EXPECT_THAT(getDiagnosticString(),
  1136. HasSubstr("Expected Result Type struct member types to be "
  1137. "unsigned integer scalar "
  1138. "or vector: IAddCarry"));
  1139. }
  1140. TEST_F(ValidateArithmetics, IAddCarryWrongLeftOperand) {
  1141. const std::string body = R"(
  1142. %val = OpIAddCarry %struct_u32_u32 %s32_0 %u32_1
  1143. )";
  1144. CompileSuccessfully(GenerateCode(body).c_str());
  1145. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1146. EXPECT_THAT(getDiagnosticString(),
  1147. HasSubstr("Expected both operands to be of Result Type member "
  1148. "type: IAddCarry"));
  1149. }
  1150. TEST_F(ValidateArithmetics, IAddCarryWrongRightOperand) {
  1151. const std::string body = R"(
  1152. %val = OpIAddCarry %struct_u32_u32 %u32_0 %s32_1
  1153. )";
  1154. CompileSuccessfully(GenerateCode(body).c_str());
  1155. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1156. EXPECT_THAT(getDiagnosticString(),
  1157. HasSubstr("Expected both operands to be of Result Type member "
  1158. "type: IAddCarry"));
  1159. }
  1160. TEST_F(ValidateArithmetics, OpSMulExtendedSuccess) {
  1161. const std::string body = R"(
  1162. %val1 = OpSMulExtended %struct_u32_u32 %u32_0 %u32_1
  1163. %val2 = OpSMulExtended %struct_s32_s32 %s32_0 %s32_1
  1164. %val3 = OpSMulExtended %struct_u32vec2_u32vec2 %u32vec2_01 %u32vec2_12
  1165. %val4 = OpSMulExtended %struct_s32vec2_s32vec2 %s32vec2_01 %s32vec2_12
  1166. )";
  1167. CompileSuccessfully(GenerateCode(body).c_str());
  1168. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1169. }
  1170. TEST_F(ValidateArithmetics, SMulExtendedResultTypeMemberNotInt) {
  1171. const std::string body = R"(
  1172. %val = OpSMulExtended %struct_f32_f32 %f32_0 %f32_1
  1173. )";
  1174. CompileSuccessfully(GenerateCode(body).c_str());
  1175. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1176. EXPECT_THAT(
  1177. getDiagnosticString(),
  1178. HasSubstr("Expected Result Type struct member types to be integer scalar "
  1179. "or vector: SMulExtended"));
  1180. }
  1181. TEST_F(ValidateArithmetics, SMulExtendedResultTypeMembersNotIdentical) {
  1182. const std::string body = R"(
  1183. %val = OpSMulExtended %struct_s32_u32 %s32_0 %s32_1
  1184. )";
  1185. CompileSuccessfully(GenerateCode(body).c_str());
  1186. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1187. EXPECT_THAT(
  1188. getDiagnosticString(),
  1189. HasSubstr("Expected Result Type struct member types to be identical: "
  1190. "SMulExtended"));
  1191. }
  1192. } // namespace
  1193. } // namespace val
  1194. } // namespace spvtools