diff options
| author | Darren Wihandi <65404740+fairywreath@users.noreply.github.com> | 2025-05-30 01:04:27 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-29 22:04:27 -0700 |
| commit | aa3e6bdbe024355b07f6a61806024b248528fe4b (patch) | |
| tree | 3f11539df4dfd0dfcb7df2b4e7ce877ab9b84179 /source/slang/slang-ir-util.cpp | |
| parent | 61f66c116ab10fdfd37492056aab7dfa4276a0b7 (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.cpp | 62 |
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 |
