@@ -9352,6 +9352,9 @@ SpirvEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
93529352 case hlsl::IntrinsicOp::IOP_printf:
93539353 retVal = processIntrinsicPrintf(callExpr);
93549354 break;
9355+ case hlsl::IntrinsicOp::IOP_usign:
9356+ retVal = processIntrinsicSignUnsignedInt(callExpr);
9357+ break;
93559358 case hlsl::IntrinsicOp::IOP_sign: {
93569359 if (isFloatOrVecMatOfFloatType(callExpr->getArg(0)->getType()))
93579360 retVal = processIntrinsicFloatSign(callExpr);
@@ -12656,6 +12659,80 @@ SpirvEmitter::processIntrinsicSaturate(const CallExpr *callExpr) {
1265612659 return nullptr;
1265712660}
1265812661
12662+ SpirvInstruction *
12663+ SpirvEmitter::processIntrinsicSignUnsignedInt(const CallExpr *callExpr) {
12664+ const auto srcLoc = callExpr->getExprLoc();
12665+ const auto srcRange = callExpr->getSourceRange();
12666+
12667+ const Expr *firstArg = callExpr->getArg(0);
12668+ const QualType firstArgType = firstArg->getType();
12669+ auto elemType = QualType{};
12670+ uint32_t numRows;
12671+ uint32_t numCols;
12672+ uint32_t count;
12673+ bool isScalar =
12674+ isScalarType(firstArgType, &elemType) ||
12675+ (isVectorType(firstArgType, &elemType, &count) && count == 1) ||
12676+ (isMxNMatrix(firstArgType, &elemType, &numRows, &numCols) &&
12677+ (numRows == 1 && numCols == 1));
12678+
12679+ auto *zero = getValueZero(astContext.IntTy);
12680+ auto *one = getValueOne(astContext.IntTy);
12681+ if (isScalar) {
12682+ auto *argVal = doExpr(callExpr->getArg(0));
12683+ auto *zeroUint = getValueZero(callExpr->getArg(0)->getType());
12684+ auto *cmp =
12685+ spvBuilder.createBinaryOp(spv::Op::OpUGreaterThan, astContext.BoolTy,
12686+ argVal, zeroUint, srcLoc, srcRange);
12687+ return spvBuilder.createSelect(astContext.IntTy, cmp, one, zero, srcLoc,
12688+ srcRange);
12689+ }
12690+
12691+ uint32_t size;
12692+ if (isVectorType(firstArgType)) {
12693+ size = count;
12694+ } else if (is1xNMatrix(firstArgType)) {
12695+ size = numCols;
12696+ } else if (isMx1Matrix(firstArgType)) {
12697+ size = numRows;
12698+ } else {
12699+ size = numRows;
12700+ }
12701+
12702+ const auto actOnEachVec = [this, srcLoc, srcRange, zero, one, elemType,
12703+ size](uint32_t index, QualType inType,
12704+ QualType outType, SpirvInstruction *curRow) {
12705+ auto zeroUint = getValueZero(elemType);
12706+ // Create `size` vector of uint zeros.
12707+ auto *zerosUint = spvBuilder.getConstantComposite(
12708+ astContext.getExtVectorType(elemType, size),
12709+ std::vector<clang::spirv::SpirvConstant *>(size, zeroUint));
12710+ // Compare if they are greater than zero.
12711+ auto *cmp = spvBuilder.createBinaryOp(
12712+ spv::Op::OpUGreaterThan,
12713+ astContext.getExtVectorType(astContext.BoolTy, size), curRow, zerosUint,
12714+ srcLoc, srcRange);
12715+
12716+ // Create a vector of int ones and zeros.
12717+ auto *zeros = spvBuilder.getConstantComposite(
12718+ astContext.getExtVectorType(astContext.IntTy, size),
12719+ std::vector<clang::spirv::SpirvConstant *>(size, zero));
12720+ auto *ones = spvBuilder.getConstantComposite(
12721+ astContext.getExtVectorType(astContext.IntTy, size),
12722+ std::vector<clang::spirv::SpirvConstant *>(size, one));
12723+ // Select between ones and zeros based on the comparison.
12724+ return spvBuilder.createSelect(
12725+ astContext.getExtVectorType(astContext.IntTy, size), cmp, ones, zeros,
12726+ srcLoc, srcRange);
12727+ };
12728+
12729+ if (isVectorType(firstArgType)) {
12730+ return actOnEachVec(0, firstArgType, callExpr->getType(), doExpr(firstArg));
12731+ }
12732+ return processEachVectorInMatrix(firstArg, doExpr(firstArg), actOnEachVec,
12733+ srcLoc, srcRange);
12734+ }
12735+
1265912736SpirvInstruction *
1266012737SpirvEmitter::processIntrinsicFloatSign(const CallExpr *callExpr) {
1266112738 // Import the GLSL.std.450 extended instruction set.
0 commit comments