2
0

cf.switch.opswitch.hlsl 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. // Run: %dxc -T ps_6_0 -E main
  2. int foo() { return 200; }
  3. void main() {
  4. int result;
  5. ////////////////////////////
  6. // The most basic case //
  7. // Has a 'default' case //
  8. // All cases have 'break' //
  9. ////////////////////////////
  10. int a = 0;
  11. // CHECK: [[a:%\d+]] = OpLoad %int %a
  12. // CHECK-NEXT: OpSelectionMerge %switch_merge None
  13. // CHECK-NEXT: OpSwitch [[a]] %switch_default -3 %switch_n3 0 %switch_0 1 %switch_1 2 %switch_2
  14. switch(a) {
  15. // CHECK-NEXT: %switch_n3 = OpLabel
  16. // CHECK-NEXT: OpStore %result %int_n300
  17. // CHECK-NEXT: OpBranch %switch_merge
  18. case -3:
  19. result = -300;
  20. break;
  21. // CHECK-NEXT: %switch_0 = OpLabel
  22. // CHECK-NEXT: OpStore %result %int_0
  23. // CHECK-NEXT: OpBranch %switch_merge
  24. case 0:
  25. result = 0;
  26. break;
  27. // CHECK-NEXT: %switch_1 = OpLabel
  28. // CHECK-NEXT: OpStore %result %int_100
  29. // CHECK-NEXT: OpBranch %switch_merge
  30. case 1:
  31. result = 100;
  32. break;
  33. // CHECK-NEXT: %switch_2 = OpLabel
  34. // CHECK-NEXT: [[foo:%\d+]] = OpFunctionCall %int %foo
  35. // CHECK-NEXT: OpStore %result [[foo]]
  36. // CHECK-NEXT: OpBranch %switch_merge
  37. case 2:
  38. result = foo();
  39. break;
  40. // CHECK-NEXT: %switch_default = OpLabel
  41. // CHECK-NEXT: OpStore %result %int_777
  42. // CHECK-NEXT: OpBranch %switch_merge
  43. default:
  44. result = 777;
  45. break;
  46. }
  47. // CHECK-NEXT: %switch_merge = OpLabel
  48. ////////////////////////////////////
  49. // The selector is a statement //
  50. // Does not have a 'default' case //
  51. // All cases have 'break' //
  52. ////////////////////////////////////
  53. // CHECK-NEXT: [[a1:%\d+]] = OpLoad %int %a
  54. // CHECK-NEXT: OpStore %c [[a1]]
  55. // CHECK-NEXT: [[c:%\d+]] = OpLoad %int %c
  56. // CHECK-NEXT: OpSelectionMerge %switch_merge_0 None
  57. // CHECK-NEXT: OpSwitch [[c]] %switch_merge_0 -4 %switch_n4 4 %switch_4
  58. switch(int c = a) {
  59. // CHECK-NEXT: %switch_n4 = OpLabel
  60. // CHECK-NEXT: OpStore %result %int_n400
  61. // CHECK-NEXT: OpBranch %switch_merge_0
  62. case -4:
  63. result = -400;
  64. break;
  65. // CHECK-NEXT: %switch_4 = OpLabel
  66. // CHECK-NEXT: OpStore %result %int_400
  67. // CHECK-NEXT: OpBranch %switch_merge_0
  68. case 4:
  69. result = 400;
  70. break;
  71. }
  72. // CHECK-NEXT: %switch_merge_0 = OpLabel
  73. ///////////////////////////////////
  74. // All cases are fall-through //
  75. // The last case is fall-through //
  76. ///////////////////////////////////
  77. // CHECK-NEXT: [[a2:%\d+]] = OpLoad %int %a
  78. // CHECK-NEXT: OpSelectionMerge %switch_merge_1 None
  79. // CHECK-NEXT: OpSwitch [[a2]] %switch_merge_1 -5 %switch_n5 5 %switch_5
  80. switch(a) {
  81. // CHECK-NEXT: %switch_n5 = OpLabel
  82. // CHECK-NEXT: OpStore %result %int_n500
  83. // CHECK-NEXT: OpBranch %switch_5
  84. case -5:
  85. result = -500;
  86. // CHECK-NEXT: %switch_5 = OpLabel
  87. // CHECK-NEXT: OpStore %result %int_500
  88. // CHECK-NEXT: OpBranch %switch_merge_1
  89. case 5:
  90. result = 500;
  91. }
  92. // CHECK-NEXT: %switch_merge_1 = OpLabel
  93. ///////////////////////////////////////
  94. // Some cases are fall-through //
  95. // The last case is not fall-through //
  96. ///////////////////////////////////////
  97. // CHECK-NEXT: [[a3:%\d+]] = OpLoad %int %a
  98. // CHECK-NEXT: OpSelectionMerge %switch_merge_2 None
  99. // CHECK-NEXT: OpSwitch [[a3]] %switch_default_0 6 %switch_6 7 %switch_7 8 %switch_8
  100. switch(a) {
  101. // CHECK-NEXT: %switch_6 = OpLabel
  102. // CHECK-NEXT: OpStore %result %int_600
  103. // CHECK-NEXT: OpBranch %switch_7
  104. case 6:
  105. result = 600;
  106. case 7:
  107. // CHECK-NEXT: %switch_7 = OpLabel
  108. // CHECK-NEXT: OpStore %result %int_700
  109. // CHECK-NEXT: OpBranch %switch_8
  110. result = 700;
  111. // CHECK-NEXT: %switch_8 = OpLabel
  112. // CHECK-NEXT: OpStore %result %int_800
  113. // CHECK-NEXT: OpBranch %switch_merge_2
  114. case 8:
  115. result = 800;
  116. break;
  117. // CHECK-NEXT: %switch_default_0 = OpLabel
  118. // CHECK-NEXT: OpStore %result %int_777
  119. // CHECK-NEXT: OpBranch %switch_merge_2
  120. default:
  121. result = 777;
  122. break;
  123. }
  124. // CHECK-NEXT: %switch_merge_2 = OpLabel
  125. ///////////////////////////////////////
  126. // Fall-through cases with no body //
  127. ///////////////////////////////////////
  128. // CHECK-NEXT: [[a4:%\d+]] = OpLoad %int %a
  129. // CHECK-NEXT: OpSelectionMerge %switch_merge_3 None
  130. // CHECK-NEXT: OpSwitch [[a4]] %switch_default_1 10 %switch_10 11 %switch_11 12 %switch_12
  131. switch(a) {
  132. // CHECK-NEXT: %switch_10 = OpLabel
  133. // CHECK-NEXT: OpBranch %switch_11
  134. case 10:
  135. // CHECK-NEXT: %switch_11 = OpLabel
  136. // CHECK-NEXT: OpBranch %switch_default_1
  137. case 11:
  138. // CHECK-NEXT: %switch_default_1 = OpLabel
  139. // CHECK-NEXT: OpBranch %switch_12
  140. default:
  141. // CHECK-NEXT: %switch_12 = OpLabel
  142. // CHECK-NEXT: OpStore %result %int_12
  143. // CHECK-NEXT: OpBranch %switch_merge_3
  144. case 12:
  145. result = 12;
  146. }
  147. // CHECK-NEXT: %switch_merge_3 = OpLabel
  148. ////////////////////////////////////////////////
  149. // No-op. Two nested cases and a nested break //
  150. ////////////////////////////////////////////////
  151. // CHECK-NEXT: [[a5:%\d+]] = OpLoad %int %a
  152. // CHECK-NEXT: OpSelectionMerge %switch_merge_4 None
  153. // CHECK-NEXT: OpSwitch [[a5]] %switch_merge_4 15 %switch_15 16 %switch_16
  154. switch(a) {
  155. // CHECK-NEXT: %switch_15 = OpLabel
  156. // CHECK-NEXT: OpBranch %switch_16
  157. case 15:
  158. // CHECK-NEXT: %switch_16 = OpLabel
  159. // CHECK-NEXT: OpBranch %switch_merge_4
  160. case 16:
  161. break;
  162. }
  163. // CHECK-NEXT: %switch_merge_4 = OpLabel
  164. ////////////////////////////////////////////////////////////////
  165. // Using braces (compound statements) in various parts //
  166. // Using breaks such that each AST configuration is different //
  167. // Also uses 'forcecase' attribute //
  168. ////////////////////////////////////////////////////////////////
  169. // CHECK-NEXT: [[a6:%\d+]] = OpLoad %int %a
  170. // CHECK-NEXT: OpSelectionMerge %switch_merge_5 None
  171. // CHECK-NEXT: OpSwitch [[a6]] %switch_merge_5 20 %switch_20 21 %switch_21 22 %switch_22 23 %switch_23 24 %switch_24 25 %switch_25 26 %switch_26 27 %switch_27 28 %switch_28 29 %switch_29
  172. [forcecase] switch(a) {
  173. // CHECK-NEXT: %switch_20 = OpLabel
  174. // CHECK-NEXT: OpStore %result %int_20
  175. // CHECK-NEXT: OpBranch %switch_merge_5
  176. case 20: {
  177. result = 20;
  178. break;
  179. }
  180. // CHECK-NEXT: %switch_21 = OpLabel
  181. // CHECK-NEXT: OpStore %result %int_21
  182. // CHECK-NEXT: OpBranch %switch_merge_5
  183. case 21:
  184. result = 21;
  185. break;
  186. // CHECK-NEXT: %switch_22 = OpLabel
  187. // CHECK-NEXT: OpBranch %switch_23
  188. // CHECK-NEXT: %switch_23 = OpLabel
  189. // CHECK-NEXT: OpBranch %switch_merge_5
  190. case 22:
  191. case 23:
  192. break;
  193. // CHECK-NEXT: %switch_24 = OpLabel
  194. // CHECK-NEXT: OpBranch %switch_25
  195. // CHECK-NEXT: %switch_25 = OpLabel
  196. // CHECK-NEXT: OpStore %result %int_25
  197. // CHECK-NEXT: OpBranch %switch_merge_5
  198. case 24:
  199. case 25: { result = 25; }
  200. break;
  201. // CHECK-NEXT: %switch_26 = OpLabel
  202. // CHECK-NEXT: OpBranch %switch_27
  203. // CHECK-NEXT: %switch_27 = OpLabel
  204. // CHECK-NEXT: OpBranch %switch_merge_5
  205. case 26:
  206. case 27: {
  207. break;
  208. }
  209. // CHECK-NEXT: %switch_28 = OpLabel
  210. // CHECK-NEXT: OpStore %result %int_28
  211. // CHECK-NEXT: OpBranch %switch_merge_5
  212. case 28: {
  213. result = 28;
  214. {{break;}}
  215. }
  216. // CHECK-NEXT: %switch_29 = OpLabel
  217. // CHECK-NEXT: OpStore %result %int_29
  218. // CHECK-NEXT: OpBranch %switch_merge_5
  219. case 29: {
  220. {
  221. result = 29;
  222. {break;}
  223. }
  224. }
  225. }
  226. // CHECK-NEXT: %switch_merge_5 = OpLabel
  227. ////////////////////////////////////////////////////////////////////////
  228. // Nested Switch statements with mixed use of fall-through and braces //
  229. ////////////////////////////////////////////////////////////////////////
  230. // CHECK-NEXT: [[a7:%\d+]] = OpLoad %int %a
  231. // CHECK-NEXT: OpSelectionMerge %switch_merge_7 None
  232. // CHECK-NEXT: OpSwitch [[a7]] %switch_merge_7 30 %switch_30
  233. switch(a) {
  234. // CHECK-NEXT: %switch_30 = OpLabel
  235. case 30: {
  236. // CHECK-NEXT: OpStore %result %int_30
  237. result = 30;
  238. // CHECK-NEXT: [[result:%\d+]] = OpLoad %int %result
  239. // CHECK-NEXT: OpSelectionMerge %switch_merge_6 None
  240. // CHECK-NEXT: OpSwitch [[result]] %switch_default_2 50 %switch_50 51 %switch_51 52 %switch_52 53 %switch_53 54 %switch_54
  241. switch(result) {
  242. // CHECK-NEXT: %switch_default_2 = OpLabel
  243. // CHECK-NEXT: OpStore %a %int_55
  244. // CHECK-NEXT: OpBranch %switch_50
  245. default:
  246. a = 55;
  247. // CHECK-NEXT: %switch_50 = OpLabel
  248. // CHECK-NEXT: OpStore %a %int_50
  249. // CHECK-NEXT: OpBranch %switch_merge_6
  250. case 50:
  251. a = 50;
  252. break;
  253. // CHECK-NEXT: %switch_51 = OpLabel
  254. // CHECK-NEXT: OpBranch %switch_52
  255. case 51:
  256. // CHECK-NEXT: %switch_52 = OpLabel
  257. // CHECK-NEXT: OpStore %a %int_52
  258. // CHECK-NEXT: OpBranch %switch_53
  259. case 52:
  260. a = 52;
  261. // CHECK-NEXT: %switch_53 = OpLabel
  262. // CHECK-NEXT: OpStore %a %int_53
  263. // CHECK-NEXT: OpBranch %switch_merge_6
  264. case 53:
  265. a = 53;
  266. break;
  267. // CHECK-NEXT: %switch_54 = OpLabel
  268. // CHECK-NEXT: OpStore %a %int_54
  269. // CHECK-NEXT: OpBranch %switch_merge_6
  270. case 54 : {
  271. a = 54;
  272. break;
  273. }
  274. }
  275. // CHECK-NEXT: %switch_merge_6 = OpLabel
  276. // CHECK-NEXT: OpBranch %switch_merge_7
  277. }
  278. }
  279. // CHECK-NEXT: %switch_merge_7 = OpLabel
  280. ///////////////////////////////////////////////
  281. // Constant integer variables as case values //
  282. ///////////////////////////////////////////////
  283. const int r = 35;
  284. const int s = 45;
  285. const int t = 2*r + s; // evaluates to 115.
  286. // CHECK: [[a8:%\d+]] = OpLoad %int %a
  287. // CHECK-NEXT: OpSelectionMerge %switch_merge_8 None
  288. // CHECK-NEXT: OpSwitch [[a8]] %switch_merge_8 35 %switch_35 115 %switch_115
  289. switch(a) {
  290. // CHECK-NEXT: %switch_35 = OpLabel
  291. // CHECK-NEXT: [[r:%\d+]] = OpLoad %int %r
  292. // CHECK-NEXT: OpStore %result [[r]]
  293. // CHECK-NEXT: OpBranch %switch_115
  294. case r:
  295. result = r;
  296. // CHECK-NEXT: %switch_115 = OpLabel
  297. // CHECK-NEXT: [[t:%\d+]] = OpLoad %int %t
  298. // CHECK-NEXT: OpStore %result [[t]]
  299. // CHECK-NEXT: OpBranch %switch_merge_8
  300. case t:
  301. result = t;
  302. break;
  303. // CHECK-NEXT: %switch_merge_8 = OpLabel
  304. }
  305. //////////////////////////////////////////////////////////////////
  306. // Using float as selector results in multiple casts in the AST //
  307. //////////////////////////////////////////////////////////////////
  308. float sel;
  309. // CHECK: [[floatSelector:%\d+]] = OpLoad %float %sel
  310. // CHECK-NEXT: [[sel:%\d+]] = OpConvertFToS %int [[floatSelector]]
  311. // CHECK-NEXT: OpSelectionMerge %switch_merge_9 None
  312. // CHECK-NEXT: OpSwitch [[sel]] %switch_merge_9 0 %switch_0_0
  313. switch (sel) {
  314. case 0:
  315. result = 0;
  316. break;
  317. }
  318. }