summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-util.cpp
diff options
context:
space:
mode:
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