amd_ext_to_khr.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. // Copyright (c) 2019 Google LLC.
  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 <vector>
  15. #include "gmock/gmock.h"
  16. #include "test/opt/pass_fixture.h"
  17. #include "test/opt/pass_utils.h"
  18. namespace spvtools {
  19. namespace opt {
  20. namespace {
  21. using AmdExtToKhrTest = PassTest<::testing::Test>;
  22. using ::testing::HasSubstr;
  23. std::string GetTest(std::string op_code, std::string new_op_code) {
  24. const std::string text = R"(
  25. ; CHECK: OpCapability Shader
  26. ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
  27. ; CHECK: OpFunction
  28. ; CHECK-NEXT: OpLabel
  29. ; CHECK-NEXT: [[undef:%\w+]] = OpUndef %uint
  30. ; CHECK-NEXT: )" + new_op_code +
  31. R"( %uint %uint_3 Reduce [[undef]]
  32. OpCapability Shader
  33. OpCapability Groups
  34. OpExtension "SPV_AMD_shader_ballot"
  35. OpMemoryModel Logical GLSL450
  36. OpEntryPoint Fragment %1 "func"
  37. OpExecutionMode %1 OriginUpperLeft
  38. %void = OpTypeVoid
  39. %3 = OpTypeFunction %void
  40. %uint = OpTypeInt 32 0
  41. %uint_3 = OpConstant %uint 3
  42. %1 = OpFunction %void None %3
  43. %6 = OpLabel
  44. %7 = OpUndef %uint
  45. %8 = )" + op_code +
  46. R"( %uint %uint_3 Reduce %7
  47. OpReturn
  48. OpFunctionEnd
  49. )";
  50. return text;
  51. }
  52. TEST_F(AmdExtToKhrTest, ReplaceGroupIAddNonUniformAMD) {
  53. std::string text =
  54. GetTest("OpGroupIAddNonUniformAMD", "OpGroupNonUniformIAdd");
  55. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  56. }
  57. TEST_F(AmdExtToKhrTest, ReplaceGroupFAddNonUniformAMD) {
  58. std::string text =
  59. GetTest("OpGroupFAddNonUniformAMD", "OpGroupNonUniformFAdd");
  60. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  61. }
  62. TEST_F(AmdExtToKhrTest, ReplaceGroupUMinNonUniformAMD) {
  63. std::string text =
  64. GetTest("OpGroupUMinNonUniformAMD", "OpGroupNonUniformUMin");
  65. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  66. }
  67. TEST_F(AmdExtToKhrTest, ReplaceGroupSMinNonUniformAMD) {
  68. std::string text =
  69. GetTest("OpGroupSMinNonUniformAMD", "OpGroupNonUniformSMin");
  70. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  71. }
  72. TEST_F(AmdExtToKhrTest, ReplaceGroupFMinNonUniformAMD) {
  73. std::string text =
  74. GetTest("OpGroupFMinNonUniformAMD", "OpGroupNonUniformFMin");
  75. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  76. }
  77. TEST_F(AmdExtToKhrTest, ReplaceGroupUMaxNonUniformAMD) {
  78. std::string text =
  79. GetTest("OpGroupUMaxNonUniformAMD", "OpGroupNonUniformUMax");
  80. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  81. }
  82. TEST_F(AmdExtToKhrTest, ReplaceGroupSMaxNonUniformAMD) {
  83. std::string text =
  84. GetTest("OpGroupSMaxNonUniformAMD", "OpGroupNonUniformSMax");
  85. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  86. }
  87. TEST_F(AmdExtToKhrTest, ReplaceGroupFMaxNonUniformAMD) {
  88. std::string text =
  89. GetTest("OpGroupFMaxNonUniformAMD", "OpGroupNonUniformFMax");
  90. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  91. }
  92. TEST_F(AmdExtToKhrTest, ReplaceMbcntAMD) {
  93. const std::string text = R"(
  94. ; CHECK: OpCapability Shader
  95. ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
  96. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_ballot"
  97. ; CHECK: OpDecorate [[var:%\w+]] BuiltIn SubgroupLtMask
  98. ; CHECK: [[var]] = OpVariable %_ptr_Input_v4uint Input
  99. ; CHECK: OpFunction
  100. ; CHECK-NEXT: OpLabel
  101. ; CHECK-NEXT: [[ld:%\w+]] = OpLoad %v4uint [[var]]
  102. ; CHECK-NEXT: [[shuffle:%\w+]] = OpVectorShuffle %v2uint [[ld]] [[ld]] 0 1
  103. ; CHECK-NEXT: [[bitcast:%\w+]] = OpBitcast %ulong [[shuffle]]
  104. ; CHECK-NEXT: [[and:%\w+]] = OpBitwiseAnd %ulong [[bitcast]] %ulong_0
  105. ; CHECK-NEXT: [[result:%\w+]] = OpBitCount %uint [[and]]
  106. OpCapability Shader
  107. OpCapability Int64
  108. OpExtension "SPV_AMD_shader_ballot"
  109. %1 = OpExtInstImport "SPV_AMD_shader_ballot"
  110. OpMemoryModel Logical GLSL450
  111. OpEntryPoint Fragment %2 "func"
  112. OpExecutionMode %2 OriginUpperLeft
  113. %void = OpTypeVoid
  114. %4 = OpTypeFunction %void
  115. %uint = OpTypeInt 32 0
  116. %ulong = OpTypeInt 64 0
  117. %ulong_0 = OpConstant %ulong 0
  118. %2 = OpFunction %void None %4
  119. %8 = OpLabel
  120. %9 = OpExtInst %uint %1 MbcntAMD %ulong_0
  121. OpReturn
  122. OpFunctionEnd
  123. )";
  124. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  125. }
  126. TEST_F(AmdExtToKhrTest, ReplaceSwizzleInvocationsAMD) {
  127. const std::string text = R"(
  128. ; CHECK: OpCapability Shader
  129. ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
  130. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_ballot"
  131. ; CHECK: OpDecorate [[var:%\w+]] BuiltIn SubgroupLocalInvocationId
  132. ; CHECK: [[subgroup:%\w+]] = OpConstant %uint 3
  133. ; CHECK: [[offset:%\w+]] = OpConstantComposite %v4uint
  134. ; CHECK: [[var]] = OpVariable %_ptr_Input_uint Input
  135. ; CHECK: [[uint_max:%\w+]] = OpConstant %uint 4294967295
  136. ; CHECK: [[ballot_value:%\w+]] = OpConstantComposite %v4uint [[uint_max]] [[uint_max]] [[uint_max]] [[uint_max]]
  137. ; CHECK: [[null:%\w+]] = OpConstantNull [[type:%\w+]]
  138. ; CHECK: OpFunction
  139. ; CHECK-NEXT: OpLabel
  140. ; CHECK-NEXT: [[data:%\w+]] = OpUndef [[type]]
  141. ; CHECK-NEXT: [[id:%\w+]] = OpLoad %uint [[var]]
  142. ; CHECK-NEXT: [[quad_idx:%\w+]] = OpBitwiseAnd %uint [[id]] %uint_3
  143. ; CHECK-NEXT: [[quad_ldr:%\w+]] = OpBitwiseXor %uint [[id]] [[quad_idx]]
  144. ; CHECK-NEXT: [[my_offset:%\w+]] = OpVectorExtractDynamic %uint [[offset]] [[quad_idx]]
  145. ; CHECK-NEXT: [[target_inv:%\w+]] = OpIAdd %uint [[quad_ldr]] [[my_offset]]
  146. ; CHECK-NEXT: [[is_active:%\w+]] = OpGroupNonUniformBallotBitExtract %bool [[subgroup]] [[ballot_value]] [[target_inv]]
  147. ; CHECK-NEXT: [[shuffle:%\w+]] = OpGroupNonUniformShuffle [[type]] [[subgroup]] [[data]] [[target_inv]]
  148. ; CHECK-NEXT: [[result:%\w+]] = OpSelect [[type]] [[is_active]] [[shuffle]] [[null]]
  149. OpCapability Shader
  150. OpExtension "SPV_AMD_shader_ballot"
  151. %ext = OpExtInstImport "SPV_AMD_shader_ballot"
  152. OpMemoryModel Logical GLSL450
  153. OpEntryPoint Fragment %1 "func"
  154. OpExecutionMode %1 OriginUpperLeft
  155. %void = OpTypeVoid
  156. %3 = OpTypeFunction %void
  157. %uint = OpTypeInt 32 0
  158. %uint_x = OpConstant %uint 1
  159. %uint_y = OpConstant %uint 2
  160. %uint_z = OpConstant %uint 3
  161. %uint_w = OpConstant %uint 0
  162. %v4uint = OpTypeVector %uint 4
  163. %offset = OpConstantComposite %v4uint %uint_x %uint_y %uint_z %uint_x
  164. %1 = OpFunction %void None %3
  165. %6 = OpLabel
  166. %data = OpUndef %uint
  167. %9 = OpExtInst %uint %ext SwizzleInvocationsAMD %data %offset
  168. OpReturn
  169. OpFunctionEnd
  170. )";
  171. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  172. }
  173. TEST_F(AmdExtToKhrTest, ReplaceSwizzleInvocationsMaskedAMD) {
  174. const std::string text = R"(
  175. ; CHECK: OpCapability Shader
  176. ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
  177. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_ballot"
  178. ; CHECK: OpDecorate [[var:%\w+]] BuiltIn SubgroupLocalInvocationId
  179. ; CHECK: [[x:%\w+]] = OpConstant %uint 19
  180. ; CHECK: [[y:%\w+]] = OpConstant %uint 12
  181. ; CHECK: [[z:%\w+]] = OpConstant %uint 16
  182. ; CHECK: [[var]] = OpVariable %_ptr_Input_uint Input
  183. ; CHECK: [[mask_extend:%\w+]] = OpConstant %uint 4294967264
  184. ; CHECK: [[uint_max:%\w+]] = OpConstant %uint 4294967295
  185. ; CHECK: [[subgroup:%\w+]] = OpConstant %uint 3
  186. ; CHECK: [[ballot_value:%\w+]] = OpConstantComposite %v4uint [[uint_max]] [[uint_max]] [[uint_max]] [[uint_max]]
  187. ; CHECK: [[null:%\w+]] = OpConstantNull [[type:%\w+]]
  188. ; CHECK: OpFunction
  189. ; CHECK-NEXT: OpLabel
  190. ; CHECK-NEXT: [[data:%\w+]] = OpUndef [[type]]
  191. ; CHECK-NEXT: [[id:%\w+]] = OpLoad %uint [[var]]
  192. ; CHECK-NEXT: [[and_mask:%\w+]] = OpBitwiseOr %uint [[x]] [[mask_extend]]
  193. ; CHECK-NEXT: [[and:%\w+]] = OpBitwiseAnd %uint [[id]] [[and_mask]]
  194. ; CHECK-NEXT: [[or:%\w+]] = OpBitwiseOr %uint [[and]] [[y]]
  195. ; CHECK-NEXT: [[target_inv:%\w+]] = OpBitwiseXor %uint [[or]] [[z]]
  196. ; CHECK-NEXT: [[is_active:%\w+]] = OpGroupNonUniformBallotBitExtract %bool [[subgroup]] [[ballot_value]] [[target_inv]]
  197. ; CHECK-NEXT: [[shuffle:%\w+]] = OpGroupNonUniformShuffle [[type]] [[subgroup]] [[data]] [[target_inv]]
  198. ; CHECK-NEXT: [[result:%\w+]] = OpSelect [[type]] [[is_active]] [[shuffle]] [[null]]
  199. OpCapability Shader
  200. OpExtension "SPV_AMD_shader_ballot"
  201. %ext = OpExtInstImport "SPV_AMD_shader_ballot"
  202. OpMemoryModel Logical GLSL450
  203. OpEntryPoint Fragment %1 "func"
  204. OpExecutionMode %1 OriginUpperLeft
  205. %void = OpTypeVoid
  206. %3 = OpTypeFunction %void
  207. %uint = OpTypeInt 32 0
  208. %uint_x = OpConstant %uint 19
  209. %uint_y = OpConstant %uint 12
  210. %uint_z = OpConstant %uint 16
  211. %v3uint = OpTypeVector %uint 3
  212. %mask = OpConstantComposite %v3uint %uint_x %uint_y %uint_z
  213. %1 = OpFunction %void None %3
  214. %6 = OpLabel
  215. %data = OpUndef %uint
  216. %9 = OpExtInst %uint %ext SwizzleInvocationsMaskedAMD %data %mask
  217. OpReturn
  218. OpFunctionEnd
  219. )";
  220. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  221. }
  222. TEST_F(AmdExtToKhrTest, ReplaceWriteInvocationAMD) {
  223. const std::string text = R"(
  224. ; CHECK: OpCapability Shader
  225. ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
  226. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_ballot"
  227. ; CHECK: OpDecorate [[var:%\w+]] BuiltIn SubgroupLocalInvocationId
  228. ; CHECK: [[var]] = OpVariable %_ptr_Input_uint Input
  229. ; CHECK: OpFunction
  230. ; CHECK-NEXT: OpLabel
  231. ; CHECK-NEXT: [[input_val:%\w+]] = OpUndef %uint
  232. ; CHECK-NEXT: [[write_val:%\w+]] = OpUndef %uint
  233. ; CHECK-NEXT: [[ld:%\w+]] = OpLoad %uint [[var]]
  234. ; CHECK-NEXT: [[cmp:%\w+]] = OpIEqual %bool [[ld]] %uint_3
  235. ; CHECK-NEXT: [[result:%\w+]] = OpSelect %uint [[cmp]] [[write_val]] [[input_val]]
  236. OpCapability Shader
  237. OpExtension "SPV_AMD_shader_ballot"
  238. %ext = OpExtInstImport "SPV_AMD_shader_ballot"
  239. OpMemoryModel Logical GLSL450
  240. OpEntryPoint Fragment %1 "func"
  241. OpExecutionMode %1 OriginUpperLeft
  242. %void = OpTypeVoid
  243. %3 = OpTypeFunction %void
  244. %uint = OpTypeInt 32 0
  245. %uint_3 = OpConstant %uint 3
  246. %1 = OpFunction %void None %3
  247. %6 = OpLabel
  248. %7 = OpUndef %uint
  249. %8 = OpUndef %uint
  250. %9 = OpExtInst %uint %ext WriteInvocationAMD %7 %8 %uint_3
  251. OpReturn
  252. OpFunctionEnd
  253. )";
  254. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  255. }
  256. TEST_F(AmdExtToKhrTest, ReplaceFMin3AMD) {
  257. const std::string text = R"(
  258. ; CHECK: OpCapability Shader
  259. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  260. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  261. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  262. ; CHECK: [[type:%\w+]] = OpTypeFloat 32
  263. ; CHECK: OpFunction
  264. ; CHECK-NEXT: OpLabel
  265. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  266. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  267. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  268. ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] FMin [[x]] [[y]]
  269. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] FMin [[temp]] [[z]]
  270. OpCapability Shader
  271. OpExtension "SPV_AMD_shader_trinary_minmax"
  272. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  273. OpMemoryModel Logical GLSL450
  274. OpEntryPoint Fragment %1 "func"
  275. OpExecutionMode %1 OriginUpperLeft
  276. %void = OpTypeVoid
  277. %3 = OpTypeFunction %void
  278. %uint = OpTypeInt 32 0
  279. %float = OpTypeFloat 32
  280. %uint_3 = OpConstant %uint 3
  281. %1 = OpFunction %void None %3
  282. %6 = OpLabel
  283. %7 = OpUndef %float
  284. %8 = OpUndef %float
  285. %9 = OpUndef %float
  286. %10 = OpExtInst %float %ext FMin3AMD %7 %8 %9
  287. OpReturn
  288. OpFunctionEnd
  289. )";
  290. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  291. }
  292. TEST_F(AmdExtToKhrTest, ReplaceSMin3AMD) {
  293. const std::string text = R"(
  294. ; CHECK: OpCapability Shader
  295. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  296. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  297. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  298. ; CHECK: [[type:%\w+]] = OpTypeInt 32 1
  299. ; CHECK: OpFunction
  300. ; CHECK-NEXT: OpLabel
  301. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  302. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  303. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  304. ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] SMin [[x]] [[y]]
  305. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] SMin [[temp]] [[z]]
  306. OpCapability Shader
  307. OpExtension "SPV_AMD_shader_trinary_minmax"
  308. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  309. OpMemoryModel Logical GLSL450
  310. OpEntryPoint Fragment %1 "func"
  311. OpExecutionMode %1 OriginUpperLeft
  312. %void = OpTypeVoid
  313. %3 = OpTypeFunction %void
  314. %uint = OpTypeInt 32 0
  315. %int = OpTypeInt 32 1
  316. %float = OpTypeFloat 32
  317. %uint_3 = OpConstant %uint 3
  318. %1 = OpFunction %void None %3
  319. %6 = OpLabel
  320. %7 = OpUndef %int
  321. %8 = OpUndef %int
  322. %9 = OpUndef %int
  323. %10 = OpExtInst %int %ext SMin3AMD %7 %8 %9
  324. OpReturn
  325. OpFunctionEnd
  326. )";
  327. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  328. }
  329. TEST_F(AmdExtToKhrTest, ReplaceUMin3AMD) {
  330. const std::string text = R"(
  331. ; CHECK: OpCapability Shader
  332. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  333. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  334. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  335. ; CHECK: [[type:%\w+]] = OpTypeInt 32 0
  336. ; CHECK: OpFunction
  337. ; CHECK-NEXT: OpLabel
  338. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  339. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  340. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  341. ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] UMin [[x]] [[y]]
  342. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UMin [[temp]] [[z]]
  343. OpCapability Shader
  344. OpExtension "SPV_AMD_shader_trinary_minmax"
  345. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  346. OpMemoryModel Logical GLSL450
  347. OpEntryPoint Fragment %1 "func"
  348. OpExecutionMode %1 OriginUpperLeft
  349. %void = OpTypeVoid
  350. %3 = OpTypeFunction %void
  351. %uint = OpTypeInt 32 0
  352. %int = OpTypeInt 32 1
  353. %float = OpTypeFloat 32
  354. %uint_3 = OpConstant %uint 3
  355. %1 = OpFunction %void None %3
  356. %6 = OpLabel
  357. %7 = OpUndef %uint
  358. %8 = OpUndef %uint
  359. %9 = OpUndef %uint
  360. %10 = OpExtInst %uint %ext UMin3AMD %7 %8 %9
  361. OpReturn
  362. OpFunctionEnd
  363. )";
  364. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  365. }
  366. TEST_F(AmdExtToKhrTest, ReplaceFMax3AMD) {
  367. const std::string text = R"(
  368. ; CHECK: OpCapability Shader
  369. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  370. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  371. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  372. ; CHECK: [[type:%\w+]] = OpTypeFloat 32
  373. ; CHECK: OpFunction
  374. ; CHECK-NEXT: OpLabel
  375. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  376. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  377. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  378. ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] FMax [[x]] [[y]]
  379. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] FMax [[temp]] [[z]]
  380. OpCapability Shader
  381. OpExtension "SPV_AMD_shader_trinary_minmax"
  382. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  383. OpMemoryModel Logical GLSL450
  384. OpEntryPoint Fragment %1 "func"
  385. OpExecutionMode %1 OriginUpperLeft
  386. %void = OpTypeVoid
  387. %3 = OpTypeFunction %void
  388. %uint = OpTypeInt 32 0
  389. %float = OpTypeFloat 32
  390. %uint_3 = OpConstant %uint 3
  391. %1 = OpFunction %void None %3
  392. %6 = OpLabel
  393. %7 = OpUndef %float
  394. %8 = OpUndef %float
  395. %9 = OpUndef %float
  396. %10 = OpExtInst %float %ext FMax3AMD %7 %8 %9
  397. OpReturn
  398. OpFunctionEnd
  399. )";
  400. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  401. }
  402. TEST_F(AmdExtToKhrTest, ReplaceSMax3AMD) {
  403. const std::string text = R"(
  404. ; CHECK: OpCapability Shader
  405. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  406. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  407. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  408. ; CHECK: [[type:%\w+]] = OpTypeInt 32 1
  409. ; CHECK: OpFunction
  410. ; CHECK-NEXT: OpLabel
  411. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  412. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  413. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  414. ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] SMax [[x]] [[y]]
  415. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] SMax [[temp]] [[z]]
  416. OpCapability Shader
  417. OpExtension "SPV_AMD_shader_trinary_minmax"
  418. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  419. OpMemoryModel Logical GLSL450
  420. OpEntryPoint Fragment %1 "func"
  421. OpExecutionMode %1 OriginUpperLeft
  422. %void = OpTypeVoid
  423. %3 = OpTypeFunction %void
  424. %uint = OpTypeInt 32 0
  425. %int = OpTypeInt 32 1
  426. %float = OpTypeFloat 32
  427. %uint_3 = OpConstant %uint 3
  428. %1 = OpFunction %void None %3
  429. %6 = OpLabel
  430. %7 = OpUndef %int
  431. %8 = OpUndef %int
  432. %9 = OpUndef %int
  433. %10 = OpExtInst %int %ext SMax3AMD %7 %8 %9
  434. OpReturn
  435. OpFunctionEnd
  436. )";
  437. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  438. }
  439. TEST_F(AmdExtToKhrTest, ReplaceUMax3AMD) {
  440. const std::string text = R"(
  441. ; CHECK: OpCapability Shader
  442. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  443. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  444. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  445. ; CHECK: [[type:%\w+]] = OpTypeInt 32 0
  446. ; CHECK: OpFunction
  447. ; CHECK-NEXT: OpLabel
  448. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  449. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  450. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  451. ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[x]] [[y]]
  452. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[temp]] [[z]]
  453. OpCapability Shader
  454. OpExtension "SPV_AMD_shader_trinary_minmax"
  455. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  456. OpMemoryModel Logical GLSL450
  457. OpEntryPoint Fragment %1 "func"
  458. OpExecutionMode %1 OriginUpperLeft
  459. %void = OpTypeVoid
  460. %3 = OpTypeFunction %void
  461. %uint = OpTypeInt 32 0
  462. %int = OpTypeInt 32 1
  463. %float = OpTypeFloat 32
  464. %uint_3 = OpConstant %uint 3
  465. %1 = OpFunction %void None %3
  466. %6 = OpLabel
  467. %7 = OpUndef %uint
  468. %8 = OpUndef %uint
  469. %9 = OpUndef %uint
  470. %10 = OpExtInst %uint %ext UMax3AMD %7 %8 %9
  471. OpReturn
  472. OpFunctionEnd
  473. )";
  474. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  475. }
  476. TEST_F(AmdExtToKhrTest, ReplaceVecUMax3AMD) {
  477. const std::string text = R"(
  478. ; CHECK: OpCapability Shader
  479. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  480. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  481. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  482. ; CHECK: [[type:%\w+]] = OpTypeVector
  483. ; CHECK: OpFunction
  484. ; CHECK-NEXT: OpLabel
  485. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  486. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  487. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  488. ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[x]] [[y]]
  489. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[temp]] [[z]]
  490. OpCapability Shader
  491. OpExtension "SPV_AMD_shader_trinary_minmax"
  492. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  493. OpMemoryModel Logical GLSL450
  494. OpEntryPoint Fragment %1 "func"
  495. OpExecutionMode %1 OriginUpperLeft
  496. %void = OpTypeVoid
  497. %3 = OpTypeFunction %void
  498. %uint = OpTypeInt 32 0
  499. %vec = OpTypeVector %uint 4
  500. %int = OpTypeInt 32 1
  501. %float = OpTypeFloat 32
  502. %uint_3 = OpConstant %uint 3
  503. %1 = OpFunction %void None %3
  504. %6 = OpLabel
  505. %7 = OpUndef %vec
  506. %8 = OpUndef %vec
  507. %9 = OpUndef %vec
  508. %10 = OpExtInst %vec %ext UMax3AMD %7 %8 %9
  509. OpReturn
  510. OpFunctionEnd
  511. )";
  512. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  513. }
  514. TEST_F(AmdExtToKhrTest, ReplaceFMid3AMD) {
  515. const std::string text = R"(
  516. ; CHECK: OpCapability Shader
  517. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  518. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  519. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  520. ; CHECK: [[type:%\w+]] = OpTypeFloat 32
  521. ; CHECK: OpFunction
  522. ; CHECK-NEXT: OpLabel
  523. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  524. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  525. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  526. ; CHECK-NEXT: [[min:%\w+]] = OpExtInst [[type]] [[ext]] FMin [[y]] [[z]]
  527. ; CHECK-NEXT: [[max:%\w+]] = OpExtInst [[type]] [[ext]] FMax [[y]] [[z]]
  528. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] FClamp [[x]] [[min]] [[max]]
  529. OpCapability Shader
  530. OpExtension "SPV_AMD_shader_trinary_minmax"
  531. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  532. OpMemoryModel Logical GLSL450
  533. OpEntryPoint Fragment %1 "func"
  534. OpExecutionMode %1 OriginUpperLeft
  535. %void = OpTypeVoid
  536. %3 = OpTypeFunction %void
  537. %uint = OpTypeInt 32 0
  538. %float = OpTypeFloat 32
  539. %uint_3 = OpConstant %uint 3
  540. %1 = OpFunction %void None %3
  541. %6 = OpLabel
  542. %7 = OpUndef %float
  543. %8 = OpUndef %float
  544. %9 = OpUndef %float
  545. %10 = OpExtInst %float %ext FMid3AMD %7 %8 %9
  546. OpReturn
  547. OpFunctionEnd
  548. )";
  549. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  550. }
  551. TEST_F(AmdExtToKhrTest, ReplaceSMid3AMD) {
  552. const std::string text = R"(
  553. ; CHECK: OpCapability Shader
  554. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  555. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  556. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  557. ; CHECK: [[type:%\w+]] = OpTypeInt 32 1
  558. ; CHECK: OpFunction
  559. ; CHECK-NEXT: OpLabel
  560. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  561. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  562. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  563. ; CHECK-NEXT: [[min:%\w+]] = OpExtInst [[type]] [[ext]] SMin [[y]] [[z]]
  564. ; CHECK-NEXT: [[max:%\w+]] = OpExtInst [[type]] [[ext]] SMax [[y]] [[z]]
  565. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] SClamp [[x]] [[min]] [[max]]
  566. OpCapability Shader
  567. OpExtension "SPV_AMD_shader_trinary_minmax"
  568. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  569. OpMemoryModel Logical GLSL450
  570. OpEntryPoint Fragment %1 "func"
  571. OpExecutionMode %1 OriginUpperLeft
  572. %void = OpTypeVoid
  573. %3 = OpTypeFunction %void
  574. %uint = OpTypeInt 32 0
  575. %int = OpTypeInt 32 1
  576. %float = OpTypeFloat 32
  577. %uint_3 = OpConstant %uint 3
  578. %1 = OpFunction %void None %3
  579. %6 = OpLabel
  580. %7 = OpUndef %int
  581. %8 = OpUndef %int
  582. %9 = OpUndef %int
  583. %10 = OpExtInst %int %ext SMid3AMD %7 %8 %9
  584. OpReturn
  585. OpFunctionEnd
  586. )";
  587. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  588. }
  589. TEST_F(AmdExtToKhrTest, ReplaceUMid3AMD) {
  590. const std::string text = R"(
  591. ; CHECK: OpCapability Shader
  592. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  593. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  594. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  595. ; CHECK: [[type:%\w+]] = OpTypeInt 32 0
  596. ; CHECK: OpFunction
  597. ; CHECK-NEXT: OpLabel
  598. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  599. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  600. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  601. ; CHECK-NEXT: [[min:%\w+]] = OpExtInst [[type]] [[ext]] UMin [[y]] [[z]]
  602. ; CHECK-NEXT: [[max:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[y]] [[z]]
  603. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UClamp [[x]] [[min]] [[max]]
  604. OpCapability Shader
  605. OpExtension "SPV_AMD_shader_trinary_minmax"
  606. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  607. OpMemoryModel Logical GLSL450
  608. OpEntryPoint Fragment %1 "func"
  609. OpExecutionMode %1 OriginUpperLeft
  610. %void = OpTypeVoid
  611. %3 = OpTypeFunction %void
  612. %uint = OpTypeInt 32 0
  613. %int = OpTypeInt 32 1
  614. %float = OpTypeFloat 32
  615. %uint_3 = OpConstant %uint 3
  616. %1 = OpFunction %void None %3
  617. %6 = OpLabel
  618. %7 = OpUndef %uint
  619. %8 = OpUndef %uint
  620. %9 = OpUndef %uint
  621. %10 = OpExtInst %uint %ext UMid3AMD %7 %8 %9
  622. OpReturn
  623. OpFunctionEnd
  624. )";
  625. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  626. }
  627. TEST_F(AmdExtToKhrTest, ReplaceVecUMid3AMD) {
  628. const std::string text = R"(
  629. ; CHECK: OpCapability Shader
  630. ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
  631. ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  632. ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
  633. ; CHECK: [[type:%\w+]] = OpTypeVector
  634. ; CHECK: OpFunction
  635. ; CHECK-NEXT: OpLabel
  636. ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
  637. ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
  638. ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
  639. ; CHECK-NEXT: [[min:%\w+]] = OpExtInst [[type]] [[ext]] UMin [[y]] [[z]]
  640. ; CHECK-NEXT: [[max:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[y]] [[z]]
  641. ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UClamp [[x]] [[min]] [[max]]
  642. OpCapability Shader
  643. OpExtension "SPV_AMD_shader_trinary_minmax"
  644. %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
  645. OpMemoryModel Logical GLSL450
  646. OpEntryPoint Fragment %1 "func"
  647. OpExecutionMode %1 OriginUpperLeft
  648. %void = OpTypeVoid
  649. %3 = OpTypeFunction %void
  650. %uint = OpTypeInt 32 0
  651. %vec = OpTypeVector %uint 3
  652. %int = OpTypeInt 32 1
  653. %float = OpTypeFloat 32
  654. %uint_3 = OpConstant %uint 3
  655. %1 = OpFunction %void None %3
  656. %6 = OpLabel
  657. %7 = OpUndef %vec
  658. %8 = OpUndef %vec
  659. %9 = OpUndef %vec
  660. %10 = OpExtInst %vec %ext UMid3AMD %7 %8 %9
  661. OpReturn
  662. OpFunctionEnd
  663. )";
  664. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  665. }
  666. TEST_F(AmdExtToKhrTest, ReplaceCubeFaceCoordAMD) {
  667. // Sorry for the Check test. The code sequence is so long, I do not think
  668. // that a match test would be anymore legible. This tests the replacement of
  669. // the CubeFaceCoordAMD instruction.
  670. const std::string before = R"(
  671. OpCapability Shader
  672. OpExtension "SPV_KHR_storage_buffer_storage_class"
  673. OpExtension "SPV_AMD_gcn_shader"
  674. %1 = OpExtInstImport "SPV_AMD_gcn_shader"
  675. OpMemoryModel Logical GLSL450
  676. OpEntryPoint GLCompute %2 "main"
  677. OpExecutionMode %2 LocalSize 1 1 1
  678. %void = OpTypeVoid
  679. %4 = OpTypeFunction %void
  680. %float = OpTypeFloat 32
  681. %v2float = OpTypeVector %float 2
  682. %v3float = OpTypeVector %float 3
  683. %2 = OpFunction %void None %4
  684. %8 = OpLabel
  685. %9 = OpUndef %v3float
  686. %10 = OpExtInst %v2float %1 CubeFaceCoordAMD %9
  687. OpReturn
  688. OpFunctionEnd
  689. )";
  690. const std::string after = R"(OpCapability Shader
  691. OpExtension "SPV_KHR_storage_buffer_storage_class"
  692. %12 = OpExtInstImport "GLSL.std.450"
  693. OpMemoryModel Logical GLSL450
  694. OpEntryPoint GLCompute %2 "main"
  695. OpExecutionMode %2 LocalSize 1 1 1
  696. %void = OpTypeVoid
  697. %4 = OpTypeFunction %void
  698. %float = OpTypeFloat 32
  699. %v2float = OpTypeVector %float 2
  700. %v3float = OpTypeVector %float 3
  701. %bool = OpTypeBool
  702. %float_0 = OpConstant %float 0
  703. %float_2 = OpConstant %float 2
  704. %float_0_5 = OpConstant %float 0.5
  705. %16 = OpConstantComposite %v2float %float_0_5 %float_0_5
  706. %2 = OpFunction %void None %4
  707. %8 = OpLabel
  708. %9 = OpUndef %v3float
  709. %17 = OpCompositeExtract %float %9 0
  710. %18 = OpCompositeExtract %float %9 1
  711. %19 = OpCompositeExtract %float %9 2
  712. %20 = OpFNegate %float %17
  713. %21 = OpFNegate %float %18
  714. %22 = OpFNegate %float %19
  715. %23 = OpExtInst %float %12 FAbs %17
  716. %24 = OpExtInst %float %12 FAbs %18
  717. %25 = OpExtInst %float %12 FAbs %19
  718. %26 = OpFOrdLessThan %bool %19 %float_0
  719. %27 = OpFOrdLessThan %bool %18 %float_0
  720. %28 = OpFOrdLessThan %bool %17 %float_0
  721. %29 = OpExtInst %float %12 FMax %23 %24
  722. %30 = OpExtInst %float %12 FMax %25 %29
  723. %31 = OpFMul %float %float_2 %30
  724. %32 = OpFOrdGreaterThanEqual %bool %25 %29
  725. %33 = OpLogicalNot %bool %32
  726. %34 = OpFOrdGreaterThanEqual %bool %24 %23
  727. %35 = OpLogicalAnd %bool %33 %34
  728. %36 = OpSelect %float %26 %20 %17
  729. %37 = OpSelect %float %28 %19 %22
  730. %38 = OpSelect %float %35 %17 %37
  731. %39 = OpSelect %float %32 %36 %38
  732. %40 = OpSelect %float %27 %22 %19
  733. %41 = OpSelect %float %35 %40 %21
  734. %42 = OpCompositeConstruct %v2float %39 %41
  735. %43 = OpCompositeConstruct %v2float %31 %31
  736. %44 = OpFDiv %v2float %42 %43
  737. %10 = OpFAdd %v2float %44 %16
  738. OpReturn
  739. OpFunctionEnd
  740. )";
  741. SinglePassRunAndCheck<AmdExtensionToKhrPass>(before, after, true);
  742. }
  743. TEST_F(AmdExtToKhrTest, ReplaceCubeFaceIndexAMD) {
  744. // Sorry for the Check test. The code sequence is so long, I do not think
  745. // that a match test would be anymore legible. This tests the replacement of
  746. // the CubeFaceIndexAMD instruction.
  747. const std::string before = R"(OpCapability Shader
  748. OpExtension "SPV_KHR_storage_buffer_storage_class"
  749. OpExtension "SPV_AMD_gcn_shader"
  750. %1 = OpExtInstImport "SPV_AMD_gcn_shader"
  751. OpMemoryModel Logical GLSL450
  752. OpEntryPoint GLCompute %2 "main"
  753. OpExecutionMode %2 LocalSize 1 1 1
  754. %void = OpTypeVoid
  755. %4 = OpTypeFunction %void
  756. %float = OpTypeFloat 32
  757. %v3float = OpTypeVector %float 3
  758. %2 = OpFunction %void None %4
  759. %7 = OpLabel
  760. %8 = OpUndef %v3float
  761. %9 = OpExtInst %float %1 CubeFaceIndexAMD %8
  762. OpReturn
  763. OpFunctionEnd
  764. )";
  765. const std::string after = R"(OpCapability Shader
  766. OpExtension "SPV_KHR_storage_buffer_storage_class"
  767. %11 = OpExtInstImport "GLSL.std.450"
  768. OpMemoryModel Logical GLSL450
  769. OpEntryPoint GLCompute %2 "main"
  770. OpExecutionMode %2 LocalSize 1 1 1
  771. %void = OpTypeVoid
  772. %4 = OpTypeFunction %void
  773. %float = OpTypeFloat 32
  774. %v3float = OpTypeVector %float 3
  775. %bool = OpTypeBool
  776. %float_0 = OpConstant %float 0
  777. %float_1 = OpConstant %float 1
  778. %float_2 = OpConstant %float 2
  779. %float_3 = OpConstant %float 3
  780. %float_4 = OpConstant %float 4
  781. %float_5 = OpConstant %float 5
  782. %2 = OpFunction %void None %4
  783. %7 = OpLabel
  784. %8 = OpUndef %v3float
  785. %18 = OpCompositeExtract %float %8 0
  786. %19 = OpCompositeExtract %float %8 1
  787. %20 = OpCompositeExtract %float %8 2
  788. %21 = OpExtInst %float %11 FAbs %18
  789. %22 = OpExtInst %float %11 FAbs %19
  790. %23 = OpExtInst %float %11 FAbs %20
  791. %24 = OpFOrdLessThan %bool %20 %float_0
  792. %25 = OpFOrdLessThan %bool %19 %float_0
  793. %26 = OpFOrdLessThan %bool %18 %float_0
  794. %27 = OpExtInst %float %11 FMax %21 %22
  795. %28 = OpFOrdGreaterThanEqual %bool %23 %27
  796. %29 = OpFOrdGreaterThanEqual %bool %22 %21
  797. %30 = OpSelect %float %24 %float_5 %float_4
  798. %31 = OpSelect %float %25 %float_3 %float_2
  799. %32 = OpSelect %float %26 %float_1 %float_0
  800. %33 = OpSelect %float %29 %31 %32
  801. %9 = OpSelect %float %28 %30 %33
  802. OpReturn
  803. OpFunctionEnd
  804. )";
  805. SinglePassRunAndCheck<AmdExtensionToKhrPass>(before, after, true);
  806. }
  807. TEST_F(AmdExtToKhrTest, SetVersion) {
  808. const std::string text = R"(
  809. OpCapability Shader
  810. OpCapability Int64
  811. OpExtension "SPV_AMD_shader_ballot"
  812. %1 = OpExtInstImport "SPV_AMD_shader_ballot"
  813. OpMemoryModel Logical GLSL450
  814. OpEntryPoint Fragment %2 "func"
  815. OpExecutionMode %2 OriginUpperLeft
  816. %void = OpTypeVoid
  817. %4 = OpTypeFunction %void
  818. %uint = OpTypeInt 32 0
  819. %ulong = OpTypeInt 64 0
  820. %ulong_0 = OpConstant %ulong 0
  821. %2 = OpFunction %void None %4
  822. %8 = OpLabel
  823. %9 = OpExtInst %uint %1 MbcntAMD %ulong_0
  824. OpReturn
  825. OpFunctionEnd
  826. )";
  827. // Set the version to 1.1 and make sure it is upgraded to 1.3.
  828. SetTargetEnv(SPV_ENV_UNIVERSAL_1_1);
  829. SetDisassembleOptions(0);
  830. auto result = SinglePassRunAndDisassemble<AmdExtensionToKhrPass>(
  831. text, /* skip_nop = */ true, /* skip_validation = */ false);
  832. EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
  833. const std::string& output = std::get<0>(result);
  834. EXPECT_THAT(output, HasSubstr("Version: 1.3"));
  835. }
  836. TEST_F(AmdExtToKhrTest, SetVersion1) {
  837. const std::string text = R"(
  838. OpCapability Shader
  839. OpCapability Int64
  840. OpExtension "SPV_AMD_shader_ballot"
  841. %1 = OpExtInstImport "SPV_AMD_shader_ballot"
  842. OpMemoryModel Logical GLSL450
  843. OpEntryPoint Fragment %2 "func"
  844. OpExecutionMode %2 OriginUpperLeft
  845. %void = OpTypeVoid
  846. %4 = OpTypeFunction %void
  847. %uint = OpTypeInt 32 0
  848. %ulong = OpTypeInt 64 0
  849. %ulong_0 = OpConstant %ulong 0
  850. %2 = OpFunction %void None %4
  851. %8 = OpLabel
  852. %9 = OpExtInst %uint %1 MbcntAMD %ulong_0
  853. OpReturn
  854. OpFunctionEnd
  855. )";
  856. // Set the version to 1.4 and make sure it is stays the same.
  857. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  858. SetDisassembleOptions(0);
  859. auto result = SinglePassRunAndDisassemble<AmdExtensionToKhrPass>(
  860. text, /* skip_nop = */ true, /* skip_validation = */ false);
  861. EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
  862. const std::string& output = std::get<0>(result);
  863. EXPECT_THAT(output, HasSubstr("Version: 1.4"));
  864. }
  865. TEST_F(AmdExtToKhrTest, TimeAMD) {
  866. const std::string text = R"(
  867. OpCapability Shader
  868. OpCapability Int64
  869. OpExtension "SPV_AMD_gcn_shader"
  870. ; CHECK-NOT: OpExtension "SPV_AMD_gcn_shader"
  871. ; CHECK: OpExtension "SPV_KHR_shader_clock"
  872. %1 = OpExtInstImport "GLSL.std.450"
  873. %2 = OpExtInstImport "SPV_AMD_gcn_shader"
  874. ; CHECK-NOT: OpExtInstImport "SPV_AMD_gcn_shader"
  875. OpMemoryModel Logical GLSL450
  876. OpEntryPoint Fragment %main "main"
  877. OpExecutionMode %main OriginUpperLeft
  878. OpSource GLSL 450
  879. OpSourceExtension "GL_AMD_gcn_shader"
  880. OpSourceExtension "GL_ARB_gpu_shader_int64"
  881. OpName %main "main"
  882. OpName %time "time"
  883. %void = OpTypeVoid
  884. %6 = OpTypeFunction %void
  885. %ulong = OpTypeInt 64 0
  886. %_ptr_Function_ulong = OpTypePointer Function %ulong
  887. %main = OpFunction %void None %6
  888. %9 = OpLabel
  889. %time = OpVariable %_ptr_Function_ulong Function
  890. ; CHECK: [[uint:%\w+]] = OpTypeInt 32 0
  891. ; CHECK: [[uint_3:%\w+]] = OpConstant [[uint]] 3
  892. %10 = OpExtInst %ulong %2 TimeAMD
  893. ; CHECK: %10 = OpReadClockKHR %ulong [[uint_3]]
  894. OpStore %time %10
  895. OpReturn
  896. OpFunctionEnd
  897. )";
  898. SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
  899. }
  900. } // namespace
  901. } // namespace opt
  902. } // namespace spvtools