binary-op.arithmetic.mixed.hlsl 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Run: %dxc -T vs_6_0 -E main
  2. void main() {
  3. // CHECK-LABEL: %bb_entry = OpLabel
  4. float4 a, b;
  5. float s;
  6. int3 c, d;
  7. int t;
  8. float1 e, f;
  9. int1 g, h;
  10. float2x3 i, j;
  11. float1x3 k, l;
  12. float2x1 m, n;
  13. float1x1 o, p;
  14. // Use OpVectorTimesScalar for floatN * float
  15. // CHECK: [[a4:%\d+]] = OpLoad %v4float %a
  16. // CHECK-NEXT: [[s0:%\d+]] = OpLoad %float %s
  17. // CHECK-NEXT: [[mul0:%\d+]] = OpVectorTimesScalar %v4float [[a4]] [[s0]]
  18. // CHECK-NEXT: OpStore %b [[mul0]]
  19. b = a * s;
  20. // CHECK-NEXT: [[a5:%\d+]] = OpLoad %v4float %a
  21. // CHECK-NEXT: [[s1:%\d+]] = OpLoad %float %s
  22. // CHECK-NEXT: [[mul1:%\d+]] = OpVectorTimesScalar %v4float [[a5]] [[s1]]
  23. // CHECK-NEXT: OpStore %b [[mul1]]
  24. b = s * a;
  25. // Use normal OpCompositeConstruct and OpIMul for intN * int
  26. // CHECK-NEXT: [[c0:%\d+]] = OpLoad %v3int %c
  27. // CHECK-NEXT: [[t0:%\d+]] = OpLoad %int %t
  28. // CHECK-NEXT: [[cc10:%\d+]] = OpCompositeConstruct %v3int [[t0]] [[t0]] [[t0]]
  29. // CHECK-NEXT: [[mul2:%\d+]] = OpIMul %v3int [[c0]] [[cc10]]
  30. // CHECK-NEXT: OpStore %d [[mul2]]
  31. d = c * t;
  32. // CHECK-NEXT: [[t1:%\d+]] = OpLoad %int %t
  33. // CHECK-NEXT: [[cc11:%\d+]] = OpCompositeConstruct %v3int [[t1]] [[t1]] [[t1]]
  34. // CHECK-NEXT: [[c1:%\d+]] = OpLoad %v3int %c
  35. // CHECK-NEXT: [[mul3:%\d+]] = OpIMul %v3int [[cc11]] [[c1]]
  36. // CHECK-NEXT: OpStore %d [[mul3]]
  37. d = t * c;
  38. // Vector of size 1
  39. // CHECK-NEXT: [[e0:%\d+]] = OpLoad %float %e
  40. // CHECK-NEXT: [[s2:%\d+]] = OpLoad %float %s
  41. // CHECK-NEXT: [[mul4:%\d+]] = OpFMul %float [[e0]] [[s2]]
  42. // CHECK-NEXT: OpStore %f [[mul4]]
  43. f = e * s;
  44. // CHECK-NEXT: [[s3:%\d+]] = OpLoad %float %s
  45. // CHECK-NEXT: [[e1:%\d+]] = OpLoad %float %e
  46. // CHECK-NEXT: [[mul5:%\d+]] = OpFMul %float [[s3]] [[e1]]
  47. // CHECK-NEXT: OpStore %f [[mul5]]
  48. f = s * e;
  49. // CHECK-NEXT: [[g0:%\d+]] = OpLoad %int %g
  50. // CHECK-NEXT: [[t2:%\d+]] = OpLoad %int %t
  51. // CHECK-NEXT: [[mul6:%\d+]] = OpIMul %int [[g0]] [[t2]]
  52. // CHECK-NEXT: OpStore %h [[mul6]]
  53. h = g * t;
  54. // CHECK-NEXT: [[t3:%\d+]] = OpLoad %int %t
  55. // CHECK-NEXT: [[g1:%\d+]] = OpLoad %int %g
  56. // CHECK-NEXT: [[mul7:%\d+]] = OpIMul %int [[t3]] [[g1]]
  57. // CHECK-NEXT: OpStore %h [[mul7]]
  58. h = t * g;
  59. // Use OpMatrixTimesScalar for floatMxN * float
  60. // CHECK-NEXT: [[i0:%\d+]] = OpLoad %mat2v3float %i
  61. // CHECK-NEXT: [[s4:%\d+]] = OpLoad %float %s
  62. // CHECK-NEXT: [[mul8:%\d+]] = OpMatrixTimesScalar %mat2v3float [[i0]] [[s4]]
  63. // CHECK-NEXT: OpStore %j [[mul8]]
  64. j = i * s;
  65. // CHECK-NEXT: [[i1:%\d+]] = OpLoad %mat2v3float %i
  66. // CHECK-NEXT: [[s5:%\d+]] = OpLoad %float %s
  67. // CHECK-NEXT: [[mul9:%\d+]] = OpMatrixTimesScalar %mat2v3float [[i1]] [[s5]]
  68. // CHECK-NEXT: OpStore %j [[mul9]]
  69. j = s * i;
  70. // Use OpVectorTimesScalar for float1xN * float
  71. // CHECK-NEXT: [[k0:%\d+]] = OpLoad %v3float %k
  72. // CHECK-NEXT: [[s6:%\d+]] = OpLoad %float %s
  73. // CHECK-NEXT: [[mul10:%\d+]] = OpVectorTimesScalar %v3float [[k0]] [[s6]]
  74. // CHECK-NEXT: OpStore %l [[mul10]]
  75. l = k * s;
  76. // CHECK-NEXT: [[k1:%\d+]] = OpLoad %v3float %k
  77. // CHECK-NEXT: [[s7:%\d+]] = OpLoad %float %s
  78. // CHECK-NEXT: [[mul11:%\d+]] = OpVectorTimesScalar %v3float [[k1]] [[s7]]
  79. // CHECK-NEXT: OpStore %l [[mul11]]
  80. l = s * k;
  81. // Use OpVectorTimesScalar for floatMx1 * float
  82. // CHECK-NEXT: [[m0:%\d+]] = OpLoad %v2float %m
  83. // CHECK-NEXT: [[s8:%\d+]] = OpLoad %float %s
  84. // CHECK-NEXT: [[mul12:%\d+]] = OpVectorTimesScalar %v2float [[m0]] [[s8]]
  85. // CHECK-NEXT: OpStore %n [[mul12]]
  86. n = m * s;
  87. // CHECK-NEXT: [[m1:%\d+]] = OpLoad %v2float %m
  88. // CHECK-NEXT: [[s9:%\d+]] = OpLoad %float %s
  89. // CHECK-NEXT: [[mul13:%\d+]] = OpVectorTimesScalar %v2float [[m1]] [[s9]]
  90. // CHECK-NEXT: OpStore %n [[mul13]]
  91. n = s * m;
  92. // Matrix of size 1x1
  93. // CHECK-NEXT: [[o0:%\d+]] = OpLoad %float %o
  94. // CHECK-NEXT: [[s10:%\d+]] = OpLoad %float %s
  95. // CHECK-NEXT: [[mul14:%\d+]] = OpFMul %float [[o0]] [[s10]]
  96. // CHECK-NEXT: OpStore %p [[mul14]]
  97. p = o * s;
  98. // CHECK-NEXT: [[s11:%\d+]] = OpLoad %float %s
  99. // CHECK-NEXT: [[o1:%\d+]] = OpLoad %float %o
  100. // CHECK-NEXT: [[mul15:%\d+]] = OpFMul %float [[s11]] [[o1]]
  101. // CHECK-NEXT: OpStore %p [[mul15]]
  102. p = s * o;
  103. // Non-floating point matrices:
  104. // Since non-fp matrices are represented as arrays of vectors, we cannot use
  105. // OpMatrixTimes* instructions.
  106. int2x3 q;
  107. // Note: The AST includes a MatrixSplat, therefore we splat the scalar to a matrix. So we cannot use OpVectorTimesScalar.
  108. // CHECK: [[t:%\d+]] = OpLoad %int %t
  109. // CHECK-NEXT: [[tvec:%\d+]] = OpCompositeConstruct %v3int [[t]] [[t]] [[t]]
  110. // CHECK-NEXT: [[tmat:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[tvec]] [[tvec]]
  111. // CHECK-NEXT: [[q:%\d+]] = OpLoad %_arr_v3int_uint_2 %q
  112. // CHECK-NEXT: [[tmat0:%\d+]] = OpCompositeExtract %v3int [[tmat]] 0
  113. // CHECK-NEXT: [[q0:%\d+]] = OpCompositeExtract %v3int [[q]] 0
  114. // CHECK-NEXT: [[qt0:%\d+]] = OpIMul %v3int [[tmat0]] [[q0]]
  115. // CHECK-NEXT: [[tmat1:%\d+]] = OpCompositeExtract %v3int [[tmat]] 1
  116. // CHECK-NEXT: [[q1:%\d+]] = OpCompositeExtract %v3int [[q]] 1
  117. // CHECK-NEXT: [[qt1:%\d+]] = OpIMul %v3int [[tmat1]] [[q1]]
  118. // CHECK-NEXT: [[qt:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[qt0]] [[qt1]]
  119. // CHECK-NEXT: OpStore %qt [[qt]]
  120. int2x3 qt = t * q;
  121. bool2x3 x;
  122. // Note: The AST includes a MatrixSplat, therefore we splat the scalar to a matrix. So we cannot use OpVectorTimesScalar.
  123. // CHECK: [[z:%\d+]] = OpLoad %bool %z
  124. // CHECK-NEXT: [[zint:%\d+]] = OpSelect %int [[z]] %int_1 %int_0
  125. // CHECK-NEXT: [[zvec:%\d+]] = OpCompositeConstruct %v3int [[zint]] [[zint]] [[zint]]
  126. // CHECK-NEXT: [[z_int_mat:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[zvec]] [[zvec]]
  127. // CHECK-NEXT: [[x:%\d+]] = OpLoad %_arr_v3bool_uint_2 %x
  128. // CHECK-NEXT: [[x0:%\d+]] = OpCompositeExtract %v3bool [[x]] 0
  129. // CHECK-NEXT: [[x0int:%\d+]] = OpSelect %v3int [[x0]] {{%\d+}} {{%\d+}}
  130. // CHECK-NEXT: [[x1:%\d+]] = OpCompositeExtract %v3bool [[x]] 1
  131. // CHECK-NEXT: [[x1int:%\d+]] = OpSelect %v3int [[x1]] {{%\d+}} {{%\d+}}
  132. // CHECK-NEXT: [[x_int_mat:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[x0int]] [[x1int]]
  133. // CHECK-NEXT: [[z0:%\d+]] = OpCompositeExtract %v3int [[z_int_mat]] 0
  134. // CHECK-NEXT: [[x0:%\d+]] = OpCompositeExtract %v3int [[x_int_mat]] 0
  135. // CHECK-NEXT: [[zx0:%\d+]] = OpIMul %v3int [[z0]] [[x0]]
  136. // CHECK-NEXT: [[z1:%\d+]] = OpCompositeExtract %v3int [[z_int_mat]] 1
  137. // CHECK-NEXT: [[x1:%\d+]] = OpCompositeExtract %v3int [[x_int_mat]] 1
  138. // CHECK-NEXT: [[zx1:%\d+]] = OpIMul %v3int [[z1]] [[x1]]
  139. // CHECK-NEXT: [[zx_int_mat:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2 [[zx0]] [[zx1]]
  140. // CHECK-NEXT: [[zx0:%\d+]] = OpCompositeExtract %v3int [[zx_int_mat]] 0
  141. // CHECK-NEXT: [[zx0bool:%\d+]] = OpINotEqual %v3bool [[zx0]] {{%\d+}}
  142. // CHECK-NEXT: [[zx1:%\d+]] = OpCompositeExtract %v3int [[zx_int_mat]] 1
  143. // CHECK-NEXT: [[zx1bool:%\d+]] = OpINotEqual %v3bool [[zx1]] {{%\d+}}
  144. // CHECK-NEXT: [[zx_bool_mat:%\d+]] = OpCompositeConstruct %_arr_v3bool_uint_2 [[zx0bool]] [[zx1bool]]
  145. // CHECK-NEXT: OpStore %zx [[zx_bool_mat]]
  146. bool z;
  147. bool2x3 zx = z * x;
  148. }