hoist_access_chains.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright (c) 2023 The Khronos Group Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <string>
  15. #include "gmock/gmock.h"
  16. #include "source/opt/licm_pass.h"
  17. #include "test/opt/pass_fixture.h"
  18. namespace spvtools {
  19. namespace opt {
  20. namespace {
  21. using PassClassTest = PassTest<::testing::Test>;
  22. /*
  23. Tests for the LICM pass to check it handles access chains correctly
  24. Generated from the following GLSL fragment shader
  25. --eliminate-local-multi-store has also been run on the spv binary
  26. #version 460
  27. void main() {
  28. for (uint i = 0; i < 123u; ++i) {
  29. vec2 do_not_hoist_store = vec2(0.0f);
  30. float do_not_hoist_access_chain_load = do_not_hoist_store.x;
  31. }
  32. }
  33. */
  34. TEST_F(PassClassTest, HoistAccessChains) {
  35. const std::string before_hoist = R"(OpCapability Shader
  36. %1 = OpExtInstImport "GLSL.std.450"
  37. OpMemoryModel Logical GLSL450
  38. OpEntryPoint Fragment %main "main"
  39. OpExecutionMode %main OriginUpperLeft
  40. OpSource GLSL 460
  41. OpName %main "main"
  42. OpName %i "i"
  43. OpName %do_not_hoist_store "do_not_hoist_store"
  44. OpName %do_not_hoist_access_chain_load "do_not_hoist_access_chain_load"
  45. %void = OpTypeVoid
  46. %7 = OpTypeFunction %void
  47. %uint = OpTypeInt 32 0
  48. %_ptr_Function_uint = OpTypePointer Function %uint
  49. %uint_0 = OpConstant %uint 0
  50. %uint_123 = OpConstant %uint 123
  51. %bool = OpTypeBool
  52. %float = OpTypeFloat 32
  53. %v2float = OpTypeVector %float 2
  54. %_ptr_Function_v2float = OpTypePointer Function %v2float
  55. %float_0 = OpConstant %float 0
  56. %17 = OpConstantComposite %v2float %float_0 %float_0
  57. %_ptr_Function_float = OpTypePointer Function %float
  58. %int = OpTypeInt 32 1
  59. %int_1 = OpConstant %int 1
  60. %main = OpFunction %void None %7
  61. %21 = OpLabel
  62. %i = OpVariable %_ptr_Function_uint Function
  63. %do_not_hoist_store = OpVariable %_ptr_Function_v2float Function
  64. %do_not_hoist_access_chain_load = OpVariable %_ptr_Function_float Function
  65. OpStore %i %uint_0
  66. OpBranch %22
  67. %22 = OpLabel
  68. OpLoopMerge %23 %24 None
  69. OpBranch %25
  70. %25 = OpLabel
  71. %26 = OpLoad %uint %i
  72. %27 = OpULessThan %bool %26 %uint_123
  73. OpBranchConditional %27 %28 %23
  74. %28 = OpLabel
  75. OpStore %do_not_hoist_store %17
  76. %29 = OpAccessChain %_ptr_Function_float %do_not_hoist_store %uint_0
  77. %30 = OpLoad %float %29
  78. OpStore %do_not_hoist_access_chain_load %30
  79. OpBranch %24
  80. %24 = OpLabel
  81. %31 = OpLoad %uint %i
  82. %32 = OpIAdd %uint %31 %int_1
  83. OpStore %i %32
  84. OpBranch %22
  85. %23 = OpLabel
  86. OpReturn
  87. OpFunctionEnd
  88. )";
  89. const std::string after_hoist = R"(OpCapability Shader
  90. %1 = OpExtInstImport "GLSL.std.450"
  91. OpMemoryModel Logical GLSL450
  92. OpEntryPoint Fragment %main "main"
  93. OpExecutionMode %main OriginUpperLeft
  94. OpSource GLSL 460
  95. OpName %main "main"
  96. OpName %i "i"
  97. OpName %do_not_hoist_store "do_not_hoist_store"
  98. OpName %do_not_hoist_access_chain_load "do_not_hoist_access_chain_load"
  99. %void = OpTypeVoid
  100. %7 = OpTypeFunction %void
  101. %uint = OpTypeInt 32 0
  102. %_ptr_Function_uint = OpTypePointer Function %uint
  103. %uint_0 = OpConstant %uint 0
  104. %uint_123 = OpConstant %uint 123
  105. %bool = OpTypeBool
  106. %float = OpTypeFloat 32
  107. %v2float = OpTypeVector %float 2
  108. %_ptr_Function_v2float = OpTypePointer Function %v2float
  109. %float_0 = OpConstant %float 0
  110. %17 = OpConstantComposite %v2float %float_0 %float_0
  111. %_ptr_Function_float = OpTypePointer Function %float
  112. %int = OpTypeInt 32 1
  113. %int_1 = OpConstant %int 1
  114. %main = OpFunction %void None %7
  115. %21 = OpLabel
  116. %i = OpVariable %_ptr_Function_uint Function
  117. %do_not_hoist_store = OpVariable %_ptr_Function_v2float Function
  118. %do_not_hoist_access_chain_load = OpVariable %_ptr_Function_float Function
  119. OpStore %i %uint_0
  120. %29 = OpAccessChain %_ptr_Function_float %do_not_hoist_store %uint_0
  121. OpBranch %22
  122. %22 = OpLabel
  123. OpLoopMerge %23 %24 None
  124. OpBranch %25
  125. %25 = OpLabel
  126. %26 = OpLoad %uint %i
  127. %27 = OpULessThan %bool %26 %uint_123
  128. OpBranchConditional %27 %28 %23
  129. %28 = OpLabel
  130. OpStore %do_not_hoist_store %17
  131. %30 = OpLoad %float %29
  132. OpStore %do_not_hoist_access_chain_load %30
  133. OpBranch %24
  134. %24 = OpLabel
  135. %31 = OpLoad %uint %i
  136. %32 = OpIAdd %uint %31 %int_1
  137. OpStore %i %32
  138. OpBranch %22
  139. %23 = OpLabel
  140. OpReturn
  141. OpFunctionEnd
  142. )";
  143. SinglePassRunAndCheck<LICMPass>(before_hoist, after_hoist, true);
  144. }
  145. } // namespace
  146. } // namespace opt
  147. } // namespace spvtools