summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-ir-util.cpp
diff options
context:
space:
mode:
authorDarren Wihandi <65404740+fairywreath@users.noreply.github.com>2025-05-30 01:04:27 -0400
committerGitHub <noreply@github.com>2025-05-29 22:04:27 -0700
commitaa3e6bdbe024355b07f6a61806024b248528fe4b (patch)
tree3f11539df4dfd0dfcb7df2b4e7ce877ab9b84179 /source/slang/slang-ir-util.cpp
parent61f66c116ab10fdfd37492056aab7dfa4276a0b7 (diff)
Fix SPIRV `OpSpecConstantOp` emit (#7158)
* Fix SPIRV specialization constant with floating-point operations * Improve test * WIP * Restrict `OpSpecConstantOp` allowed operations based on SPIRV specifications * Fix typo on floating type check * Emit error on float to int spec cosnt int val casts
Diffstat (limited to 'source/slang/slang-ir-util.cpp')
-rw-r--r--source/slang/slang-ir-util.cpp62
1 files changed, 39 insertions, 23 deletions
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index c8faec73b..13742711c 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -2276,8 +2276,14 @@ IRType* maybeAddRateType(IRBuilder* builder, IRType* rateQulifiedType, IRType* o
return oldType;
}
-bool isArithmeticInst(IROp op)
+bool canOperationBeSpecConst(IROp op, IRType* resultType, IRInst* const* fixedArgs, IRUse* operands)
{
+ // Returns true for ops that can be declared as an operation under `OpSpecConstantOp`.
+ //
+ // Integer arithmetic and comparison operations can be `OpSpecConstantOp` with the `Shader`
+ // capability, while floating-point arithmetic and comparison operations require the `Kernel`
+ // capability. We only support `Shader` capability for now, return false when floating-point
+ // arithmetic/comparison is encountered.
switch (op)
{
case kIROp_Add:
@@ -2285,51 +2291,61 @@ bool isArithmeticInst(IROp op)
case kIROp_Mul:
case kIROp_Div:
case kIROp_Neg:
- case kIROp_Not:
+ return !isFloatingType(resultType);
+
case kIROp_Eql:
case kIROp_Neq:
case kIROp_Leq:
case kIROp_Geq:
case kIROp_Less:
- case kIROp_IRem:
- case kIROp_FRem:
case kIROp_Greater:
+ {
+ IRInst* operand1;
+ IRInst* operand2;
+ if (fixedArgs)
+ {
+ operand1 = fixedArgs[0];
+ operand2 = fixedArgs[1];
+ }
+ else
+ {
+ operand1 = operands[0].get();
+ operand2 = operands[1].get();
+ }
+ return !isFloatingType(operand1->getDataType()) &&
+ !isFloatingType(operand2->getDataType());
+ }
+
+ case kIROp_Not:
+ case kIROp_IRem:
case kIROp_Lsh:
case kIROp_Rsh:
case kIROp_BitAnd:
case kIROp_BitOr:
case kIROp_BitXor:
case kIROp_BitNot:
- case kIROp_BitCast:
- case kIROp_CastIntToFloat:
- case kIROp_CastFloatToInt:
case kIROp_IntCast:
case kIROp_FloatCast:
case kIROp_Select:
return true;
+
default:
return false;
}
}
-bool isArithmeticInst(IRInst* inst)
+
+bool isSpecConstOpHoistable(IROp op, IRType* type, IRInst* const* fixedArgs)
{
- return isArithmeticInst(inst->getOp());
+ auto rateType = as<IRRateQualifiedType>(type);
+ return rateType && as<IRSpecConstRate>(rateType->getRate()) &&
+ canOperationBeSpecConst(op, rateType->getValueType(), fixedArgs, nullptr);
}
-bool isInstHoistable(IROp op, IRType* type)
-{
- if ((getIROpInfo(op).flags & kIROpFlag_Hoistable))
- {
- return true;
- }
- if (isArithmeticInst(op))
- {
- if (type && isSpecConstRateType(type))
- {
- return true;
- }
- }
- return false;
+bool isInstHoistable(IROp op, IRType* type, IRInst* const* fixedArgs)
+{
+ return (getIROpInfo(op).flags & kIROpFlag_Hoistable) ||
+ isSpecConstOpHoistable(op, type, fixedArgs);
}
+
} // namespace Slang