Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions source/slang/slang-emit-spirv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7308,11 +7308,9 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
// Perform unsigned conversion first to an unsigned integer of the same width as the
// result then perform bit cast to the signed result type. This is done because SPIRV's
// unsigned conversion (`OpUConvert`) requires result type to be unsigned.
auto unsignedV = emitOpUConvert(
parent,
nullptr,
builder.getType(getOppositeSignIntTypeOp(toType->getOp())),
inst->getOperand(0));
auto builderType = getUnsignedTypeFromSignedType(&builder, toTypeV);

auto unsignedV = emitOpUConvert(parent, nullptr, builderType, inst->getOperand(0));
return emitOpBitcast(parent, inst, toTypeV, unsignedV);
}
else if (fromInfo.isSigned)
Expand Down
39 changes: 39 additions & 0 deletions source/slang/slang-ir-util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2348,6 +2348,45 @@ bool isInstHoistable(IROp op, IRType* type, IRInst* const* fixedArgs)
isSpecConstOpHoistable(op, type, fixedArgs);
}

IRType* getUnsignedTypeFromSignedType(IRBuilder* builder, IRType* type)
{
SLANG_RELEASE_ASSERT(isSignedType(type));

auto elementType = getVectorOrCoopMatrixElementType(type);

IROp op = type->getOp();
switch (op)
{
case kIROp_MatrixType:
{
auto unsignedTypeOp = getOppositeSignIntTypeOp(elementType->getOp());
auto matType = as<IRMatrixType>(type);
SLANG_RELEASE_ASSERT(matType);
return builder->getMatrixType(
builder->getType(unsignedTypeOp),
matType->getRowCount(),
matType->getColumnCount(),
matType->getLayout());
}
case kIROp_VectorType:
{
auto unsignedTypeOp = getOppositeSignIntTypeOp(elementType->getOp());
auto vecType = as<IRVectorType>(type);
SLANG_RELEASE_ASSERT(vecType);
return builder->getVectorType(
builder->getType(unsignedTypeOp),
vecType->getElementCount());
}
case kIROp_IntType:
case kIROp_Int16Type:
case kIROp_Int64Type:
case kIROp_Int8Type:
return builder->getType(getOppositeSignIntTypeOp(elementType->getOp()));
default:
return type;
}
}

bool isSignedType(IRType* type)
{
switch (type->getOp())
Expand Down
2 changes: 2 additions & 0 deletions source/slang/slang-ir-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,8 @@ constexpr bool anyOf(Range&& range, Predicate&& pred)
return false;
}

IRType* getUnsignedTypeFromSignedType(IRBuilder* builder, IRType* type);

bool isSignedType(IRType* type);
} // namespace Slang

Expand Down
20 changes: 20 additions & 0 deletions tests/spirv/uconvert-vector-typecheck.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//TEST:SIMPLE(filecheck=CHECK): -target spirv

// CHECK: %[[PTR:[0-9a-zA-Z_]+]] = OpVectorShuffle %v2uint %{{.*}} %{{.*}} 0 1
// CHECK: %{{.*}} = OpUConvert %v2ushort %[[PTR]]

RWTexture2D<uint> tex;

void writeFlags(int2 position, RWTexture2D<uint> flagsTexture, uint flags)
{
flagsTexture[position] = flags;
}

[shader("compute")]
[numthreads(1,1,1)]
void main(uint3 threadId : SV_DispatchThreadID)
{
uint16_t2 position = uint16_t2(threadId.xy);
uint flags = 1;
writeFlags(position, tex, flags);
}
Loading