amd_ext_to_khr.cpp 35 KB

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