summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorCopilot <198982749+Copilot@users.noreply.github.com>2025-07-11 22:27:28 +0000
committerGitHub <noreply@github.com>2025-07-11 22:27:28 +0000
commit704d0c7109cf066f4b311e55a141f117f76c0672 (patch)
tree21563ef0b6189cd2f9533c7fb043e2e1bbd1e61c /source
parent243f522a9087a807d2dadbb3ef201694b6897bf7 (diff)
Fix unnecessary Int64 SPIRV capability usage in pointer marshalling (#7717)
* Initial plan * Fix unnecessary Int64 SPIRV capability usage in pointer marshalling Replace uint64-based pointer marshalling with uint2-based approach to avoid requiring Int64 capability in SPIRV output. This affects both basic type marshalling and resource handle marshalling for pointer types. Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Replace test cases with user-provided test case Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> * Fix test case to avoid unrelated pointer casting operations that require Int64 Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com>
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-ir-any-value-marshalling.cpp88
1 files changed, 71 insertions, 17 deletions
diff --git a/source/slang/slang-ir-any-value-marshalling.cpp b/source/slang/slang-ir-any-value-marshalling.cpp
index ed5f8e4e4..18862313f 100644
--- a/source/slang/slang-ir-any-value-marshalling.cpp
+++ b/source/slang/slang-ir-any-value-marshalling.cpp
@@ -400,11 +400,6 @@ struct AnyValueMarshallingContext
case kIROp_UInt64Type:
case kIROp_Int64Type:
case kIROp_DoubleType:
- case kIROp_PtrType:
-#if SLANG_PTR_IS_64
- case kIROp_UIntPtrType:
- case kIROp_IntPtrType:
-#endif
ensureOffsetAt8ByteBoundary();
if (fieldOffset < static_cast<uint32_t>(anyValInfo->fieldKeys.getCount()))
{
@@ -434,6 +429,38 @@ struct AnyValueMarshallingContext
}
}
break;
+ case kIROp_PtrType:
+#if SLANG_PTR_IS_64
+ case kIROp_UIntPtrType:
+ case kIROp_IntPtrType:
+#endif
+ ensureOffsetAt8ByteBoundary();
+ if (fieldOffset < static_cast<uint32_t>(anyValInfo->fieldKeys.getCount()))
+ {
+ auto srcVal = builder->emitLoad(concreteVar);
+ // Use uint2 instead of uint64 to avoid Int64 capability requirement
+ auto uint2Type = builder->getVectorType(builder->getUIntType(), 2);
+ auto uint2Val = builder->emitBitCast(uint2Type, srcVal);
+ auto lowBits = builder->emitElementExtract(uint2Val, IRIntegerValue(0));
+ auto highBits = builder->emitElementExtract(uint2Val, IRIntegerValue(1));
+
+ auto dstAddr = builder->emitFieldAddress(
+ uintPtrType,
+ anyValueVar,
+ anyValInfo->fieldKeys[fieldOffset]);
+ builder->emitStore(dstAddr, lowBits);
+ fieldOffset++;
+ if (fieldOffset < static_cast<uint32_t>(anyValInfo->fieldKeys.getCount()))
+ {
+ dstAddr = builder->emitFieldAddress(
+ uintPtrType,
+ anyValueVar,
+ anyValInfo->fieldKeys[fieldOffset]);
+ builder->emitStore(dstAddr, highBits);
+ fieldOffset++;
+ }
+ }
+ break;
default:
SLANG_UNREACHABLE("unknown basic type");
}
@@ -449,13 +476,11 @@ struct AnyValueMarshallingContext
if (fieldOffset + 1 < static_cast<uint32_t>(anyValInfo->fieldKeys.getCount()))
{
auto srcVal = builder->emitLoad(concreteVar);
- auto uint64Val = builder->emitBitCast(builder->getUInt64Type(), srcVal);
- auto lowBits = builder->emitCast(builder->getUIntType(), uint64Val);
- auto shiftedBits = builder->emitShr(
- builder->getUInt64Type(),
- uint64Val,
- builder->getIntValue(builder->getIntType(), 32));
- auto highBits = builder->emitBitCast(builder->getUIntType(), shiftedBits);
+ // Use uint2 instead of uint64 to avoid Int64 capability requirement
+ auto uint2Type = builder->getVectorType(builder->getUIntType(), 2);
+ auto uint2Val = builder->emitBitCast(uint2Type, srcVal);
+ auto lowBits = builder->emitElementExtract(uint2Val, IRIntegerValue(0));
+ auto highBits = builder->emitElementExtract(uint2Val, IRIntegerValue(1));
auto dstAddr1 = builder->emitFieldAddress(
uintPtrType,
anyValueVar,
@@ -649,6 +674,30 @@ struct AnyValueMarshallingContext
case kIROp_UInt64Type:
case kIROp_Int64Type:
case kIROp_DoubleType:
+ ensureOffsetAt8ByteBoundary();
+ if (fieldOffset < static_cast<uint32_t>(anyValInfo->fieldKeys.getCount()))
+ {
+ auto srcAddr = builder->emitFieldAddress(
+ uintPtrType,
+ anyValueVar,
+ anyValInfo->fieldKeys[fieldOffset]);
+ auto lowBits = builder->emitLoad(srcAddr);
+ fieldOffset++;
+ if (fieldOffset < static_cast<uint32_t>(anyValInfo->fieldKeys.getCount()))
+ {
+ auto srcAddr1 = builder->emitFieldAddress(
+ uintPtrType,
+ anyValueVar,
+ anyValInfo->fieldKeys[fieldOffset]);
+ fieldOffset++;
+ auto highBits = builder->emitLoad(srcAddr1);
+ auto combinedBits = builder->emitMakeUInt64(lowBits, highBits);
+ if (dataType->getOp() != kIROp_UInt64Type)
+ combinedBits = builder->emitBitCast(dataType, combinedBits);
+ builder->emitStore(concreteVar, combinedBits);
+ }
+ }
+ break;
case kIROp_PtrType:
#if SLANG_PTR_IS_64
case kIROp_IntPtrType:
@@ -671,9 +720,11 @@ struct AnyValueMarshallingContext
anyValInfo->fieldKeys[fieldOffset]);
fieldOffset++;
auto highBits = builder->emitLoad(srcAddr1);
- auto combinedBits = builder->emitMakeUInt64(lowBits, highBits);
- if (dataType->getOp() != kIROp_UInt64Type)
- combinedBits = builder->emitBitCast(dataType, combinedBits);
+ // Use uint2 instead of uint64 to avoid Int64 capability requirement
+ auto uint2Type = builder->getVectorType(builder->getUIntType(), 2);
+ IRInst* components[2] = {lowBits, highBits};
+ auto uint2Val = builder->emitMakeVector(uint2Type, 2, components);
+ auto combinedBits = builder->emitBitCast(dataType, uint2Val);
builder->emitStore(concreteVar, combinedBits);
}
}
@@ -703,8 +754,11 @@ struct AnyValueMarshallingContext
anyValInfo->fieldKeys[fieldOffset + 1]);
auto highBits = builder->emitLoad(srcAddr1);
- auto combinedBits = builder->emitMakeUInt64(lowBits, highBits);
- combinedBits = builder->emitBitCast(dataType, combinedBits);
+ // Use uint2 instead of uint64 to avoid Int64 capability requirement
+ auto uint2Type = builder->getVectorType(builder->getUIntType(), 2);
+ IRInst* components[2] = {lowBits, highBits};
+ auto uint2Val = builder->emitMakeVector(uint2Type, 2, components);
+ auto combinedBits = builder->emitBitCast(dataType, uint2Val);
builder->emitStore(concreteVar, combinedBits);
advanceOffset(8);
}