summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--prelude/slang-cpp-types.h3
-rw-r--r--source/slang/slang-emit-c-like.cpp8
-rw-r--r--source/slang/slang-emit-c-like.h1
-rw-r--r--source/slang/slang-emit-cpp.cpp163
-rw-r--r--source/slang/slang-emit-cpp.h7
-rw-r--r--source/slang/slang-emit-cuda.cpp7
-rw-r--r--source/slang/slang-hlsl-intrinsic-set.cpp50
-rw-r--r--source/slang/slang-hlsl-intrinsic-set.h8
-rw-r--r--tests/hlsl-intrinsic/matrix-int-runtime-index.slang37
-rw-r--r--tests/hlsl-intrinsic/matrix-int-runtime-index.slang.expected.txt4
-rw-r--r--tests/hlsl-intrinsic/matrix-int.slang46
-rw-r--r--tests/hlsl-intrinsic/matrix-int.slang.expected.txt4
-rw-r--r--tests/hlsl-intrinsic/vector-int-runtime-index.slang46
-rw-r--r--tests/hlsl-intrinsic/vector-int-runtime-index.slang.expected.txt4
-rw-r--r--tests/hlsl-intrinsic/vector-int.slang21
15 files changed, 323 insertions, 86 deletions
diff --git a/prelude/slang-cpp-types.h b/prelude/slang-cpp-types.h
index a7ecf5991..67db607f6 100644
--- a/prelude/slang-cpp-types.h
+++ b/prelude/slang-cpp-types.h
@@ -82,9 +82,6 @@ typedef Vector<uint32_t, 4> uint4;
template <typename T, int ROWS, int COLS>
struct Matrix
{
- Vector<T, COLS>& operator[](int i) { SLANG_PRELUDE_ASSERT(i >= 0 && i < ROWS); return rows[i]; }
- const Vector<T, COLS>& operator[](int i) const { SLANG_PRELUDE_ASSERT(i >= 0 && i < ROWS); return rows[i]; }
-
Vector<T, COLS> rows[ROWS];
};
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index ae6becf0f..10790567e 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -1114,7 +1114,13 @@ IRTargetIntrinsicDecoration* CLikeSourceEmitter::findTargetIntrinsicDecoration(I
return true;
}
-void CLikeSourceEmitter::emitIntrinsicCallExpr(
+
+void CLikeSourceEmitter::emitIntrinsicCallExpr(IRCall* inst, IRTargetIntrinsicDecoration* targetIntrinsic, EmitOpInfo const& inOuterPrec)
+{
+ emitIntrinsicCallExprImpl(inst, targetIntrinsic, inOuterPrec);
+}
+
+void CLikeSourceEmitter::emitIntrinsicCallExprImpl(
IRCall* inst,
IRTargetIntrinsicDecoration* targetIntrinsic,
EmitOpInfo const& inOuterPrec)
diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h
index a6c48dc73..611678865 100644
--- a/source/slang/slang-emit-c-like.h
+++ b/source/slang/slang-emit-c-like.h
@@ -327,6 +327,7 @@ public:
virtual void emitSimpleFuncImpl(IRFunc* func);
virtual void emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPrec);
virtual void emitParamTypeImpl(IRType* type, String const& name);
+ virtual void emitIntrinsicCallExprImpl(IRCall* inst, IRTargetIntrinsicDecoration* targetIntrinsic, EmitOpInfo const& inOuterPrec);
// Only needed for glsl output with $ prefix intrinsics - so perhaps removable in the future
virtual void emitTextureOrTextureSamplerTypeImpl(IRTextureTypeBase* type, char const* baseName) { SLANG_UNUSED(type); SLANG_UNUSED(baseName); }
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 5dd028182..5ea3c72a2 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -544,6 +544,14 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
void CPPSourceEmitter::useType(IRType* type)
{
+ if (type->op == kIROp_PtrType)
+ {
+ // TODO(JS):
+ // If it's a pointer type we ignore. We may want to strip but in practice it's
+ // probably not necessary.
+ return;
+ }
+
_getTypeName(type);
}
@@ -969,33 +977,52 @@ void CPPSourceEmitter::_emitGetAtDefinition(const UnownedStringSlice& funcName,
IRType* srcType = funcType->getParamType(0);
- emitSpecializedOperationDefinitionPreamble(specOp);
+ for (Index i = 0; i < 2; ++i)
+ {
+ UnownedStringSlice typePrefix = (i == 0) ? UnownedStringSlice::fromLiteral("const ") : UnownedStringSlice();
- IRType* retType = specOp->returnType;
- emitType(retType);
- m_writer->emit("& ");
+ emitSpecializedOperationDefinitionPreamble(specOp);
- writer->emit(funcName);
- writer->emit("(");
+ writer->emit(typePrefix);
+ emitType(specOp->returnType);
+ m_writer->emit("& ");
- emitType(funcType->getParamType(0));
- writer->emit("& a, ");
- emitType(funcType->getParamType(1));
- writer->emit(" b)\n{\n");
+ writer->emit(funcName);
+ writer->emit("(");
- writer->indent();
+ writer->emit(typePrefix);
+ emitType(funcType->getParamType(0));
+ writer->emit("& a, ");
+ emitType(funcType->getParamType(1));
+ writer->emit(" b)\n{\n");
- IRVectorType* vectorType = as<IRVectorType>(srcType);
- int vecSize = int(GetIntVal(vectorType->getElementCount()));
+ writer->indent();
- writer->emit("assert(b >= 0 && b < ");
- writer->emit(vecSize);
- writer->emit(");\n");
+ if (auto vectorType = as<IRVectorType>(srcType))
+ {
+ int vecSize = int(GetIntVal(vectorType->getElementCount()));
- writer->emit("return (&a.x)[b];\n");
+ writer->emit("assert(b >= 0 && b < ");
+ writer->emit(vecSize);
+ writer->emit(");\n");
- writer->dedent();
- writer->emit("}\n\n");
+ writer->emit("return (&a.x)[b];\n");
+ }
+ else if (auto matrixType = as<IRMatrixType>(srcType))
+ {
+ //int colCount = int(GetIntVal(matrixType->getColumnCount()));
+ int rowCount = int(GetIntVal(matrixType->getRowCount()));
+
+ writer->emit("assert(b >= 0 && b < ");
+ writer->emit(rowCount);
+ writer->emit(");\n");
+
+ writer->emit("return a.rows[b];\n");
+ }
+
+ writer->dedent();
+ writer->emit("}\n\n");
+ }
}
void CPPSourceEmitter::_emitNormalizeDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
@@ -1549,11 +1576,6 @@ SlangResult CPPSourceEmitter::calcFuncName(const HLSLIntrinsic* specOp, StringBu
outBuilder << "getAt";
return SLANG_OK;
}
- case Op::SetAt:
- {
- outBuilder << "setAt";
- return SLANG_OK;
- }
default: break;
}
@@ -1810,7 +1832,7 @@ void CPPSourceEmitter::emitTypeImpl(IRType* type, const StringSliceLoc* nameLoc)
}
}
-void CPPSourceEmitter::emitIntrinsicCallExpr(
+void CPPSourceEmitter::emitIntrinsicCallExprImpl(
IRCall* inst,
IRTargetIntrinsicDecoration* targetIntrinsic,
EmitOpInfo const& inOuterPrec)
@@ -1826,13 +1848,9 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(
auto outerPrec = inOuterPrec;
bool needClose = false;
- // For a call with N arguments, the instruction will
- // have N+1 operands. We will start consuming operands
- // starting at the index 1.
- UInt operandCount = inst->getOperandCount();
- UInt operandIndex = 1;
-
-
+ Index argCount = Index(inst->getArgCount());
+ auto args = inst->getArgs();
+
auto name = targetIntrinsic->getDefinition();
// We will special-case some names here, that
@@ -1841,23 +1859,56 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(
// syntax.
if (name == ".operator[]")
{
- // The user is invoking a built-in subscript operator
+ SLANG_ASSERT(argCount == 2 || argCount == 3);
+
+ // If the first item is either a matrix or a vector, we use 'getAt' logic
+ IRType* targetType = args[0].get()->getDataType();
+ if (targetType->op == kIROp_VectorType || targetType->op == kIROp_MatrixType)
+ {
+ // Work out the intrinsic used
+ HLSLIntrinsic intrinsic;
+ m_intrinsicSet.calcIntrinsic(HLSLIntrinsic::Op::GetAt, inst->getDataType(), args, 2, intrinsic);
+ HLSLIntrinsic* specOp = m_intrinsicSet.add(intrinsic);
+
+ if (argCount == 2)
+ {
+ // Load
+ emitCall(specOp, inst, args, 2, inOuterPrec);
+ }
+ else
+ {
+ // Store
+ auto prec = getInfo(EmitOp::Postfix);
+ needClose = maybeEmitParens(outerPrec, prec);
- auto prec = getInfo(EmitOp::Postfix);
- needClose = maybeEmitParens(outerPrec, prec);
+ emitCall(specOp, inst, inst->getOperands(), 2, inOuterPrec);
- emitOperand(inst->getOperand(operandIndex++), leftSide(outerPrec, prec));
- m_writer->emit("[");
- emitOperand(inst->getOperand(operandIndex++), getInfo(EmitOp::General));
- m_writer->emit("]");
+ m_writer->emit(" = ");
+ emitOperand(inst->getOperand(2), getInfo(EmitOp::General));
- if (operandIndex < operandCount)
+ maybeCloseParens(needClose);
+ }
+ }
+ else
{
- m_writer->emit(" = ");
- emitOperand(inst->getOperand(operandIndex++), getInfo(EmitOp::General));
+ // The user is invoking a built-in subscript operator
+ auto prec = getInfo(EmitOp::Postfix);
+ needClose = maybeEmitParens(outerPrec, prec);
+
+ emitOperand(args[0].get(), leftSide(outerPrec, prec));
+ m_writer->emit("[");
+ emitOperand(args[1].get(), getInfo(EmitOp::General));
+ m_writer->emit("]");
+
+ if (argCount == 3)
+ {
+ m_writer->emit(" = ");
+ emitOperand(args[2].get(), getInfo(EmitOp::General));
+ }
+
+ maybeCloseParens(needClose);
}
- maybeCloseParens(needClose);
return;
}
@@ -1867,37 +1918,39 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(
if (name[0] == '.')
{
// Looks like a member function call
- emitOperand(inst->getOperand(operandIndex), leftSide(outerPrec, prec));
+ emitOperand(args[0].get(), leftSide(outerPrec, prec));
m_writer->emit(".");
- name = UnownedStringSlice(name.begin()+1, name.end());
- operandIndex++;
+ name = UnownedStringSlice(name.begin() + 1, name.end());
+
+ args++;
+ argCount--;
}
else
{
Op op = m_opLookup->getOpByName(name);
if (op != Op::Invalid)
{
- IRUse* operands = inst->getOperands() + operandIndex;
-
+
// Work out the intrinsic used
HLSLIntrinsic intrinsic;
- m_intrinsicSet.calcIntrinsic(op, inst->getDataType(), operands, int(operandCount - operandIndex), intrinsic);
+ m_intrinsicSet.calcIntrinsic(op, inst->getDataType(), args, argCount, intrinsic);
HLSLIntrinsic* specOp = m_intrinsicSet.add(intrinsic);
- emitCall(specOp, inst, operands, int(operandCount - operandIndex), inOuterPrec);
+ emitCall(specOp, inst, args, int(argCount), inOuterPrec);
return;
}
}
m_writer->emit(name);
m_writer->emit("(");
- bool first = true;
- for (; operandIndex < operandCount; ++operandIndex)
+ for (Index i = 0; i < argCount; ++i)
{
- if (!first) m_writer->emit(", ");
- emitOperand(inst->getOperand(operandIndex), getInfo(EmitOp::General));
- first = false;
+ if (i != 0)
+ {
+ m_writer->emit(", ");
+ }
+ emitOperand(args[i].get(), getInfo(EmitOp::General));
}
m_writer->emit(")");
maybeCloseParens(needClose);
diff --git a/source/slang/slang-emit-cpp.h b/source/slang/slang-emit-cpp.h
index 12bc0939e..9ea083199 100644
--- a/source/slang/slang-emit-cpp.h
+++ b/source/slang/slang-emit-cpp.h
@@ -77,6 +77,8 @@ protected:
virtual void emitParamTypeImpl(IRType* type, String const& name) SLANG_OVERRIDE;
virtual bool tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType) SLANG_OVERRIDE;
+ virtual void emitIntrinsicCallExprImpl(IRCall* inst, IRTargetIntrinsicDecoration* targetIntrinsic, EmitOpInfo const& inOuterPrec) SLANG_OVERRIDE;
+
// Replaceable for classes derived from CPPSourceEmitter
virtual SlangResult calcTypeName(IRType* type, CodeGenTarget target, StringBuilder& out);
@@ -87,11 +89,6 @@ protected:
void _maybeEmitSpecializedOperationDefinition(const HLSLIntrinsic* specOp);
- void emitIntrinsicCallExpr(
- IRCall* inst,
- IRTargetIntrinsicDecoration* targetIntrinsic,
- EmitOpInfo const& inOuterPrec);
-
void _emitForwardDeclarations(const List<EmitAction>& actions);
void _calcGlobalParams(const List<EmitAction>& actions, List<GlobalParamInfo>& outParams, IRGlobalParam** outEntryPointGlobalParams);
void _emitUniformStateMembers(const List<EmitAction>& actions, IRGlobalParam** outEntryPointGlobalParams);
diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp
index c72b9125a..93508813b 100644
--- a/source/slang/slang-emit-cuda.cpp
+++ b/source/slang/slang-emit-cuda.cpp
@@ -219,6 +219,13 @@ SlangResult CUDASourceEmitter::calcScalarFuncName(HLSLIntrinsic::Op op, IRBasicT
SlangResult CUDASourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, StringBuilder& out)
{
SLANG_UNUSED(target);
+
+ if (target == CodeGenTarget::CSource)
+ {
+ return Super::calcTypeName(type, target, out);
+ }
+
+ // We allow C source, because if we need a name
SLANG_ASSERT(target == CodeGenTarget::CUDASource);
switch (type->op)
diff --git a/source/slang/slang-hlsl-intrinsic-set.cpp b/source/slang/slang-hlsl-intrinsic-set.cpp
index 9bc7e7d54..1f42836f3 100644
--- a/source/slang/slang-hlsl-intrinsic-set.cpp
+++ b/source/slang/slang-hlsl-intrinsic-set.cpp
@@ -55,6 +55,35 @@ void HLSLIntrinsicSet::_calcIntrinsic(HLSLIntrinsic::Op op, IRType* returnType,
switch (op)
{
+ case Op::GetAt:
+ {
+ IRType* argTypes[3];
+
+ SLANG_ASSERT(argsCount == 2 || argsCount == 3);
+ // TODO(JS):
+ // HACK! GetAt can be from getElementPtr or from getElement. Get element ptr means the return type will be
+ // a pointer. We don't want to deal with that, so strip it
+ if (returnType->op == kIROp_PtrType)
+ {
+ returnType = as<IRType>(returnType->getOperand(0));
+ }
+
+ // TODO(JS): Similarly for the input parameters
+ for (Index i = 0; i < argsCount; ++i)
+ {
+ IRType* argType = inArgs[i];
+
+ if (argType->op == kIROp_PtrType)
+ {
+ argType = as<IRType>(argType->getOperand(0));
+ }
+ argTypes[i] = argType;
+ }
+
+ out.returnType = returnType;
+ out.signatureType = builder.getFuncType(argsCount, argTypes, builder.getVoidType());
+ break;
+ }
case Op::ConstructFromScalar:
{
//SLANG_ASSERT(argsCount == 1);
@@ -269,10 +298,10 @@ SlangResult HLSLIntrinsicSet::makeIntrinsic(IRInst* inst, HLSLIntrinsic& out)
break;
}
case kIROp_getElement:
- case kIROp_getElementPtr:
{
IRInst* target = inst->getOperand(0);
- if (target->getDataType()->op == kIROp_VectorType)
+ IRType* targetType = target->getDataType();
+ if (targetType->op == kIROp_VectorType || targetType->op == kIROp_MatrixType)
{
// Specially handle this
calcIntrinsic(Op::GetAt, inst, out);
@@ -280,6 +309,23 @@ SlangResult HLSLIntrinsicSet::makeIntrinsic(IRInst* inst, HLSLIntrinsic& out)
}
break;
}
+ case kIROp_getElementPtr:
+ {
+ IRInst* target = inst->getOperand(0);
+ IRType* targetType = target->getDataType();
+
+ if (auto ptrType = as<IRPtrType>(targetType))
+ {
+ targetType = as<IRType>(ptrType->getOperand(0));
+ if (targetType->op == kIROp_VectorType || targetType->op == kIROp_MatrixType)
+ {
+ // Specially handle this
+ calcIntrinsic(Op::GetAt, inst, out);
+ return SLANG_OK;
+ }
+ }
+ break;
+ }
case kIROp_Call:
{
IRCall* callInst = (IRCall*)inst;
diff --git a/source/slang/slang-hlsl-intrinsic-set.h b/source/slang/slang-hlsl-intrinsic-set.h
index df1677b17..17e88fc9a 100644
--- a/source/slang/slang-hlsl-intrinsic-set.h
+++ b/source/slang/slang-hlsl-intrinsic-set.h
@@ -123,7 +123,6 @@ just constructXXXFromScalar. Would be good if there was a suitable name to encom
x(ConstructFromScalar, "", 1) \
\
x(GetAt, "", 2) \
- x(SetAt, "", 3) \
\
x(CountBits, "countbits", 1)
@@ -153,6 +152,13 @@ struct HLSLIntrinsic
for (Index i = 0; i < paramCount; ++i)
{
IRType* paramType = signatureType->getParamType(i);
+
+ // Strip off ptr if it's an operand type
+ if (paramType->op == kIROp_PtrType)
+ {
+ paramType = as<IRType>(paramType->getOperand(0));
+ }
+
// If any are vec or matrix, then we
if (paramType->op == kIROp_MatrixType || paramType->op == kIROp_VectorType)
{
diff --git a/tests/hlsl-intrinsic/matrix-int-runtime-index.slang b/tests/hlsl-intrinsic/matrix-int-runtime-index.slang
new file mode 100644
index 000000000..e3e2733b7
--- /dev/null
+++ b/tests/hlsl-intrinsic/matrix-int-runtime-index.slang
@@ -0,0 +1,37 @@
+// NOTE we can't test on VK/gl because we will output imat3 - and imat3 is not supported by glsl.
+// NOTE we also can't do this test on fxc - as it does not allow runtime non constant indexing.
+
+//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute
+//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil
+//DISABLE_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-cuda -compute
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+int horizontalAdd(int3 v) { return v.x + v.y + v.z; }
+
+[numthreads(4, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ int idx = int(dispatchThreadID.x);
+
+ matrix<int, 3, 3> a = { { 0, 1, 2}, {2, 4, 6}, {7, 21, 32}};
+ matrix<int, 3, 3> b = { { 4, 9, -1}, {-2, 4, 2}, {31, -3, 7}};
+
+ // Do a dynamic row swap
+ {
+ matrix<int, 3, 3> c = a;
+
+ int row0 = idx % 3;
+ int row1 = (idx + 1) % 3;
+ int row2 = (idx + 2) % 3;
+
+ a[row0] = c[0];
+ a[row1] = c[1];
+ a[row2] = c[2];
+ }
+
+ outputBuffer[idx] = (a[0].x & 15) + ((a[1].x & 15) << 4) + ((a[2].x & 15) << 8);
+} \ No newline at end of file
diff --git a/tests/hlsl-intrinsic/matrix-int-runtime-index.slang.expected.txt b/tests/hlsl-intrinsic/matrix-int-runtime-index.slang.expected.txt
new file mode 100644
index 000000000..b31b447b8
--- /dev/null
+++ b/tests/hlsl-intrinsic/matrix-int-runtime-index.slang.expected.txt
@@ -0,0 +1,4 @@
+720
+207
+72
+720
diff --git a/tests/hlsl-intrinsic/matrix-int.slang b/tests/hlsl-intrinsic/matrix-int.slang
new file mode 100644
index 000000000..cd69156a7
--- /dev/null
+++ b/tests/hlsl-intrinsic/matrix-int.slang
@@ -0,0 +1,46 @@
+// NOTE we can't test on VK/gl at the moment because we don't support intrinsics over matrices on that target currently
+
+//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil
+//DISABLE_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-cuda -compute
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+int horizontalAdd(int3 v) { return v.x + v.y + v.z; }
+
+[numthreads(4, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ int idx = int(dispatchThreadID.x);
+
+ matrix<int, 3, 3> a = { { 0, 1, 2}, {2, 4, 6}, {16, 21, 32}};
+ matrix<int, 3, 3> b = { { 4, 9, -1}, {-2, 4, 2}, {31, -3, 7}};
+
+ matrix<int, 3, 3> t = {};
+
+ t += max(a, b);
+ t += min(a, b);
+ t += abs(a);
+ t += b % 5;
+
+ {
+ int3 low = int3(3 + idx * 1);
+ int3 high = int3(5 + idx * 2);
+
+ t += clamp(a, matrix<int, 3, 3>(low, low, low), matrix<int, 3, 3>(high, high, high));
+ }
+
+ // Access rows and elements, both read and write
+
+ a[0].x ++;
+ a[1][1] --;
+ a[0] = a[1];
+ a[2].y += b[1].x;
+
+ t += a;
+
+ outputBuffer[idx] = horizontalAdd(t[0]) + horizontalAdd(t[1]) + horizontalAdd(t[2]);
+} \ No newline at end of file
diff --git a/tests/hlsl-intrinsic/matrix-int.slang.expected.txt b/tests/hlsl-intrinsic/matrix-int.slang.expected.txt
new file mode 100644
index 000000000..ad9f3b0fb
--- /dev/null
+++ b/tests/hlsl-intrinsic/matrix-int.slang.expected.txt
@@ -0,0 +1,4 @@
+163
+16E
+179
+184
diff --git a/tests/hlsl-intrinsic/vector-int-runtime-index.slang b/tests/hlsl-intrinsic/vector-int-runtime-index.slang
new file mode 100644
index 000000000..bb704ed1a
--- /dev/null
+++ b/tests/hlsl-intrinsic/vector-int-runtime-index.slang
@@ -0,0 +1,46 @@
+//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute
+//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-cuda -compute
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+[numthreads(4, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ int idx = int(dispatchThreadID.x);
+
+ int3 a = { idx + 10, idx - 9, idx + 3};
+ int3 b = { idx * 2, idx * 3, idx * 10};
+
+ int3 t = { 0, 0, 0};
+
+ t += max(a, b);
+ t += min(a, b);
+ t += abs(a);
+ t += b % 5;
+
+ t += clamp(a, int3(10), int3(23));
+
+ // Swizzle
+ t += a.zyx;
+ // Swizzle from scalar
+ t += idx.xxx;
+
+ {
+ t += int3(a[idx % 3], a[0], b[2]);
+ }
+
+ // Writes
+ {
+ int3 v = int3(b[(idx + 1) % 3], b[(idx + 2) % 3], b[(idx + 3) % 3]);
+ v[1] += v[0];
+ v[idx & 1] += v[2];
+
+ t += v;
+ }
+
+ outputBuffer[idx] = t.x + t.y + t.z;
+} \ No newline at end of file
diff --git a/tests/hlsl-intrinsic/vector-int-runtime-index.slang.expected.txt b/tests/hlsl-intrinsic/vector-int-runtime-index.slang.expected.txt
new file mode 100644
index 000000000..1ff551cc3
--- /dev/null
+++ b/tests/hlsl-intrinsic/vector-int-runtime-index.slang.expected.txt
@@ -0,0 +1,4 @@
+50
+84
+D0
+103
diff --git a/tests/hlsl-intrinsic/vector-int.slang b/tests/hlsl-intrinsic/vector-int.slang
index 9a3f1faaa..d3327cfd0 100644
--- a/tests/hlsl-intrinsic/vector-int.slang
+++ b/tests/hlsl-intrinsic/vector-int.slang
@@ -1,6 +1,6 @@
//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
-//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil
//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-cuda -compute
@@ -28,23 +28,6 @@ void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
t += a.zyx;
// Swizzle from scalar
t += idx.xxx;
-
-#if 0
- // TODO(JS): On C++ not all accesses are turned into getAt/setAt, so disable for now.
- // Reads
- {
- t += int3(a[idx % 3], a[0], b[2]);
- }
-
- // Writes
- {
- int3 v = int3(b[(idx + 1) % 3], b[(idx + 2) % 3], b[(idx + 3) % 3]);
- v[1] += v[0];
- v[idx & 1] += v[2];
-
- t += v;
- }
-#endif
-
+
outputBuffer[idx] = t.x + t.y + t.z;
} \ No newline at end of file