binary-op.arithmetic.matrix.hlsl 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // Run: %dxc -T vs_6_0 -E main
  2. // CHECK: [[v3int1:%\d+]] = OpConstantComposite %v3int %int_1 %int_1 %int_1
  3. // CHECK: [[v3int0:%\d+]] = OpConstantComposite %v3int %int_0 %int_0 %int_0
  4. void main() {
  5. // CHECK-LABEL: %bb_entry = OpLabel
  6. // 1x1
  7. float1x1 a, b, c;
  8. // CHECK: [[a0:%\d+]] = OpLoad %float %a
  9. // CHECK-NEXT: [[b0:%\d+]] = OpLoad %float %b
  10. // CHECK-NEXT: [[c0:%\d+]] = OpFAdd %float [[a0]] [[b0]]
  11. // CHECK-NEXT: OpStore %c [[c0]]
  12. c = a + b;
  13. // CHECK-NEXT: [[a1:%\d+]] = OpLoad %float %a
  14. // CHECK-NEXT: [[b1:%\d+]] = OpLoad %float %b
  15. // CHECK-NEXT: [[c1:%\d+]] = OpFSub %float [[a1]] [[b1]]
  16. // CHECK-NEXT: OpStore %c [[c1]]
  17. c = a - b;
  18. // CHECK-NEXT: [[a2:%\d+]] = OpLoad %float %a
  19. // CHECK-NEXT: [[b2:%\d+]] = OpLoad %float %b
  20. // CHECK-NEXT: [[c2:%\d+]] = OpFMul %float [[a2]] [[b2]]
  21. // CHECK-NEXT: OpStore %c [[c2]]
  22. c = a * b;
  23. // CHECK-NEXT: [[a3:%\d+]] = OpLoad %float %a
  24. // CHECK-NEXT: [[b3:%\d+]] = OpLoad %float %b
  25. // CHECK-NEXT: [[c3:%\d+]] = OpFDiv %float [[a3]] [[b3]]
  26. // CHECK-NEXT: OpStore %c [[c3]]
  27. c = a / b;
  28. // CHECK-NEXT: [[a4:%\d+]] = OpLoad %float %a
  29. // CHECK-NEXT: [[b4:%\d+]] = OpLoad %float %b
  30. // CHECK-NEXT: [[c4:%\d+]] = OpFRem %float [[a4]] [[b4]]
  31. // CHECK-NEXT: OpStore %c [[c4]]
  32. c = a % b;
  33. // Mx1
  34. float2x1 h, i, j;
  35. // CHECK-NEXT: [[h0:%\d+]] = OpLoad %v2float %h
  36. // CHECK-NEXT: [[i0:%\d+]] = OpLoad %v2float %i
  37. // CHECK-NEXT: [[j0:%\d+]] = OpFAdd %v2float [[h0]] [[i0]]
  38. // CHECK-NEXT: OpStore %j [[j0]]
  39. j = h + i;
  40. // CHECK-NEXT: [[h1:%\d+]] = OpLoad %v2float %h
  41. // CHECK-NEXT: [[i1:%\d+]] = OpLoad %v2float %i
  42. // CHECK-NEXT: [[j1:%\d+]] = OpFSub %v2float [[h1]] [[i1]]
  43. // CHECK-NEXT: OpStore %j [[j1]]
  44. j = h - i;
  45. // CHECK-NEXT: [[h2:%\d+]] = OpLoad %v2float %h
  46. // CHECK-NEXT: [[i2:%\d+]] = OpLoad %v2float %i
  47. // CHECK-NEXT: [[j2:%\d+]] = OpFMul %v2float [[h2]] [[i2]]
  48. // CHECK-NEXT: OpStore %j [[j2]]
  49. j = h * i;
  50. // CHECK-NEXT: [[h3:%\d+]] = OpLoad %v2float %h
  51. // CHECK-NEXT: [[i3:%\d+]] = OpLoad %v2float %i
  52. // CHECK-NEXT: [[j3:%\d+]] = OpFDiv %v2float [[h3]] [[i3]]
  53. // CHECK-NEXT: OpStore %j [[j3]]
  54. j = h / i;
  55. // CHECK-NEXT: [[h4:%\d+]] = OpLoad %v2float %h
  56. // CHECK-NEXT: [[i4:%\d+]] = OpLoad %v2float %i
  57. // CHECK-NEXT: [[j4:%\d+]] = OpFRem %v2float [[h4]] [[i4]]
  58. // CHECK-NEXT: OpStore %j [[j4]]
  59. j = h % i;
  60. // 1xN
  61. float1x3 o, p, q;
  62. // CHECK-NEXT: [[o0:%\d+]] = OpLoad %v3float %o
  63. // CHECK-NEXT: [[p0:%\d+]] = OpLoad %v3float %p
  64. // CHECK-NEXT: [[q0:%\d+]] = OpFAdd %v3float [[o0]] [[p0]]
  65. // CHECK-NEXT: OpStore %q [[q0]]
  66. q = o + p;
  67. // CHECK-NEXT: [[o1:%\d+]] = OpLoad %v3float %o
  68. // CHECK-NEXT: [[p1:%\d+]] = OpLoad %v3float %p
  69. // CHECK-NEXT: [[q1:%\d+]] = OpFSub %v3float [[o1]] [[p1]]
  70. // CHECK-NEXT: OpStore %q [[q1]]
  71. q = o - p;
  72. // CHECK-NEXT: [[o2:%\d+]] = OpLoad %v3float %o
  73. // CHECK-NEXT: [[p2:%\d+]] = OpLoad %v3float %p
  74. // CHECK-NEXT: [[q2:%\d+]] = OpFMul %v3float [[o2]] [[p2]]
  75. // CHECK-NEXT: OpStore %q [[q2]]
  76. q = o * p;
  77. // CHECK-NEXT: [[o3:%\d+]] = OpLoad %v3float %o
  78. // CHECK-NEXT: [[p3:%\d+]] = OpLoad %v3float %p
  79. // CHECK-NEXT: [[q3:%\d+]] = OpFDiv %v3float [[o3]] [[p3]]
  80. // CHECK-NEXT: OpStore %q [[q3]]
  81. q = o / p;
  82. // CHECK-NEXT: [[o4:%\d+]] = OpLoad %v3float %o
  83. // CHECK-NEXT: [[p4:%\d+]] = OpLoad %v3float %p
  84. // CHECK-NEXT: [[q4:%\d+]] = OpFRem %v3float [[o4]] [[p4]]
  85. // CHECK-NEXT: OpStore %q [[q4]]
  86. q = o % p;
  87. // MxN
  88. float2x3 r, s, t;
  89. // CHECK-NEXT: [[r0:%\d+]] = OpLoad %mat2v3float %r
  90. // CHECK-NEXT: [[s0:%\d+]] = OpLoad %mat2v3float %s
  91. // CHECK-NEXT: [[r0v0:%\d+]] = OpCompositeExtract %v3float [[r0]] 0
  92. // CHECK-NEXT: [[s0v0:%\d+]] = OpCompositeExtract %v3float [[s0]] 0
  93. // CHECK-NEXT: [[t0v0:%\d+]] = OpFAdd %v3float [[r0v0]] [[s0v0]]
  94. // CHECK-NEXT: [[r0v1:%\d+]] = OpCompositeExtract %v3float [[r0]] 1
  95. // CHECK-NEXT: [[s0v1:%\d+]] = OpCompositeExtract %v3float [[s0]] 1
  96. // CHECK-NEXT: [[t0v1:%\d+]] = OpFAdd %v3float [[r0v1]] [[s0v1]]
  97. // CHECK-NEXT: [[t0:%\d+]] = OpCompositeConstruct %mat2v3float [[t0v0]] [[t0v1]]
  98. // CHECK-NEXT: OpStore %t [[t0]]
  99. t = r + s;
  100. // CHECK-NEXT: [[r1:%\d+]] = OpLoad %mat2v3float %r
  101. // CHECK-NEXT: [[s1:%\d+]] = OpLoad %mat2v3float %s
  102. // CHECK-NEXT: [[r1v0:%\d+]] = OpCompositeExtract %v3float [[r1]] 0
  103. // CHECK-NEXT: [[s1v0:%\d+]] = OpCompositeExtract %v3float [[s1]] 0
  104. // CHECK-NEXT: [[t1v0:%\d+]] = OpFSub %v3float [[r1v0]] [[s1v0]]
  105. // CHECK-NEXT: [[r1v1:%\d+]] = OpCompositeExtract %v3float [[r1]] 1
  106. // CHECK-NEXT: [[s1v1:%\d+]] = OpCompositeExtract %v3float [[s1]] 1
  107. // CHECK-NEXT: [[t1v1:%\d+]] = OpFSub %v3float [[r1v1]] [[s1v1]]
  108. // CHECK-NEXT: [[t1:%\d+]] = OpCompositeConstruct %mat2v3float [[t1v0]] [[t1v1]]
  109. // CHECK-NEXT: OpStore %t [[t1]]
  110. t = r - s;
  111. // CHECK-NEXT: [[r2:%\d+]] = OpLoad %mat2v3float %r
  112. // CHECK-NEXT: [[s2:%\d+]] = OpLoad %mat2v3float %s
  113. // CHECK-NEXT: [[r2v0:%\d+]] = OpCompositeExtract %v3float [[r2]] 0
  114. // CHECK-NEXT: [[s2v0:%\d+]] = OpCompositeExtract %v3float [[s2]] 0
  115. // CHECK-NEXT: [[t2v0:%\d+]] = OpFMul %v3float [[r2v0]] [[s2v0]]
  116. // CHECK-NEXT: [[r2v1:%\d+]] = OpCompositeExtract %v3float [[r2]] 1
  117. // CHECK-NEXT: [[s2v1:%\d+]] = OpCompositeExtract %v3float [[s2]] 1
  118. // CHECK-NEXT: [[t2v1:%\d+]] = OpFMul %v3float [[r2v1]] [[s2v1]]
  119. // CHECK-NEXT: [[t2:%\d+]] = OpCompositeConstruct %mat2v3float [[t2v0]] [[t2v1]]
  120. // CHECK-NEXT: OpStore %t [[t2]]
  121. t = r * s;
  122. // CHECK-NEXT: [[r3:%\d+]] = OpLoad %mat2v3float %r
  123. // CHECK-NEXT: [[s3:%\d+]] = OpLoad %mat2v3float %s
  124. // CHECK-NEXT: [[r3v0:%\d+]] = OpCompositeExtract %v3float [[r3]] 0
  125. // CHECK-NEXT: [[s3v0:%\d+]] = OpCompositeExtract %v3float [[s3]] 0
  126. // CHECK-NEXT: [[t3v0:%\d+]] = OpFDiv %v3float [[r3v0]] [[s3v0]]
  127. // CHECK-NEXT: [[r3v1:%\d+]] = OpCompositeExtract %v3float [[r3]] 1
  128. // CHECK-NEXT: [[s3v1:%\d+]] = OpCompositeExtract %v3float [[s3]] 1
  129. // CHECK-NEXT: [[t3v1:%\d+]] = OpFDiv %v3float [[r3v1]] [[s3v1]]
  130. // CHECK-NEXT: [[t3:%\d+]] = OpCompositeConstruct %mat2v3float [[t3v0]] [[t3v1]]
  131. // CHECK-NEXT: OpStore %t [[t3]]
  132. t = r / s;
  133. // CHECK-NEXT: [[r4:%\d+]] = OpLoad %mat2v3float %r
  134. // CHECK-NEXT: [[s4:%\d+]] = OpLoad %mat2v3float %s
  135. // CHECK-NEXT: [[r4v0:%\d+]] = OpCompositeExtract %v3float [[r4]] 0
  136. // CHECK-NEXT: [[s4v0:%\d+]] = OpCompositeExtract %v3float [[s4]] 0
  137. // CHECK-NEXT: [[t4v0:%\d+]] = OpFRem %v3float [[r4v0]] [[s4v0]]
  138. // CHECK-NEXT: [[r4v1:%\d+]] = OpCompositeExtract %v3float [[r4]] 1
  139. // CHECK-NEXT: [[s4v1:%\d+]] = OpCompositeExtract %v3float [[s4]] 1
  140. // CHECK-NEXT: [[t4v1:%\d+]] = OpFRem %v3float [[r4v1]] [[s4v1]]
  141. // CHECK-NEXT: [[t4:%\d+]] = OpCompositeConstruct %mat2v3float [[t4v0]] [[t4v1]]
  142. // CHECK-NEXT: OpStore %t [[t4]]
  143. t = r % s;
  144. // MxN non-floating point matrices
  145. int2x3 u, v, w;
  146. // CHECK-NEXT: [[u0:%\d+]] = OpLoad %_arr_v3int_uint_2 %u
  147. // CHECK-NEXT: [[v0:%\d+]] = OpLoad %_arr_v3int_uint_2 %v
  148. // CHECK-NEXT: [[u0v0:%\d+]] = OpCompositeExtract %v3int [[u0]] 0
  149. // CHECK-NEXT: [[v0v0:%\d+]] = OpCompositeExtract %v3int [[v0]] 0
  150. // CHECK-NEXT: [[w0v0:%\d+]] = OpIAdd %v3int [[u0v0]] [[v0v0]]
  151. // CHECK-NEXT: [[u0v1:%\d+]] = OpCompositeExtract %v3int [[u0]] 1
  152. // CHECK-NEXT: [[v0v1:%\d+]] = OpCompositeExtract %v3int [[v0]] 1
  153. // CHECK-NEXT: [[w0v1:%\d+]] = OpIAdd %v3int [[u0v1]] [[v0v1]]
  154. // CHECK-NEXT: [[w0:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[w0v0]] [[w0v1]]
  155. // CHECK-NEXT: OpStore %w [[w0]]
  156. w = u + v;
  157. // CHECK-NEXT: [[u1:%\d+]] = OpLoad %_arr_v3int_uint_2 %u
  158. // CHECK-NEXT: [[v1:%\d+]] = OpLoad %_arr_v3int_uint_2 %v
  159. // CHECK-NEXT: [[u1v0:%\d+]] = OpCompositeExtract %v3int [[u1]] 0
  160. // CHECK-NEXT: [[v1v0:%\d+]] = OpCompositeExtract %v3int [[v1]] 0
  161. // CHECK-NEXT: [[w1v0:%\d+]] = OpISub %v3int [[u1v0]] [[v1v0]]
  162. // CHECK-NEXT: [[u1v1:%\d+]] = OpCompositeExtract %v3int [[u1]] 1
  163. // CHECK-NEXT: [[v1v1:%\d+]] = OpCompositeExtract %v3int [[v1]] 1
  164. // CHECK-NEXT: [[w1v1:%\d+]] = OpISub %v3int [[u1v1]] [[v1v1]]
  165. // CHECK-NEXT: [[w1:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[w1v0]] [[w1v1]]
  166. // CHECK-NEXT: OpStore %w [[w1]]
  167. w = u - v;
  168. // CHECK-NEXT: [[u2:%\d+]] = OpLoad %_arr_v3int_uint_2 %u
  169. // CHECK-NEXT: [[v2:%\d+]] = OpLoad %_arr_v3int_uint_2 %v
  170. // CHECK-NEXT: [[u2v0:%\d+]] = OpCompositeExtract %v3int [[u2]] 0
  171. // CHECK-NEXT: [[v2v0:%\d+]] = OpCompositeExtract %v3int [[v2]] 0
  172. // CHECK-NEXT: [[w2v0:%\d+]] = OpIMul %v3int [[u2v0]] [[v2v0]]
  173. // CHECK-NEXT: [[u2v1:%\d+]] = OpCompositeExtract %v3int [[u2]] 1
  174. // CHECK-NEXT: [[v2v1:%\d+]] = OpCompositeExtract %v3int [[v2]] 1
  175. // CHECK-NEXT: [[w2v1:%\d+]] = OpIMul %v3int [[u2v1]] [[v2v1]]
  176. // CHECK-NEXT: [[w2:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[w2v0]] [[w2v1]]
  177. // CHECK-NEXT: OpStore %w [[w2]]
  178. w = u * v;
  179. // CHECK-NEXT: [[u3:%\d+]] = OpLoad %_arr_v3int_uint_2 %u
  180. // CHECK-NEXT: [[v3:%\d+]] = OpLoad %_arr_v3int_uint_2 %v
  181. // CHECK-NEXT: [[u3v0:%\d+]] = OpCompositeExtract %v3int [[u3]] 0
  182. // CHECK-NEXT: [[v3v0:%\d+]] = OpCompositeExtract %v3int [[v3]] 0
  183. // CHECK-NEXT: [[w3v0:%\d+]] = OpSDiv %v3int [[u3v0]] [[v3v0]]
  184. // CHECK-NEXT: [[u3v1:%\d+]] = OpCompositeExtract %v3int [[u3]] 1
  185. // CHECK-NEXT: [[v3v1:%\d+]] = OpCompositeExtract %v3int [[v3]] 1
  186. // CHECK-NEXT: [[w3v1:%\d+]] = OpSDiv %v3int [[u3v1]] [[v3v1]]
  187. // CHECK-NEXT: [[w3:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[w3v0]] [[w3v1]]
  188. // CHECK-NEXT: OpStore %w [[w3]]
  189. w = u / v;
  190. // CHECK-NEXT: [[u4:%\d+]] = OpLoad %_arr_v3int_uint_2 %u
  191. // CHECK-NEXT: [[v4:%\d+]] = OpLoad %_arr_v3int_uint_2 %v
  192. // CHECK-NEXT: [[u4v0:%\d+]] = OpCompositeExtract %v3int [[u4]] 0
  193. // CHECK-NEXT: [[v4v0:%\d+]] = OpCompositeExtract %v3int [[v4]] 0
  194. // CHECK-NEXT: [[w4v0:%\d+]] = OpSRem %v3int [[u4v0]] [[v4v0]]
  195. // CHECK-NEXT: [[u4v1:%\d+]] = OpCompositeExtract %v3int [[u4]] 1
  196. // CHECK-NEXT: [[v4v1:%\d+]] = OpCompositeExtract %v3int [[v4]] 1
  197. // CHECK-NEXT: [[w4v1:%\d+]] = OpSRem %v3int [[u4v1]] [[v4v1]]
  198. // CHECK-NEXT: [[w4:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[w4v0]] [[w4v1]]
  199. // CHECK-NEXT: OpStore %w [[w4]]
  200. w = u % v;
  201. // Boolean matrices
  202. // In all cases, the boolean matrix (represented as an array of boolean vectores)
  203. // is first casted to an integer matrix (represented as an array of integer vectors).
  204. // Then, the binary operation (e.g. '+', '-', '*', '/', '%') is performed and then
  205. // it is converted back to a boolean matrix. This behavior is due to the AST.
  206. bool2x3 x, y, z;
  207. // CHECK-NEXT: [[x0:%\d+]] = OpLoad %_arr_v3bool_uint_2 %x
  208. // CHECK-NEXT: [[x0v0:%\d+]] = OpCompositeExtract %v3bool [[x0]] 0
  209. // CHECK-NEXT: [[x0v0int:%\d+]] = OpSelect %v3int [[x0v0]] [[v3int1]] [[v3int0]]
  210. // CHECK-NEXT: [[x0v1:%\d+]] = OpCompositeExtract %v3bool [[x0]] 1
  211. // CHECK-NEXT: [[x0v1int:%\d+]] = OpSelect %v3int [[x0v1]] [[v3int1]] [[v3int0]]
  212. // CHECK-NEXT: [[x0int:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[x0v0int]] [[x0v1int]]
  213. // CHECK-NEXT: [[y0:%\d+]] = OpLoad %_arr_v3bool_uint_2 %y
  214. // CHECK-NEXT: [[y0v0:%\d+]] = OpCompositeExtract %v3bool [[y0]] 0
  215. // CHECK-NEXT: [[y0v0int:%\d+]] = OpSelect %v3int [[y0v0]] [[v3int1]] [[v3int0]]
  216. // CHECK-NEXT: [[y0v1:%\d+]] = OpCompositeExtract %v3bool [[y0]] 1
  217. // CHECK-NEXT: [[y0v1int:%\d+]] = OpSelect %v3int [[y0v1]] [[v3int1]] [[v3int0]]
  218. // CHECK-NEXT: [[y0int:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[y0v0int]] [[y0v1int]]
  219. // CHECK-NEXT: [[x0v0:%\d+]] = OpCompositeExtract %v3int [[x0int]] 0
  220. // CHECK-NEXT: [[y0v0:%\d+]] = OpCompositeExtract %v3int [[y0int]] 0
  221. // CHECK-NEXT: [[z0v0:%\d+]] = OpIAdd %v3int [[x0v0]] [[y0v0]]
  222. // CHECK-NEXT: [[x0v1:%\d+]] = OpCompositeExtract %v3int [[x0int]] 1
  223. // CHECK-NEXT: [[y0v1:%\d+]] = OpCompositeExtract %v3int [[y0int]] 1
  224. // CHECK-NEXT: [[z0v1:%\d+]] = OpIAdd %v3int [[x0v1]] [[y0v1]]
  225. // CHECK-NEXT: [[z_int:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[z0v0]] [[z0v1]]
  226. // CHECK-NEXT: [[z0v0:%\d+]] = OpCompositeExtract %v3int [[z_int]] 0
  227. // CHECK-NEXT:[[z0v0bool:%\d+]] = OpINotEqual %v3bool [[z0v0]] [[v3int0]]
  228. // CHECK-NEXT: [[z0v1:%\d+]] = OpCompositeExtract %v3int [[z_int]] 1
  229. // CHECK-NEXT:[[z0v1bool:%\d+]] = OpINotEqual %v3bool [[z0v1]] [[v3int0]]
  230. // CHECK-NEXT: [[z:%\d+]] = OpCompositeConstruct %_arr_v3bool_uint_2 [[z0v0bool]] [[z0v1bool]]
  231. // CHECK-NEXT: OpStore %z [[z]]
  232. z = x + y;
  233. }