Fix #1360: uint->int width conversions must still be typed as uint.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 6d89109..ec1b530 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -190,7 +190,7 @@
glslang::TBasicType typeProxy);
spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand,
glslang::TBasicType typeProxy);
- spv::Id createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize);
+ spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize);
spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
@@ -4830,109 +4830,45 @@
return result;
}
-spv::Id TGlslangToSpvTraverser::createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize)
+// For converting integers where both the bitwidth and the signedness could
+// change, but only do the width change here. The caller is still responsible
+// for the signedness conversion.
+spv::Id TGlslangToSpvTraverser::createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize)
{
- spv::Op convOp = spv::OpNop;
- spv::Id type = 0;
-
- spv::Id result = 0;
-
+ // Get the result type width, based on the type to convert to.
+ int width = 32;
switch(op) {
+ case glslang::EOpConvInt16ToUint8:
+ case glslang::EOpConvIntToUint8:
+ case glslang::EOpConvInt64ToUint8:
+ case glslang::EOpConvUint16ToInt8:
+ case glslang::EOpConvUintToInt8:
+ case glslang::EOpConvUint64ToInt8:
+ width = 8;
+ break;
case glslang::EOpConvInt8ToUint16:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(16);
+ case glslang::EOpConvIntToUint16:
+ case glslang::EOpConvInt64ToUint16:
+ case glslang::EOpConvUint8ToInt16:
+ case glslang::EOpConvUintToInt16:
+ case glslang::EOpConvUint64ToInt16:
+ width = 16;
break;
case glslang::EOpConvInt8ToUint:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(32);
+ case glslang::EOpConvInt16ToUint:
+ case glslang::EOpConvInt64ToUint:
+ case glslang::EOpConvUint8ToInt:
+ case glslang::EOpConvUint16ToInt:
+ case glslang::EOpConvUint64ToInt:
+ width = 32;
break;
case glslang::EOpConvInt8ToUint64:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(64);
- break;
- case glslang::EOpConvInt16ToUint8:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(8);
- break;
- case glslang::EOpConvInt16ToUint:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(32);
- break;
case glslang::EOpConvInt16ToUint64:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(64);
- break;
- case glslang::EOpConvIntToUint8:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(8);
- break;
- case glslang::EOpConvIntToUint16:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(16);
- break;
case glslang::EOpConvIntToUint64:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(64);
- break;
- case glslang::EOpConvInt64ToUint8:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(8);
- break;
- case glslang::EOpConvInt64ToUint16:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(16);
- break;
- case glslang::EOpConvInt64ToUint:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(32);
- break;
- case glslang::EOpConvUint8ToInt16:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(16);
- break;
- case glslang::EOpConvUint8ToInt:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(32);
- break;
case glslang::EOpConvUint8ToInt64:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(64);
- break;
- case glslang::EOpConvUint16ToInt8:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(8);
- break;
- case glslang::EOpConvUint16ToInt:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(32);
- break;
case glslang::EOpConvUint16ToInt64:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(64);
- break;
- case glslang::EOpConvUintToInt8:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(8);
- break;
- case glslang::EOpConvUintToInt16:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(16);
- break;
case glslang::EOpConvUintToInt64:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(64);
- break;
- case glslang::EOpConvUint64ToInt8:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(8);
- break;
- case glslang::EOpConvUint64ToInt16:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(16);
- break;
- case glslang::EOpConvUint64ToInt:
- convOp = spv::OpUConvert;
- type = builder.makeIntType(32);
+ width = 64;
break;
default:
@@ -4940,11 +4876,36 @@
break;
}
+ // Get the conversion operation and result type,
+ // based on the target width, but the source type.
+ spv::Id type = spv::NoType;
+ spv::Op convOp = spv::OpNop;
+ switch(op) {
+ case glslang::EOpConvInt8ToUint16:
+ case glslang::EOpConvInt8ToUint:
+ case glslang::EOpConvInt8ToUint64:
+ case glslang::EOpConvInt16ToUint8:
+ case glslang::EOpConvInt16ToUint:
+ case glslang::EOpConvInt16ToUint64:
+ case glslang::EOpConvIntToUint8:
+ case glslang::EOpConvIntToUint16:
+ case glslang::EOpConvIntToUint64:
+ case glslang::EOpConvInt64ToUint8:
+ case glslang::EOpConvInt64ToUint16:
+ case glslang::EOpConvInt64ToUint:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(width);
+ break;
+ default:
+ convOp = spv::OpUConvert;
+ type = builder.makeUintType(width);
+ break;
+ }
+
if (vectorSize > 0)
type = builder.makeVectorType(type, vectorSize);
- result = builder.createUnaryOp(convOp, type, operand);
- return result;
+ return builder.createUnaryOp(convOp, type, operand);
}
spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecorations& decorations, spv::Id destType,
@@ -5219,7 +5180,7 @@
case glslang::EOpConvUint64ToInt16:
case glslang::EOpConvUint64ToInt:
// OpSConvert/OpUConvert + OpBitCast
- operand = createConversionOperation(op, operand, vectorSize);
+ operand = createIntWidthConversion(op, operand, vectorSize);
if (builder.isInSpecConstCodeGenMode()) {
// Build zero scalar or vector for OpIAdd.