summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-02-07 18:36:35 -0800
committerGitHub <noreply@github.com>2023-02-07 18:36:35 -0800
commit4be623c52a6518eb86756a0369706c1d6670f6bb (patch)
treec24f54e34db9f1f02c2d51808b15121eba9195a9
parent101f164b036d0c1c012243df69179559b6f40fb8 (diff)
Arithmetic simplifications and more IR clean up logic. (#2632)
-rw-r--r--build/visual-studio/slang/slang.vcxproj2
-rw-r--r--build/visual-studio/slang/slang.vcxproj.filters6
-rw-r--r--source/slang/hlsl.meta.slang8
-rw-r--r--source/slang/slang-ast-expr.h7
-rw-r--r--source/slang/slang-ast-support-types.h1
-rw-r--r--source/slang/slang-check-conversion.cpp62
-rw-r--r--source/slang/slang-check-expr.cpp1
-rw-r--r--source/slang/slang-check-impl.h1
-rw-r--r--source/slang/slang-emit-c-like.cpp37
-rw-r--r--source/slang/slang-emit-source-writer.cpp17
-rw-r--r--source/slang/slang-emit.cpp13
-rw-r--r--source/slang/slang-intrinsic-expand.cpp8
-rw-r--r--source/slang/slang-ir-autodiff-fwd.cpp2
-rw-r--r--source/slang/slang-ir-autodiff-rev.cpp71
-rw-r--r--source/slang/slang-ir-autodiff-unzip.cpp38
-rw-r--r--source/slang/slang-ir-autodiff.cpp5
-rw-r--r--source/slang/slang-ir-dce.cpp7
-rw-r--r--source/slang/slang-ir-inst-defs.h3
-rw-r--r--source/slang/slang-ir-insts.h9
-rw-r--r--source/slang/slang-ir-peephole.cpp158
-rw-r--r--source/slang/slang-ir-redundancy-removal.cpp92
-rw-r--r--source/slang/slang-ir-redundancy-removal.h2
-rw-r--r--source/slang/slang-ir-simplify-for-emit.cpp354
-rw-r--r--source/slang/slang-ir-simplify-for-emit.h9
-rw-r--r--source/slang/slang-ir-util.cpp211
-rw-r--r--source/slang/slang-ir-util.h9
-rw-r--r--source/slang/slang-ir.cpp24
-rw-r--r--source/slang/slang-ir.h9
-rw-r--r--source/slang/slang-lower-to-ir.cpp33
-rw-r--r--tests/compute/unbounded-array-of-array-syntax.slang.glsl12
-rw-r--r--tests/cross-compile/array-of-buffers.slang.glsl23
-rw-r--r--tests/cross-compile/array-of-buffers.slang.hlsl27
-rw-r--r--tests/cross-compile/dual-source-blending.slang.glsl8
-rw-r--r--tests/cross-compile/geometry-shader.slang.glsl17
-rw-r--r--tests/cross-compile/unknown-image-format.slang.glsl25
-rw-r--r--tests/cross-compile/vector-comparison.slang.glsl4
-rw-r--r--tests/experimental/liveness/liveness-3.slang.expected98
-rw-r--r--tests/experimental/liveness/liveness-4.slang.expected16
-rw-r--r--tests/experimental/liveness/liveness-5.slang.expected23
-rw-r--r--tests/experimental/liveness/liveness-6.slang.expected33
-rw-r--r--tests/experimental/liveness/liveness.slang.expected25
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected18
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected35
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected15
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected44
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected23
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected23
-rw-r--r--tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl29
-rw-r--r--tests/pipeline/rasterization/mesh/hello.slang.glsl10
-rw-r--r--tests/pipeline/rasterization/mesh/hello.slang.hlsl12
-rw-r--r--tests/pipeline/rasterization/mesh/hlsl-syntax.slang.glsl10
-rw-r--r--tests/pipeline/rasterization/mesh/passing-outputs.slang.glsl131
-rw-r--r--tests/pipeline/rasterization/mesh/primitive-output.slang.glsl12
-rw-r--r--tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl38
54 files changed, 1450 insertions, 460 deletions
diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj
index 00b7076dd..979ee4e96 100644
--- a/build/visual-studio/slang/slang.vcxproj
+++ b/build/visual-studio/slang/slang.vcxproj
@@ -414,6 +414,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClInclude Include="..\..\..\source\slang\slang-ir-restructure.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-sccp.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-simplify-cfg.h" />
+ <ClInclude Include="..\..\..\source\slang\slang-ir-simplify-for-emit.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-single-return.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-specialize-arrays.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-specialize-buffer-load-arg.h" />
@@ -599,6 +600,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClCompile Include="..\..\..\source\slang\slang-ir-restructure.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-sccp.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-simplify-cfg.cpp" />
+ <ClCompile Include="..\..\..\source\slang\slang-ir-simplify-for-emit.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-single-return.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-specialize-arrays.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-specialize-buffer-load-arg.cpp" />
diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters
index f79d322ae..e151f6c4f 100644
--- a/build/visual-studio/slang/slang.vcxproj.filters
+++ b/build/visual-studio/slang/slang.vcxproj.filters
@@ -348,6 +348,9 @@
<ClInclude Include="..\..\..\source\slang\slang-ir-simplify-cfg.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\slang\slang-ir-simplify-for-emit.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-ir-single-return.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -899,6 +902,9 @@
<ClCompile Include="..\..\..\source\slang\slang-ir-simplify-cfg.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\slang\slang-ir-simplify-for-emit.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-ir-single-return.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index f5b138f25..6c7a2c1d2 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -4793,7 +4793,7 @@ void __executeCallable(uint shaderIndex, int payloadLocation);
__generic<Payload>
__target_intrinsic(__glslRayTracing, "$XC")
[__readNone]
-int __callablePayloadLocation(Payload payload);
+int __callablePayloadLocation(__ref Payload payload);
// Now we provide a hard-coded definition of `CallShader()` for GLSL-based
// targets, which maps the generic HLSL operation into the non-generic
@@ -4848,7 +4848,7 @@ void __traceRay(
__generic<Payload>
__target_intrinsic(__glslRayTracing, "$XP")
[__readNone]
-int __rayPayloadLocation(Payload payload);
+int __rayPayloadLocation(__ref Payload payload);
__generic<payload_t>
__specialized_for_target(glsl)
@@ -5678,7 +5678,7 @@ struct VkSubpassInputMS<T>
// We access the HitObjectAttributes via this function for the desired type, and it acts *as if* it's just an access
// to the global t.
[ForceInline]
-__ref T __hitObjectAttributes<T>()
+Ref<T> __hitObjectAttributes<T>()
{
[__vulkanHitObjectAttributes]
static T t;
@@ -5691,7 +5691,7 @@ __ref T __hitObjectAttributes<T>()
__generic<Payload>
__target_intrinsic(__glslRayTracing, "$XH")
[__readNone]
-int __hitObjectAttributesLocation(Payload payload);
+int __hitObjectAttributesLocation(__ref Payload payload);
/// Immutable data type representing a ray hit or a miss. Can be used to invoke hit or miss shading,
/// or as a key in ReorderThread. Created by one of several methods described below. HitObject
diff --git a/source/slang/slang-ast-expr.h b/source/slang/slang-ast-expr.h
index 9fdc10807..d49db89a2 100644
--- a/source/slang/slang-ast-expr.h
+++ b/source/slang/slang-ast-expr.h
@@ -268,6 +268,13 @@ class SwizzleExpr: public Expr
SourceLoc memberOpLoc;
};
+// An operation to convert an l-value to a reference type.
+class MakeRefExpr : public Expr
+{
+ SLANG_AST_CLASS(MakeRefExpr)
+ Expr* base = nullptr;
+};
+
// A dereference of a pointer or pointer-like type
class DerefExpr: public Expr
{
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index 21611bcb1..5fd9df400 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -78,6 +78,7 @@ namespace Slang
// Conversion from a buffer to the type it carries needs to add a minimal
// extra cost, just so we can distinguish an overload on `ConstantBuffer<Foo>`
// from one on `Foo`
+ kConversionCost_GetRef = 5,
kConversionCost_ImplicitDereference = 10,
// Conversions based on explicit sub-typing relationships are the cheapest
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index 6decce625..71231b9e5 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -642,11 +642,6 @@ namespace Slang
return true;
}
- if (auto refType = as<RefType>(toType))
- {
- return _coerce(refType->getValueType(), outToExpr, fromType, fromExpr, outCost);
- }
-
// If both are string types we assume they are convertable in both directions
if (as<StringTypeBase>(fromType) && as<StringTypeBase>(toType))
{
@@ -860,6 +855,63 @@ namespace Slang
return true;
}
+ if (auto refType = as<RefType>(toType))
+ {
+ if (!refType->getValueType()->equals(fromType))
+ return false;
+ if (!fromExpr->type.isLeftValue)
+ return false;
+
+ ConversionCost subCost = kConversionCost_GetRef;
+
+ MakeRefExpr* refExpr = nullptr;
+ if (outToExpr)
+ {
+ refExpr = m_astBuilder->create<MakeRefExpr>();
+ refExpr->base = fromExpr;
+ refExpr->type = QualType(refType);
+ refExpr->type.isLeftValue = false;
+ *outToExpr = refExpr;
+ }
+ if (outCost)
+ *outCost = subCost;
+ return true;
+ }
+
+
+ // Allow implicit dereferencing a reference type.
+ if (auto fromRefType = as<RefType>(fromType))
+ {
+ auto fromValueType = fromRefType->getValueType();
+
+ // If we convert, e.g., `ConstantBuffer<A> to `A`, we will allow
+ // subsequent conversion of `A` to `B` if such a conversion
+ // is possible.
+ //
+ ConversionCost subCost = kConversionCost_None;
+
+ Expr* openRefExpr = nullptr;
+ if (outToExpr)
+ {
+ openRefExpr = maybeOpenRef(fromExpr);
+ }
+
+ if (!_coerce(
+ toType,
+ outToExpr,
+ fromValueType,
+ openRefExpr,
+ &subCost))
+ {
+ return false;
+ }
+
+ if (outCost)
+ *outCost = subCost + kConversionCost_ImplicitDereference;
+ return true;
+ }
+
+
// The main general-purpose approach for conversion is
// using suitable marked initializer ("constructor")
// declarations on the target type.
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 7e2bc3822..7d546e60b 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -1863,6 +1863,7 @@ namespace Slang
Expr* SemanticsVisitor::checkAssignWithCheckedOperands(AssignExpr* expr)
{
+ expr->left = maybeOpenRef(expr->left);
auto type = expr->left->type;
auto right = maybeOpenRef(expr->right);
expr->right = coerce(type, right);
diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h
index ac5fc8392..719706635 100644
--- a/source/slang/slang-check-impl.h
+++ b/source/slang/slang-check-impl.h
@@ -1928,6 +1928,7 @@ namespace Slang
}
CASE(DerefExpr)
+ CASE(MakeRefExpr)
CASE(MatrixSwizzleExpr)
CASE(SwizzleExpr)
CASE(OverloadedExpr)
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 160585e26..c664449e5 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -1082,6 +1082,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
case kIROp_Param:
case kIROp_Func:
case kIROp_Alloca:
+ case kIROp_Store:
return false;
// Never fold these, because their result cannot be computed
@@ -1997,17 +1998,6 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
}
break;
- case kIROp_Store:
- {
- auto prec = getInfo(EmitOp::Assign);
- needClose = maybeEmitParens(outerPrec, prec);
-
- emitDereferenceOperand(inst->getOperand(0), leftSide(outerPrec, prec));
- m_writer->emit(" = ");
- emitOperand(inst->getOperand(1), rightSide(prec, outerPrec));
- }
- break;
-
case kIROp_Call:
{
emitCallExpr((IRCall*)inst, outerPrec);
@@ -2393,6 +2383,22 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
}
break;
+ case kIROp_Store:
+ {
+ if (inst->getPrevInst() == inst->getOperand(0) && inst->getOperand(0)->getOp() == kIROp_Var)
+ {
+ // If we are storing into a var that is defined right before the store, we have
+ // already folded the store in the initialization of the var, so we can skip here.
+ break;
+ }
+ auto prec = getInfo(EmitOp::Assign);
+ emitDereferenceOperand(inst->getOperand(0), leftSide(getInfo(EmitOp::General), prec));
+ m_writer->emit(" = ");
+ emitOperand(inst->getOperand(1), rightSide(prec, getInfo(EmitOp::General)));
+ m_writer->emit(";\n");
+ }
+ break;
+
case kIROp_Param:
// Don't emit parameters, since they are declared as part of the function.
break;
@@ -3321,6 +3327,15 @@ void CLikeSourceEmitter::emitVar(IRVar* varDecl)
emitLayoutSemantics(varDecl);
+ if (auto store = as<IRStore>(varDecl->getNextInst()))
+ {
+ if (store->getPtr() == varDecl)
+ {
+ m_writer->emit(" = ");
+ emitOperand(store->getVal(), getInfo(EmitOp::General));
+ }
+ }
+
m_writer->emit(";\n");
}
diff --git a/source/slang/slang-emit-source-writer.cpp b/source/slang/slang-emit-source-writer.cpp
index bed9a2dbc..7692bd0ec 100644
--- a/source/slang/slang-emit-source-writer.cpp
+++ b/source/slang/slang-emit-source-writer.cpp
@@ -247,8 +247,21 @@ void SourceWriter::emit(double value)
stream.setf(std::ios::fixed, std::ios::floatfield);
stream.precision(20);
stream << value;
-
- emit(stream.str().c_str());
+ auto str = stream.str();
+ auto slice = UnownedStringSlice(str.c_str());
+ // Remove redundant trailing 0s.
+ if (slice.end() > slice.begin())
+ {
+ auto lastChar = slice.end() - 1;
+ while (lastChar > slice.begin() && *lastChar == '0')
+ lastChar--;
+ if (*lastChar == '.')
+ lastChar++;
+ if (lastChar > slice.end() - 1)
+ lastChar = slice.end() - 1;
+ slice = slice.subString(0, lastChar - slice.begin() + 1);
+ }
+ emit(slice);
}
void SourceWriter::advanceToSourceLocationIfValid(const SourceLoc& sourceLocation)
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 3d923179c..2ef0a5647 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -54,6 +54,7 @@
#include "slang-ir-liveness.h"
#include "slang-ir-glsl-liveness.h"
#include "slang-ir-string-hash.h"
+#include "slang-ir-simplify-for-emit.h"
#include "slang-legalize-types.h"
#include "slang-lower-to-ir.h"
#include "slang-mangle.h"
@@ -1008,6 +1009,9 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr
linkedIR));
auto irModule = linkedIR.module;
+
+ // Perform final simplifications to help emit logic to generate more compact code.
+ simplifyForEmit(irModule);
metadata = linkedIR.metadata;
@@ -1015,15 +1019,6 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr
// passes have been performed, we can emit target code from
// the IR module.
//
- // TODO: do we want to emit directly from IR, or translate the
- // IR back into AST for emission?
-#if 0
- {
- StringBuilder sb;
- StringWriter writer(&sb, Slang::WriterFlag::AutoFlush);
- dumpIR(irModule, getIRDumpOptions(), sourceManager, &writer);
- }
-#endif
sourceEmitter->emitModule(irModule, sink);
}
diff --git a/source/slang/slang-intrinsic-expand.cpp b/source/slang/slang-intrinsic-expand.cpp
index 64ef4e761..de3396efb 100644
--- a/source/slang/slang-intrinsic-expand.cpp
+++ b/source/slang/slang-intrinsic-expand.cpp
@@ -735,14 +735,10 @@ const char* IntrinsicExpandContext::_emitSpecial(const char* cursor)
Index argIndex = 0;
SLANG_RELEASE_ASSERT(m_argCount > argIndex);
auto arg = m_args[argIndex].get();
- auto argLoad = as<IRLoad>(arg);
- SLANG_RELEASE_ASSERT(argLoad);
-
- auto argVar = argLoad->getOperand(0);
// Find the associated decoration
IRDecoration* foundDecoration = nullptr;
- for (auto decoration : argVar->getDecorations())
+ for (auto decoration : arg->getDecorations())
{
const auto curKind = LocationTracker::getKindFromDecoration(decoration);
if (curKind == kind)
@@ -755,7 +751,7 @@ const char* IntrinsicExpandContext::_emitSpecial(const char* cursor)
// Must have found the decoration
SLANG_ASSERT(foundDecoration);
- const auto location = m_emitter->getLocationTracker().getValue(kind, argVar, foundDecoration);
+ const auto location = m_emitter->getLocationTracker().getValue(kind, arg, foundDecoration);
m_writer->emit(location);
}
}
diff --git a/source/slang/slang-ir-autodiff-fwd.cpp b/source/slang/slang-ir-autodiff-fwd.cpp
index 16b7a977c..a45a3abf9 100644
--- a/source/slang/slang-ir-autodiff-fwd.cpp
+++ b/source/slang/slang-ir-autodiff-fwd.cpp
@@ -1162,6 +1162,8 @@ InstPair ForwardDiffTranscriber::transcribeFuncHeader(IRBuilder* inBuilder, IRFu
inBuilder->addForwardDerivativeDecoration(origFunc, diffFunc);
}
+ inBuilder->addFloatingModeOverrideDecoration(diffFunc, FloatingPointMode::Fast);
+
FuncBodyTranscriptionTask task;
task.type = FuncBodyTranscriptionTaskType::Forward;
task.originalFunc = origFunc;
diff --git a/source/slang/slang-ir-autodiff-rev.cpp b/source/slang/slang-ir-autodiff-rev.cpp
index fed53b037..702f9819a 100644
--- a/source/slang/slang-ir-autodiff-rev.cpp
+++ b/source/slang/slang-ir-autodiff-rev.cpp
@@ -12,6 +12,7 @@
#include "slang-ir-addr-inst-elimination.h"
#include "slang-ir-eliminate-multilevel-break.h"
#include "slang-ir-init-local-var.h"
+#include "slang-ir-redundancy-removal.h"
namespace Slang
{
@@ -305,7 +306,14 @@ namespace Slang
IRFunc* primalFunc = origFunc;
maybeMigrateDifferentiableDictionaryFromDerivativeFunc(inBuilder, origFunc);
- differentiableTypeConformanceContext.setFunc(origFunc);
+
+ // The original func may not have a type dictionary if it is not originally marked as
+ // differentiable, in this case we would have already pulled the necessary types from
+ // the user-provided derivative function, so we are still fine.
+ if (origFunc->findDecoration<IRDifferentiableTypeDictionaryDecoration>())
+ {
+ differentiableTypeConformanceContext.setFunc(origFunc);
+ }
auto diffFunc = builder.createFunc();
@@ -334,7 +342,7 @@ namespace Slang
builder.setInsertBefore(diffFunc->getFirstDecorationOrChild());
cloneInst(&cloneEnv, &builder, dictDecor);
}
-
+ builder.addFloatingModeOverrideDecoration(diffFunc, FloatingPointMode::Fast);
return InstPair(primalFunc, diffFunc);
}
@@ -588,43 +596,6 @@ namespace Slang
return result;
}
- void eliminateRedundantLoad(IRFunc* func)
- {
- for (auto block : func->getBlocks())
- {
- for (auto inst = block->getFirstInst(); inst;)
- {
- auto nextInst = inst->getNextInst();
- if (auto load = as<IRLoad>(inst))
- {
- for (auto prev = inst->getPrevInst(); prev; prev = prev->getPrevInst())
- {
- if (auto store = as<IRStore>(prev))
- {
- if (store->getPtr() == load->getPtr())
- {
- // If the load is preceeded by a store without any side-effect insts in-between, remove the load.
- auto value = store->getVal();
- load->replaceUsesWith(value);
- load->removeAndDeallocate();
- break;
- }
- }
- else if (as<IRCall>(prev))
- {
- break;
- }
- else if (prev->mightHaveSideEffects())
- {
- break;
- }
- }
- }
- inst = nextInst;
- }
- }
- }
-
// Create a copy of originalFunc's forward derivative in the same generic context (if any) of
// `diffPropagateFunc`.
IRFunc* BackwardDiffTranscriberBase::generateNewForwardDerivativeForFunc(
@@ -669,7 +640,7 @@ namespace Slang
primalOuterParent->removeAndDeallocate();
// Remove redundant loads since they interfere with transposition logic.
- eliminateRedundantLoad(fwdDiffFunc);
+ eliminateRedundantLoadStore(fwdDiffFunc);
// Migrate the new forward derivative function into the generic parent of `diffPropagateFunc`.
if (auto fwdParentGeneric = as<IRGeneric>(findOuterGeneric(fwdDiffFunc)))
@@ -976,13 +947,16 @@ namespace Slang
{
// Create dOut param.
auto diffParam = builder->emitParam(diffType);
+ copyNameHintDecoration(diffParam, fwdParam);
result.propagateFuncParams.Add(diffParam);
primalRefReplacement = builder->emitParam(builder->getOutType(primalType));
+ copyNameHintDecoration(primalRefReplacement, fwdParam);
// Create a local var for read access in pre-transpose code.
// This will the var from which we will fetch the final resulting derivative
// after transposition.
auto tempVar = nextBlockBuilder.emitVar(diffType);
+ copyNameHintDecoration(tempVar, fwdParam);
nextBlockBuilder.markInstAsDifferential(tempVar, diffPairType);
// Initialize the var with input diff param at start.
@@ -999,11 +973,13 @@ namespace Slang
else
{
primalRefReplacement = builder->emitParam(outType);
+ copyNameHintDecoration(primalRefReplacement, fwdParam);
}
result.primalFuncParams.Add(primalRefReplacement);
// Create a local var for the out param for the primal part of the prop func.
auto tempPrimalVar = nextBlockBuilder.emitVar(outType->getValueType());
+ copyNameHintDecoration(tempPrimalVar, fwdParam);
result.mapPrimalSpecificParamToReplacementInPropFunc[primalRefReplacement] = tempPrimalVar;
instsToRemove.Add(fwdParam);
@@ -1023,10 +999,13 @@ namespace Slang
// Create an in param for the prop func.
auto propParam = builder->emitParam(inoutType->getValueType());
+ copyNameHintDecoration(propParam, fwdParam);
result.propagateFuncParams.Add(propParam);
// Create a local var for the out param for the primal part of the prop func.
auto tempPrimalVar = nextBlockBuilder.emitVar(inoutType->getValueType());
+ copyNameHintDecoration(tempPrimalVar, fwdParam);
+
result.propagateFuncSpecificPrimalInsts.add(tempPrimalVar);
auto storeInst = nextBlockBuilder.emitStore(tempPrimalVar, propParam);
result.propagateFuncSpecificPrimalInsts.add(storeInst);
@@ -1054,8 +1033,11 @@ namespace Slang
// Create inout version.
auto inoutDiffPairType = builder->getInOutType(diffPairType);
primalRefReplacement = builder->emitParam(primalType);
+ copyNameHintDecoration(primalRefReplacement, fwdParam);
+
result.primalFuncParams.Add(primalRefReplacement);
auto propParam = builder->emitParam(inoutDiffPairType);
+ copyNameHintDecoration(propParam, fwdParam);
result.propagateFuncParams.Add(propParam);
// A reference to this parameter from the diff blocks should be replaced with a load
@@ -1085,9 +1067,11 @@ namespace Slang
// Process differentiable inout parameters.
auto primalParam = builder->emitParam(builder->getInOutType(primalType));
+ copyNameHintDecoration(primalParam, fwdParam);
result.primalFuncParams.Add(primalParam);
auto diffParam = builder->emitParam(inoutType);
+ copyNameHintDecoration(diffParam, fwdParam);
result.propagateFuncParams.Add(diffParam);
// Primal references to this param is the new primal param.
@@ -1102,6 +1086,7 @@ namespace Slang
// Create a local var for diff read access.
auto diffVar = nextBlockBuilder.emitVar(diffType);
+ copyNameHintDecoration(diffVar, fwdParam);
result.propagateFuncSpecificPrimalInsts.add(diffVar);
diffBuilder.markInstAsDifferential(diffVar, diffPairType);
diffRefReplacement = diffVar;
@@ -1114,6 +1099,8 @@ namespace Slang
// Create a local var for diff write access.
auto diffWriteVar = nextBlockBuilder.emitVar(diffType);
+ copyNameHintDecoration(diffWriteVar, fwdParam);
+
// Initialize write var to 0.
auto writeStore = nextBlockBuilder.emitStore(diffWriteVar, initDiff);
result.propagateFuncSpecificPrimalInsts.add(writeStore);
@@ -1122,6 +1109,8 @@ namespace Slang
// Create a local var for the primal logic in the propagate func.
auto primalVar = nextBlockBuilder.emitVar(primalType);
+ copyNameHintDecoration(primalVar, fwdParam);
+
result.propagateFuncSpecificPrimalInsts.add(primalVar);
auto initPrimalVal = nextBlockBuilder.emitDifferentialPairGetPrimal(loadedParam);
result.propagateFuncSpecificPrimalInsts.add(initPrimalVal);
@@ -1213,11 +1202,13 @@ namespace Slang
SLANG_ASSERT(dOutParamType);
dOutParam = builder->emitParam(dOutParamType);
+ builder->addNameHintDecoration(dOutParam, UnownedStringSlice("_s_dOut"));
result.propagateFuncParams.Add(dOutParam);
}
// Add a parameter for intermediate val.
auto ctxParam = builder->emitParam(as<IRFuncType>(diffFunc->getDataType())->getParamType(paramCount - 1));
+ builder->addNameHintDecoration(ctxParam, UnownedStringSlice("_s_diff_ctx"));
result.primalFuncParams.Add(ctxParam);
result.propagateFuncParams.Add(ctxParam);
result.dOutParam = dOutParam;
diff --git a/source/slang/slang-ir-autodiff-unzip.cpp b/source/slang/slang-ir-autodiff-unzip.cpp
index be20d8aa8..3e7e346d2 100644
--- a/source/slang/slang-ir-autodiff-unzip.cpp
+++ b/source/slang/slang-ir-autodiff-unzip.cpp
@@ -295,6 +295,7 @@ struct ExtractPrimalFuncContext
auto oldIntermediateParam = func->getLastParam();
auto outIntermediary =
builder.emitParam(builder.getInOutType((IRType*)intermediateType));
+ oldIntermediateParam->transferDecorationsTo(outIntermediary);
primalParams.Add(outIntermediary);
oldIntermediateParam->replaceUsesWith(outIntermediary);
oldIntermediateParam->removeAndDeallocate();
@@ -473,15 +474,34 @@ IRFunc* DiffUnzipPass::extractPrimalFunc(
if (inst->getOp() == kIROp_Var)
{
// This is a var for intermediate context.
- auto valType = cast<IRPtrTypeBase>(inst->getFullType())->getValueType();
- auto val = builder.emitFieldExtract(
- valType,
- intermediateVar,
- structKeyDecor->getStructKey());
- auto tempVar =
- builder.emitVar(valType);
- builder.emitStore(tempVar, val);
- inst->replaceUsesWith(tempVar);
+ // Replace all loads of the var with a field extract.
+ // Other type of uses will get a temp var that stores a copy of the field.
+ while (auto use = inst->firstUse)
+ {
+ if (as<IRDecoration>(use->getUser()))
+ {
+ use->set(builder.getVoidValue());
+ continue;
+ }
+ builder.setInsertBefore(use->getUser());
+ auto valType = cast<IRPtrTypeBase>(inst->getFullType())->getValueType();
+ auto val = builder.emitFieldExtract(
+ valType,
+ intermediateVar,
+ structKeyDecor->getStructKey());
+ if (use->getUser()->getOp() == kIROp_Load)
+ {
+ use->getUser()->replaceUsesWith(val);
+ use->getUser()->removeAndDeallocate();
+ }
+ else
+ {
+ auto tempVar =
+ builder.emitVar(valType);
+ builder.emitStore(tempVar, val);
+ use->set(tempVar);
+ }
+ }
}
else
{
diff --git a/source/slang/slang-ir-autodiff.cpp b/source/slang/slang-ir-autodiff.cpp
index fdaff4960..f38bdfdbd 100644
--- a/source/slang/slang-ir-autodiff.cpp
+++ b/source/slang/slang-ir-autodiff.cpp
@@ -256,6 +256,11 @@ IRInst* DifferentialPairTypeBuilder::_createDiffPairType(IRType* origBaseType, I
builder.setInsertBefore(diffType);
auto pairStructType = builder.createStructType();
+ StringBuilder nameBuilder;
+ nameBuilder << "DiffPair_";
+ getTypeNameHint(nameBuilder, origBaseType);
+ builder.addNameHintDecoration(pairStructType, nameBuilder.ToString().getUnownedSlice());
+
builder.createStructField(pairStructType, _getOrCreatePrimalStructKey(), origBaseType);
builder.createStructField(pairStructType, _getOrCreateDiffStructKey(), (IRType*)diffType);
return pairStructType;
diff --git a/source/slang/slang-ir-dce.cpp b/source/slang/slang-ir-dce.cpp
index 33e5b3cb4..337caa246 100644
--- a/source/slang/slang-ir-dce.cpp
+++ b/source/slang/slang-ir-dce.cpp
@@ -3,6 +3,7 @@
#include "slang-ir.h"
#include "slang-ir-insts.h"
+#include "slang-ir-util.h"
namespace Slang
{
@@ -16,6 +17,7 @@ struct DeadCodeEliminationContext
// `eliminateDeadCode` function.
//
IRModule* module;
+
IRDeadCodeEliminationOptions options;
// If we removed an inst, there may be still "weak references" to the inst.
@@ -129,6 +131,9 @@ struct DeadCodeEliminationContext
auto inst = workList.getLast();
workList.removeLast();
+ if (!isChildInstOf(inst, root))
+ continue;
+
// At this point we know that `inst` is live,
// and we want to start considering which other
// instructions must be live because of that
@@ -426,7 +431,6 @@ bool eliminateDeadCode(
DeadCodeEliminationContext context;
context.module = module;
context.options = options;
-
return context.processModule();
}
@@ -437,7 +441,6 @@ bool eliminateDeadCode(
DeadCodeEliminationContext context;
context.module = root->getModule();
context.options = options;
-
return context.processInst(root);
}
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 1cb839751..26a92a17a 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -797,6 +797,9 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
/* Differentiable Type Dictionary */
INST(DifferentiableTypeDictionaryDecoration, DifferentiableTypeDictionaryDecoration, 0, PARENT)
+ /// Overrides the floating mode for the target function
+ INST(FloatingPointModeOverrideDecoration, FloatingPointModeOverride, 1, 0)
+
/// Marks a struct type as being used as a structured buffer block.
/// Recognized by SPIRV-emit pass so we can emit a SPIRV `BufferBlock` decoration.
INST(SPIRVBufferBlockDecoration, spvBufferBlock, 0, 0)
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index d1374477f..fad20e900 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -846,6 +846,13 @@ struct IRDifferentiableTypeDictionaryDecoration : IRDecoration
IR_LEAF_ISA(DifferentiableTypeDictionaryDecoration)
};
+struct IRFloatingModeOverrideDecoration : IRDecoration
+{
+ IR_LEAF_ISA(FloatingPointModeOverrideDecoration)
+
+ FloatingPointMode getFloatingPointMode() { return (FloatingPointMode)cast<IRIntLit>(getOperand(0))->getValue(); }
+};
+
// An instruction that specializes another IR value
// (representing a generic) to a particular set of generic arguments
// (instructions representing types, witness tables, etc.)
@@ -2835,6 +2842,8 @@ public:
// Add a differentiable type entry to the appropriate dictionary.
IRInst* addDifferentiableTypeEntry(IRInst* dictDecoration, IRInst* irType, IRInst* conformanceWitness);
+ IRInst* addFloatingModeOverrideDecoration(IRInst* dest, FloatingPointMode mode);
+
IRInst* emitSpecializeInst(
IRType* type,
IRInst* genericVal,
diff --git a/source/slang/slang-ir-peephole.cpp b/source/slang/slang-ir-peephole.cpp
index fd0b4577a..65b4adcac 100644
--- a/source/slang/slang-ir-peephole.cpp
+++ b/source/slang/slang-ir-peephole.cpp
@@ -10,6 +10,7 @@ struct PeepholeContext : InstPassBase
{}
bool changed = false;
+ FloatingPointMode floatingPointMode = FloatingPointMode::Precise;
bool tryFoldElementExtractFromUpdateInst(IRInst* inst)
{
@@ -96,8 +97,158 @@ struct PeepholeContext : InstPassBase
return false;
}
+ bool isZero(IRInst* inst)
+ {
+ switch (inst->getOp())
+ {
+ case kIROp_IntLit:
+ return as<IRIntLit>(inst)->getValue() == 0;
+ case kIROp_FloatLit:
+ return as<IRFloatLit>(inst)->getValue() == 0.0;
+ case kIROp_MakeVector:
+ case kIROp_MakeVectorFromScalar:
+ case kIROp_MakeMatrix:
+ case kIROp_MakeMatrixFromScalar:
+ case kIROp_MatrixReshape:
+ case kIROp_VectorReshape:
+ {
+ for (UInt i = 0; i < inst->getOperandCount(); i++)
+ {
+ if (!isZero(inst->getOperand(i)))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ case kIROp_CastIntToFloat:
+ case kIROp_CastFloatToInt:
+ return isZero(inst->getOperand(0));
+ default:
+ return false;
+ }
+ }
+
+ bool isOne(IRInst* inst)
+ {
+ switch (inst->getOp())
+ {
+ case kIROp_IntLit:
+ return as<IRIntLit>(inst)->getValue() == 1;
+ case kIROp_FloatLit:
+ return as<IRFloatLit>(inst)->getValue() == 1.0;
+ case kIROp_MakeVector:
+ case kIROp_MakeVectorFromScalar:
+ case kIROp_MakeMatrix:
+ case kIROp_MakeMatrixFromScalar:
+ case kIROp_MatrixReshape:
+ case kIROp_VectorReshape:
+ {
+ for (UInt i = 0; i < inst->getOperandCount(); i++)
+ {
+ if (!isOne(inst->getOperand(i)))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ case kIROp_CastIntToFloat:
+ case kIROp_CastFloatToInt:
+ return isOne(inst->getOperand(0));
+ default:
+ return false;
+ }
+ }
+
+ bool tryOptimizeArithmeticInst(IRInst* inst)
+ {
+ bool allowUnsafeOptimizations =
+ (floatingPointMode == FloatingPointMode::Fast ||
+ isIntegralScalarOrCompositeType(inst->getDataType()));
+
+ auto tryReplace = [&](IRInst* replacement) -> bool
+ {
+ if (replacement->getFullType() != inst->getFullType())
+ {
+ // If the operand type is different from result type,
+ // we try to convert for some known cases.
+ if (auto vectorType = as<IRVectorType>(inst->getFullType()))
+ {
+ if (vectorType->getElementType() != replacement->getFullType())
+ return false;
+ IRBuilder builder(sharedBuilderStorage);
+ builder.setInsertBefore(inst);
+ replacement = builder.emitMakeVectorFromScalar(inst->getFullType(), replacement);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ inst->replaceUsesWith(replacement);
+ inst->removeAndDeallocate();
+ return true;
+ };
+
+ switch (inst->getOp())
+ {
+ case kIROp_Add:
+ if (isZero(inst->getOperand(0)))
+ {
+ return tryReplace(inst->getOperand(1));
+ }
+ else if (isZero(inst->getOperand(1)))
+ {
+ return tryReplace(inst->getOperand(0));
+ }
+ break;
+ case kIROp_Sub:
+ if (isZero(inst->getOperand(1)))
+ {
+ return tryReplace(inst->getOperand(0));
+ }
+ break;
+ case kIROp_Mul:
+ if (isOne(inst->getOperand(0)))
+ {
+ return tryReplace(inst->getOperand(1));
+ }
+ else if (isOne(inst->getOperand(1)))
+ {
+ return tryReplace(inst->getOperand(0));
+ }
+ else if (allowUnsafeOptimizations && isZero(inst->getOperand(0)))
+ {
+ return tryReplace(inst->getOperand(0));
+ }
+ else if (allowUnsafeOptimizations && isZero(inst->getOperand(1)))
+ {
+ return tryReplace(inst->getOperand(1));
+ }
+ break;
+ case kIROp_Div:
+ if (allowUnsafeOptimizations && isZero(inst->getOperand(0)))
+ {
+ return tryReplace(inst->getOperand(0));
+ }
+ else if (isOne(inst->getOperand(1)))
+ {
+ return tryReplace(inst->getOperand(0));
+ }
+ }
+ return false;
+ }
+
void processInst(IRInst* inst)
{
+ if (as<IRGlobalValueWithCode>(inst))
+ {
+ if (auto fpModeDecor = inst->findDecoration<IRFloatingModeOverrideDecoration>())
+ floatingPointMode = fpModeDecor->getFloatingPointMode();
+ }
+
switch (inst->getOp())
{
case kIROp_GetResultError:
@@ -432,6 +583,12 @@ struct PeepholeContext : InstPassBase
}
}
break;
+ case kIROp_Add:
+ case kIROp_Mul:
+ case kIROp_Sub:
+ case kIROp_Div:
+ changed = tryOptimizeArithmeticInst(inst);
+ break;
default:
break;
}
@@ -443,6 +600,7 @@ struct PeepholeContext : InstPassBase
sharedBuilder->init(module);
sharedBuilderStorage.deduplicateAndRebuildGlobalNumberingMap();
bool result = false;
+
for (;;)
{
changed = false;
diff --git a/source/slang/slang-ir-redundancy-removal.cpp b/source/slang/slang-ir-redundancy-removal.cpp
index 9bd681115..176142601 100644
--- a/source/slang/slang-ir-redundancy-removal.cpp
+++ b/source/slang/slang-ir-redundancy-removal.cpp
@@ -109,6 +109,7 @@ bool removeRedundancy(IRModule* module)
if (auto func = as<IRFunc>(inst))
{
changed |= removeRedundancyInFunc(func);
+ changed |= eliminateRedundantLoadStore(func);
}
}
return changed;
@@ -126,4 +127,95 @@ bool removeRedundancyInFunc(IRGlobalValueWithCode* func)
return context.removeRedundancyInBlock(deduplicateCtx, root);
}
+bool eliminateRedundantLoadStore(IRGlobalValueWithCode* func)
+{
+ bool changed = false;
+ for (auto block : func->getBlocks())
+ {
+ for (auto inst = block->getFirstInst(); inst;)
+ {
+ auto nextInst = inst->getNextInst();
+ if (auto load = as<IRLoad>(inst))
+ {
+ for (auto prev = inst->getPrevInst(); prev; prev = prev->getPrevInst())
+ {
+ if (auto store = as<IRStore>(prev))
+ {
+ if (store->getPtr() == load->getPtr())
+ {
+ // If the load is preceeded by a store without any side-effect insts in-between, remove the load.
+ auto value = store->getVal();
+ load->replaceUsesWith(value);
+ load->removeAndDeallocate();
+ changed = true;
+ break;
+ }
+ }
+
+ if (canInstHaveSideEffectAtAddress(func, prev, load->getPtr()))
+ {
+ break;
+ }
+ }
+ }
+ else if (auto store = as<IRStore>(inst))
+ {
+ // We perform a quick and conservative check:
+ // A store is redundant if it is followed by another store to the same address in
+ // the same basic block, and there are no instructions that may use any addresses
+ // related to this address.
+ bool hasAddrUse = false;
+ bool hasOverridingStore = false;
+
+ // Stores to global variables will never get removed.
+ if (!isChildInstOf(store->getPtr(), func))
+ hasAddrUse = true;
+
+ for (auto next = store->getNextInst(); next; next = next->getNextInst())
+ {
+ if (auto nextStore = as<IRStore>(next))
+ {
+ if (nextStore->getPtr() == store->getPtr())
+ {
+ hasOverridingStore = true;
+ break;
+ }
+ }
+
+ // If we see any insts that have reads or modifies the address before seeing
+ // an overriding store, don't remove the store.
+ // We can make the test more accurate by collecting all addresses related to
+ // the target address first, and only bail out if any of the related addresses
+ // are involved.
+ switch (next->getOp())
+ {
+ case kIROp_Load:
+ if (canAddressesPotentiallyAlias(func, next->getOperand(0), store->getPtr()))
+ {
+ hasAddrUse = true;
+ }
+ break;
+ default:
+ if (canInstHaveSideEffectAtAddress(func, next, store->getPtr()))
+ {
+ hasAddrUse = true;
+ }
+ break;
+ }
+ if (hasAddrUse)
+ break;
+ }
+
+ if (!hasAddrUse && hasOverridingStore)
+ {
+ store->removeAndDeallocate();
+ changed = true;
+ }
+ }
+ inst = nextInst;
+ }
+ }
+ return changed;
+}
+
}
diff --git a/source/slang/slang-ir-redundancy-removal.h b/source/slang/slang-ir-redundancy-removal.h
index 26b265e77..c2df7853e 100644
--- a/source/slang/slang-ir-redundancy-removal.h
+++ b/source/slang/slang-ir-redundancy-removal.h
@@ -8,4 +8,6 @@ namespace Slang
bool removeRedundancy(IRModule* module);
bool removeRedundancyInFunc(IRGlobalValueWithCode* func);
+
+ bool eliminateRedundantLoadStore(IRGlobalValueWithCode* func);
}
diff --git a/source/slang/slang-ir-simplify-for-emit.cpp b/source/slang/slang-ir-simplify-for-emit.cpp
new file mode 100644
index 000000000..5e5f61a4a
--- /dev/null
+++ b/source/slang/slang-ir-simplify-for-emit.cpp
@@ -0,0 +1,354 @@
+#include "slang-ir-simplify-for-emit.h"
+#include "slang-ir-inst-pass-base.h"
+#include "slang-ir-util.h"
+
+namespace Slang
+{
+
+struct SimplifyForEmitContext : public InstPassBase
+{
+ SimplifyForEmitContext(IRModule* inModule)
+ : InstPassBase(inModule)
+ {}
+
+ List<IRInst*> followUpWorkList;
+ HashSet<IRInst*> followUpWorkListSet;
+
+ void addToFollowUpWorkList(IRInst* inst)
+ {
+ if (followUpWorkListSet.Add(inst))
+ followUpWorkList.add(inst);
+ }
+
+ void processMakeStruct(IRInst* makeStruct)
+ {
+ auto structType = as<IRStructType>(makeStruct->getDataType());
+ if (!structType)
+ return;
+ for (auto use = makeStruct->firstUse; use;)
+ {
+ auto nextUse = use->nextUse;
+ auto user = use->getUser();
+ if (auto store = as<IRStore>(user))
+ {
+ IRBuilder builder(sharedBuilderStorage);
+ builder.setInsertBefore(user);
+ UInt i = 0;
+ for (auto field : structType->getFields())
+ {
+ auto fieldAddr = builder.emitFieldAddress(
+ builder.getPtrType(field->getFieldType()),
+ store->getPtr(),
+ field->getKey());
+ builder.emitStore(fieldAddr, makeStruct->getOperand(i));
+ addToFollowUpWorkList(makeStruct->getOperand(i));
+ i++;
+ }
+ store->removeAndDeallocate();
+ }
+ use = nextUse;
+ }
+ if (!makeStruct->hasUses())
+ makeStruct->removeAndDeallocate();
+ }
+
+ void processMakeArray(IRInst* makeArray)
+ {
+ auto arrayType = as<IRArrayType>(makeArray->getDataType());
+ if (!arrayType)
+ return;
+
+ for (auto use = makeArray->firstUse; use;)
+ {
+ auto nextUse = use->nextUse;
+ auto user = use->getUser();
+ if (auto store = as<IRStore>(user))
+ {
+ IRBuilder builder(sharedBuilderStorage);
+ builder.setInsertBefore(user);
+ for (UInt i = 0; i < makeArray->getOperandCount(); i++)
+ {
+ auto elementAddr = builder.emitElementAddress(
+ builder.getPtrType(arrayType->getElementType()),
+ store->getPtr(),
+ builder.getIntValue(builder.getIntType(), (IRIntegerValue)i));
+ builder.emitStore(elementAddr, makeArray->getOperand(i));
+ addToFollowUpWorkList(makeArray->getOperand(i));
+ }
+ store->removeAndDeallocate();
+ }
+ use = nextUse;
+ }
+ if (!makeArray->hasUses())
+ makeArray->removeAndDeallocate();
+ }
+
+ void processMakeArrayFromElement(IRInst* makeArray)
+ {
+ auto arrayType = as<IRArrayType>(makeArray->getDataType());
+ if (!arrayType)
+ return;
+ auto arraySize = as<IRIntLit>(arrayType->getElementCount());
+ if (!arraySize)
+ return;
+
+ for (auto use = makeArray->firstUse; use;)
+ {
+ auto nextUse = use->nextUse;
+ auto user = use->getUser();
+ if (auto store = as<IRStore>(user))
+ {
+ IRBuilder builder(sharedBuilderStorage);
+ builder.setInsertBefore(user);
+ for (IRIntegerValue i = 0; i < arraySize->getValue(); i++)
+ {
+ auto elementAddr = builder.emitElementAddress(
+ builder.getPtrType(arrayType->getElementType()),
+ store->getPtr(),
+ builder.getIntValue(builder.getIntType(), i));
+ builder.emitStore(elementAddr, makeArray->getOperand(0));
+ addToFollowUpWorkList(makeArray->getOperand(0));
+ }
+ store->removeAndDeallocate();
+ }
+ use = nextUse;
+ }
+ if (!makeArray->hasUses())
+ makeArray->removeAndDeallocate();
+ }
+
+ void processLoadUse(IRGlobalValueWithCode* func, IRLoad* load, IRUse* use)
+ {
+ auto user = use->getUser();
+ if (user->getParent() != load->getParent())
+ return;
+ for (auto inst = load->getNextInst(); inst; inst = inst->getNextInst())
+ {
+ if (inst == user)
+ break;
+ if (canInstHaveSideEffectAtAddress(func, inst, load->getPtr()))
+ return;
+ }
+
+ // If we reach here, it is OK to defer the load at use site.
+ IRBuilder builder(sharedBuilderStorage);
+ builder.setInsertBefore(user);
+ auto newLoad = builder.emitLoad(load->getPtr());
+ use->set(newLoad);
+ }
+
+ void processLoad(IRLoad* inst)
+ {
+ auto func = getParentFunc(inst);
+ if (!func)
+ return;
+
+ for (auto use = inst->firstUse; use;)
+ {
+ auto nextUse = use->nextUse;
+ processLoadUse(func, inst, use);
+ use = nextUse;
+ }
+
+ if (!inst->hasUses())
+ inst->removeAndDeallocate();
+ }
+
+ void processElementExtract(IRInst* inst)
+ {
+ // Create a duplicate for each use site.
+ // This is safe because the result value of this inst should never
+ // change regardless of where the inst is defined.
+ // By creating the duplicates right before use sites, we will enable
+ // the emit logic to always fold these insts.
+ for (auto use = inst->firstUse; use;)
+ {
+ auto nextUse = use->nextUse;
+
+ auto user = use->getUser();
+ if (user->getPrevInst() == inst)
+ {
+ use = nextUse;
+ continue;
+ }
+
+ IRBuilder builder(sharedBuilderStorage);
+ builder.setInsertBefore(user);
+ List<IRInst*> args;
+ for (UInt i = 0; i < inst->getOperandCount(); i++)
+ args.add(inst->getOperand(i));
+ auto newInst = builder.emitIntrinsicInst(inst->getFullType(), inst->getOp(), inst->getOperandCount(), args.getBuffer());
+ use->set(newInst);
+
+ use = nextUse;
+ }
+ if (!inst->hasUses())
+ inst->removeAndDeallocate();
+ }
+
+ void processVar(IRInst* var)
+ {
+ // Defer var to its first use, if the use is in the same basic block as the var.
+ HashSet<IRInst*> userInSameBlock;
+ for (auto use = var->firstUse; use; use = use->nextUse)
+ if (use->getUser()->getParent() == var->getParent())
+ {
+ userInSameBlock.Add(use->getUser());
+ }
+ IRInst* firstUser = nullptr;
+ for (auto inst = var->getNextInst(); inst; inst = inst->getNextInst())
+ {
+ if (userInSameBlock.Contains(inst))
+ {
+ firstUser = inst;
+ break;
+ }
+ }
+ if (!firstUser)
+ return;
+ var->insertBefore(firstUser);
+ }
+
+ void processInst(IRInst* inst)
+ {
+ // We inspect each inst and see if the following simplifications
+ // can be applied:
+ // 1. If we see `store(addr, MakeArray/Struct)`, we should turn them
+ // into direct stores into each element/field and remove the need
+ // to create a temporary for the `MakeArray/Struct` inst.
+ // 2. If we see `load(addr)`, we duplicate the load right at each
+ // use site if it can be determined safe to do so. This allows
+ // emit logic to skip producing a temp var for the loaded result.
+ switch (inst->getOp())
+ {
+ case kIROp_MakeStruct:
+ processMakeStruct(inst);
+ break;
+ case kIROp_MakeArray:
+ processMakeArray(inst);
+ break;
+ case kIROp_MakeArrayFromElement:
+ processMakeArrayFromElement(inst);
+ break;
+ case kIROp_Load:
+ processLoad(as<IRLoad>(inst));
+ break;
+ case kIROp_GetElement:
+ case kIROp_FieldExtract:
+ processElementExtract(inst);
+ break;
+ case kIROp_Var:
+ processVar(inst);
+ break;
+ }
+ }
+
+ void eliminateCompositeConstruct(IRGlobalValueWithCode* func)
+ {
+ followUpWorkList.clear();
+ followUpWorkListSet.Clear();
+
+ for (auto block : func->getBlocks())
+ {
+ for (auto inst = block->getFirstInst(); inst; inst = inst->getNextInst())
+ {
+ switch (inst->getOp())
+ {
+ case kIROp_MakeStruct:
+ case kIROp_MakeArray:
+ case kIROp_MakeArrayFromElement:
+ addToFollowUpWorkList(inst);
+ break;
+ }
+ }
+ }
+ for (Index i = 0; i < followUpWorkList.getCount(); i++)
+ processInst(followUpWorkList[i]);
+ }
+
+ void deferAndDuplicateLoad(IRGlobalValueWithCode* func)
+ {
+ followUpWorkList.clear();
+ followUpWorkListSet.Clear();
+
+ for (auto block : func->getBlocks())
+ {
+ for (auto inst = block->getFirstInst(); inst; inst = inst->getNextInst())
+ {
+ switch (inst->getOp())
+ {
+ case kIROp_Load:
+ addToFollowUpWorkList(inst);
+ break;
+ }
+ }
+ }
+ for (Index i = 0; i < followUpWorkList.getCount(); i++)
+ processInst(followUpWorkList[i]);
+ }
+
+ void deferVarDecl(IRGlobalValueWithCode* func)
+ {
+ followUpWorkList.clear();
+ followUpWorkListSet.Clear();
+
+ for (auto block : func->getBlocks())
+ {
+ for (auto inst = block->getFirstInst(); inst; inst = inst->getNextInst())
+ {
+ switch (inst->getOp())
+ {
+ case kIROp_Var:
+ addToFollowUpWorkList(inst);
+ break;
+ }
+ }
+ }
+ for (Index i = 0; i < followUpWorkList.getCount(); i++)
+ processInst(followUpWorkList[i]);
+ }
+
+ void deferAndDuplicateElementExtract(IRGlobalValueWithCode* func)
+ {
+ followUpWorkList.clear();
+ followUpWorkListSet.Clear();
+
+ for (auto block = func->getLastBlock(); block; block = block->getPrevBlock())
+ {
+ for (auto inst = block->getLastChild(); inst; inst = inst->getPrevInst())
+ {
+ switch (inst->getOp())
+ {
+ case kIROp_GetElement:
+ case kIROp_FieldExtract:
+ addToFollowUpWorkList(inst);
+ break;
+ }
+ }
+ }
+ for (Index i = 0; i < followUpWorkList.getCount(); i++)
+ processInst(followUpWorkList[i]);
+ }
+
+ void processFunc(IRGlobalValueWithCode* func)
+ {
+ eliminateCompositeConstruct(func);
+ deferAndDuplicateElementExtract(func);
+ deferAndDuplicateLoad(func);
+ deferVarDecl(func);
+ }
+
+ void processModule()
+ {
+ sharedBuilderStorage.init(module);
+ processInstsOfType<IRFunc>(kIROp_Func, [this](IRFunc* f) { processFunc(f); });
+ }
+};
+
+void simplifyForEmit(IRModule* module)
+{
+ SimplifyForEmitContext context(module);
+ context.processModule();
+}
+
+}
diff --git a/source/slang/slang-ir-simplify-for-emit.h b/source/slang/slang-ir-simplify-for-emit.h
new file mode 100644
index 000000000..a6cf3bad8
--- /dev/null
+++ b/source/slang/slang-ir-simplify-for-emit.h
@@ -0,0 +1,9 @@
+// slang-ir-simplify-for-emit.h
+#pragma once
+
+namespace Slang
+{
+ struct IRModule;
+
+ void simplifyForEmit(IRModule* inModule);
+}
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index 5cf074484..af6fd8ac4 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -229,6 +229,217 @@ String dumpIRToString(IRInst* root)
return sb.ToString();
}
+void copyNameHintDecoration(IRInst* dest, IRInst* src)
+{
+ auto decor = src->findDecoration<IRNameHintDecoration>();
+ if (decor)
+ {
+ cloneDecoration(decor, dest);
+ }
+}
+
+void getTypeNameHint(StringBuilder& sb, IRInst* type)
+{
+ if (!type)
+ return;
+
+ switch (type->getOp())
+ {
+ case kIROp_FloatType:
+ sb << "float";
+ break;
+ case kIROp_HalfType:
+ sb << "half";
+ break;
+ case kIROp_DoubleType:
+ sb << "double";
+ break;
+ case kIROp_IntType:
+ sb << "int";
+ break;
+ case kIROp_Int8Type:
+ sb << "int8";
+ break;
+ case kIROp_Int16Type:
+ sb << "int16";
+ break;
+ case kIROp_Int64Type:
+ sb << "int64";
+ break;
+ case kIROp_IntPtrType:
+ sb << "intptr";
+ break;
+ case kIROp_UIntType:
+ sb << "uint";
+ break;
+ case kIROp_UInt8Type:
+ sb << "uint8";
+ break;
+ case kIROp_UInt16Type:
+ sb << "uint16";
+ break;
+ case kIROp_UInt64Type:
+ sb << "uint64";
+ break;
+ case kIROp_UIntPtrType:
+ sb << "uintptr";
+ break;
+ case kIROp_CharType:
+ sb << "char";
+ break;
+ case kIROp_StringType:
+ sb << "string";
+ break;
+ case kIROp_ArrayType:
+ sb << "array_";
+ getTypeNameHint(sb, type->getOperand(0));
+ break;
+ case kIROp_VectorType:
+ getTypeNameHint(sb, type->getOperand(0));
+ getTypeNameHint(sb, as<IRVectorType>(type)->getElementCount());
+ break;
+ case kIROp_MatrixType:
+ getTypeNameHint(sb, type->getOperand(0));
+ getTypeNameHint(sb, as<IRMatrixType>(type)->getRowCount());
+ sb << "x";
+ getTypeNameHint(sb, as<IRMatrixType>(type)->getColumnCount());
+ break;
+ case kIROp_IntLit:
+ sb << as<IRIntLit>(type)->getValue();
+ break;
+ default:
+ if (auto decor = type->findDecoration<IRNameHintDecoration>())
+ sb << decor->getName();
+ break;
+ }
+}
+
+static IRInst* _getRootAddr(IRInst* addr)
+{
+ for (;;)
+ {
+ switch (addr->getOp())
+ {
+ case kIROp_GetElementPtr:
+ case kIROp_FieldAddress:
+ addr = addr->getOperand(0);
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return addr;
+}
+
+// A simple and conservative address aliasing check.
+bool canAddressesPotentiallyAlias(IRGlobalValueWithCode* func, IRInst* addr1, IRInst* addr2)
+{
+ if (addr1 == addr2)
+ return true;
+
+ // Two variables can never alias.
+ addr1 = _getRootAddr(addr1);
+ addr2 = _getRootAddr(addr2);
+
+ // Global addresses can alias with anything.
+ if (!isChildInstOf(addr1, func))
+ return true;
+
+ if (!isChildInstOf(addr2, func))
+ return true;
+
+ if (addr1->getOp() == kIROp_Var && addr2->getOp() == kIROp_Var
+ && addr1 != addr2)
+ return false;
+
+ // A param and a var can never alias.
+ if (addr1->getOp() == kIROp_Param && addr1->getParent() == func->getFirstBlock() &&
+ addr2->getOp() == kIROp_Var ||
+ addr1->getOp() == kIROp_Var && addr2->getOp() == kIROp_Param &&
+ addr2->getParent() == func->getFirstBlock())
+ return false;
+ return true;
+}
+
+bool isPtrLikeOrHandleType(IRInst* type)
+{
+ switch (type->getOp())
+ {
+ case kIROp_ComPtrType:
+ case kIROp_RawPointerType:
+ case kIROp_RTTIPointerType:
+ case kIROp_PseudoPtrType:
+ case kIROp_OutType:
+ case kIROp_InOutType:
+ case kIROp_PtrType:
+ case kIROp_RefType:
+ return true;
+ }
+ return false;
+}
+
+bool canInstHaveSideEffectAtAddress(IRGlobalValueWithCode* func, IRInst* inst, IRInst* addr)
+{
+ switch (inst->getOp())
+ {
+ case kIROp_Store:
+ // If the target of the store inst may overlap addr, return true.
+ if (canAddressesPotentiallyAlias(func, as<IRStore>(inst)->getPtr(), addr))
+ return true;
+ break;
+ case kIROp_Call:
+ {
+ auto call = as<IRCall>(inst);
+
+ // If addr is a global variable, calling a function may change its value.
+ // So we need to return true here to be conservative.
+ if (!isChildInstOf(_getRootAddr(addr), func))
+ {
+ auto callee = call->getCallee();
+ if (callee &&
+ callee->findDecoration<IRReadNoneDecoration>() &&
+ callee->findDecoration<IRNoSideEffectDecoration>())
+ {
+ // An exception is if the callee is side-effect free and is not reading from
+ // memory.
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ // If any pointer typed argument of the call inst may overlap addr, return true.
+ for (UInt i = 0; i < call->getArgCount(); i++)
+ {
+ if (isPtrLikeOrHandleType(call->getArg(i)->getDataType()))
+ {
+ if (canAddressesPotentiallyAlias(func, call->getArg(i), addr))
+ return true;
+ }
+ }
+ }
+ break;
+ case kIROp_CastPtrToInt:
+ case kIROp_Reinterpret:
+ case kIROp_BitCast:
+ {
+ // If we are trying to cast an address to something else, return true.
+ if (isPtrLikeOrHandleType(inst->getOperand(0)->getDataType()) &&
+ canAddressesPotentiallyAlias(func, inst->getOperand(0), addr))
+ return true;
+ }
+ break;
+ default:
+ // Default behavior is that any insts that have side effect may affect `addr`.
+ if (inst->mightHaveSideEffects())
+ return true;
+ break;
+ }
+ return false;
+}
+
bool isPureFunctionalCall(IRCall* call)
{
auto callee = getResolvedInstForDecorations(call->getCallee());
diff --git a/source/slang/slang-ir-util.h b/source/slang/slang-ir-util.h
index 26ad4bc68..c067bde44 100644
--- a/source/slang/slang-ir-util.h
+++ b/source/slang/slang-ir-util.h
@@ -153,11 +153,20 @@ inline IRInst* unwrapAttributedType(IRInst* type)
return type;
}
+void getTypeNameHint(StringBuilder& sb, IRInst* type);
+void copyNameHintDecoration(IRInst* dest, IRInst* src);
+
+bool canAddressesPotentiallyAlias(IRGlobalValueWithCode* func, IRInst* addr1, IRInst* addr2);
+
String dumpIRToString(IRInst* root);
// Returns whether a call insts can be treated as a pure functional inst
// (no writes to memory, no side effects).
bool isPureFunctionalCall(IRCall* callInst);
+
+bool isPtrLikeOrHandleType(IRInst* type);
+
+bool canInstHaveSideEffectAtAddress(IRGlobalValueWithCode* func, IRInst* inst, IRInst* addr);
}
#endif
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index 558574bf6..1b16bfe1f 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -4604,6 +4604,14 @@ namespace Slang
return inst;
}
+ IRInst* IRBuilder::addFloatingModeOverrideDecoration(IRInst* dest, FloatingPointMode mode)
+ {
+ return addDecoration(
+ dest,
+ kIROp_FloatingPointModeOverrideDecoration,
+ getIntValue(getIntType(), (IRIntegerValue)mode));
+ }
+
IRInst* IRBuilder::emitSwizzle(
IRType* type,
IRInst* base,
@@ -6418,6 +6426,20 @@ namespace Slang
return false;
}
+ bool isIntegralScalarOrCompositeType(IRType* t)
+ {
+ if (!t)
+ return false;
+ switch (t->getOp())
+ {
+ case kIROp_VectorType:
+ case kIROp_MatrixType:
+ return isIntegralType((IRType*)t->getOperand(0));
+ default:
+ return isIntegralType(t);
+ }
+ }
+
void findAllInstsBreadthFirst(IRInst* inst, List<IRInst*>& outInsts)
{
Index index = outInsts.getCount();
@@ -6577,6 +6599,8 @@ namespace Slang
void IRInst::insertBefore(IRInst* other)
{
SLANG_ASSERT(other);
+ if (other->getPrevInst() == this)
+ return;
_insertAt(other->getPrevInst(), other, other->getParent());
}
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index e22e41f0c..41b140972 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -869,6 +869,8 @@ bool isTypeEqual(IRType* a, IRType* b);
// True if this is an integral IRBasicType, not including Char or Ptr types
bool isIntegralType(IRType* t);
+bool isIntegralScalarOrCompositeType(IRType* t);
+
void findAllInstsBreadthFirst(IRInst* inst, List<IRInst*>& outInsts);
// Constant Instructions
@@ -943,6 +945,13 @@ struct IRIntLit : IRConstant
IR_LEAF_ISA(IntLit);
};
+struct IRFloatLit : IRConstant
+{
+ IRFloatingPointValue getValue() { return value.floatVal; }
+
+ IR_LEAF_ISA(FloatLit);
+};
+
struct IRBoolLit : IRConstant
{
bool getValue() { return value.intVal != 0; }
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 149f5f6b9..8377246fb 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -3304,6 +3304,15 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
}
}
+ LoweredValInfo visitMakeRefExpr(MakeRefExpr* expr)
+ {
+ auto loweredBase = lowerLValueExpr(context, expr->base);
+
+ SLANG_ASSERT(loweredBase.flavor == LoweredValInfo::Flavor::Ptr);
+ loweredBase.flavor = LoweredValInfo::Flavor::Simple;
+ return loweredBase;
+ }
+
LoweredValInfo visitParenExpr(ParenExpr* expr)
{
return lowerSubExpr(expr->base);
@@ -4234,11 +4243,11 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
switch (baseVal.flavor)
{
case LoweredValInfo::Flavor::Simple:
- return LoweredValInfo::simple(
- builder->emitElementExtract(
- type,
- getSimpleVal(context, baseVal),
- indexVal));
+ return LoweredValInfo::simple(
+ builder->emitElementExtract(
+ type,
+ getSimpleVal(context, baseVal),
+ indexVal));
case LoweredValInfo::Flavor::Ptr:
return LoweredValInfo::ptr(
@@ -4416,7 +4425,11 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
LoweredValInfo visitOpenRefExpr(OpenRefExpr* expr)
{
- return lowerLValueExpr(context, expr->innerExpr);
+ auto info = lowerRValueExpr(context, expr->innerExpr);
+ SLANG_RELEASE_ASSERT(as<IRPtrTypeBase>(info.val->getFullType()));
+ SLANG_RELEASE_ASSERT(info.flavor == LoweredValInfo::Flavor::Simple);
+ info.flavor = LoweredValInfo::Flavor::Ptr;
+ return info;
}
};
@@ -4596,10 +4609,6 @@ LoweredValInfo lowerLValueExpr(
LValueExprLoweringVisitor visitor;
visitor.context = context;
auto info = visitor.dispatch(expr);
- if (as<RefType>(expr->type))
- {
- info.flavor = LoweredValInfo::Flavor::Ptr;
- }
return info;
}
@@ -4612,10 +4621,6 @@ LoweredValInfo lowerRValueExpr(
RValueExprLoweringVisitor visitor;
visitor.context = context;
auto info = visitor.dispatch(expr);
- if (as<RefType>(expr->type))
- {
- info.val = context->irBuilder->emitLoad(info.val);
- }
return info;
}
diff --git a/tests/compute/unbounded-array-of-array-syntax.slang.glsl b/tests/compute/unbounded-array-of-array-syntax.slang.glsl
index 6ee5d1c6b..b71b0cd7c 100644
--- a/tests/compute/unbounded-array-of-array-syntax.slang.glsl
+++ b/tests/compute/unbounded-array-of-array-syntax.slang.glsl
@@ -1,9 +1,9 @@
//TEST_IGNORE_FILE:
#version 450
+#extension GL_EXT_nonuniform_qualifier : require
layout(row_major) uniform;
layout(row_major) buffer;
-#extension GL_EXT_nonuniform_qualifier : require
layout(std430, binding = 1) buffer _S1 {
int _data[];
@@ -18,21 +18,21 @@ void main()
int index_0 = int(gl_GlobalInvocationID.x);
int innerIndex_0 = index_0 & 3;
+ int _S3 = nonuniformEXT(index_0 >> 2);
uint bufferCount_0;
uint bufferStride_0;
- (bufferCount_0) = (g_aoa_0[nonuniformEXT(index_0 >> 2)])._data.length();
- (bufferStride_0) = 0;
+ (bufferCount_0) = (g_aoa_0[_S3])._data.length(); (bufferStride_0) = 0;
int innerIndex_1;
if(uint(innerIndex_0) >= bufferCount_0)
{
- innerIndex_1 = int(bufferCount_0 - uint(1));
+ innerIndex_1 = int(bufferCount_0 - 1U);
}
else
{
innerIndex_1 = innerIndex_0;
}
- uint _S3 = uint(innerIndex_1);
- ((outputBuffer_0)._data[(uint(index_0))]) = ((g_aoa_0[nonuniformEXT(index_0 >> 2)])._data[(_S3)]);
+ uint _S4 = uint(innerIndex_1);
+ ((outputBuffer_0)._data[(uint(index_0))]) = ((g_aoa_0[_S3])._data[(_S4)]);
return;
}
diff --git a/tests/cross-compile/array-of-buffers.slang.glsl b/tests/cross-compile/array-of-buffers.slang.glsl
index 3dfe31d8d..1f436fad0 100644
--- a/tests/cross-compile/array-of-buffers.slang.glsl
+++ b/tests/cross-compile/array-of-buffers.slang.glsl
@@ -1,5 +1,7 @@
//TEST_IGNORE_FILE:
#version 450
+layout(row_major) uniform;
+layout(row_major) buffer;
struct SLANG_ParameterGroup_C_0
{
@@ -23,19 +25,15 @@ layout(std140) uniform _S2
S_0 _data;
} cb_0[3];
-
-layout(std430, binding = 2)
-readonly buffer _S3 {
+layout(std430, binding = 2) readonly buffer _S3 {
S_0 _data[];
} sb1_0[4];
-layout(std430, binding = 3)
-buffer _S4 {
+layout(std430, binding = 3) buffer _S4 {
vec4 _data[];
} sb2_0[5];
-layout(std430, binding = 4)
-readonly buffer _S5
+layout(std430, binding = 4) readonly buffer _S5
{
uint _data[];
} bb_0[6];
@@ -45,13 +43,12 @@ out vec4 _S6;
void main()
{
- vec4 _S7 = cb_0[C_0._data.index_0]._data.f_0;
+ S_0 _S7 = ((sb1_0[C_0._data.index_0])._data[(C_0._data.index_0)]);
+ vec4 _S8 = cb_0[C_0._data.index_0]._data.f_0 + _S7.f_0;
+ vec4 _S9 = _S8 + ((sb2_0[C_0._data.index_0])._data[(C_0._data.index_0)]);
+ uint _S10 = ((bb_0[C_0._data.index_0])._data[(int(C_0._data.index_0 * 4U))/4]);
- S_0 _S8 = sb1_0[C_0._data.index_0]._data[C_0._data.index_0];
+ _S6 = _S9 + vec4(float(_S10));
- vec4 _S9 = _S7 + _S8.f_0;
- vec4 _S10 = _S9 + sb2_0[C_0._data.index_0]._data[C_0._data.index_0];
- uint _S11 = bb_0[C_0._data.index_0]._data[int(C_0._data.index_0 * uint(4))/4];
- _S6 = _S10 + vec4(_S11);
return;
}
diff --git a/tests/cross-compile/array-of-buffers.slang.hlsl b/tests/cross-compile/array-of-buffers.slang.hlsl
index 37f4639a7..501b9c6db 100644
--- a/tests/cross-compile/array-of-buffers.slang.hlsl
+++ b/tests/cross-compile/array-of-buffers.slang.hlsl
@@ -1,5 +1,11 @@
//TEST_IGNORE_FILE:
+#pragma pack_matrix(column_major)
+#ifdef SLANG_HLSL_ENABLE_NVAPI
+#include "nvHLSLExtns.h"
+#endif
+#pragma warning(disable: 3557)
+
struct SLANG_ParameterGroup_C_0
{
uint index_0;
@@ -15,21 +21,18 @@ struct S_0
float4 f_0;
};
-ConstantBuffer<S_0> cb_0 [3] : register(b1);
-StructuredBuffer<S_0> sb1_0[4] : register(t0);
-RWStructuredBuffer<float4> sb2_0[5] : register(u0);
-ByteAddressBuffer bb_0[6] : register(t4);
+ConstantBuffer<S_0 > cb_0[int(3)] : register(b1);
+StructuredBuffer<S_0 > sb1_0[int(4)] : register(t0);
+RWStructuredBuffer<float4 > sb2_0[int(5)] : register(u0);
+ByteAddressBuffer bb_0[int(6)] : register(t4);
float4 main() : SV_TARGET
{
- float4 _S1 = cb_0[C_0.index_0].f_0;
-
- S_0 _S2 = sb1_0[C_0.index_0][C_0.index_0];
+ S_0 _S1 = sb1_0[C_0.index_0][C_0.index_0];
- float4 _S3 = _S1 + _S2.f_0;
- float4 _S4 = _S3 + sb2_0[C_0.index_0][C_0.index_0];
- uint _S5 = bb_0[C_0.index_0].Load(
- (int) (C_0.index_0 * (uint) 4));
+ float4 _S2 = cb_0[C_0.index_0].f_0 + _S1.f_0;
+ float4 _S3 = _S2 + sb2_0[C_0.index_0][C_0.index_0];
+ uint _S4 = bb_0[C_0.index_0].Load(int(C_0.index_0 * 4U));
- return _S4 + (float4) _S5;
+ return _S3 + (float4)float(_S4);
}
diff --git a/tests/cross-compile/dual-source-blending.slang.glsl b/tests/cross-compile/dual-source-blending.slang.glsl
index f10eb77a0..aa550b451 100644
--- a/tests/cross-compile/dual-source-blending.slang.glsl
+++ b/tests/cross-compile/dual-source-blending.slang.glsl
@@ -21,16 +21,16 @@ struct FragmentOutput_0
void main()
{
+ const vec4 _S4 = vec4(0.0, 0.0, 0.0, 0.0);
FragmentOutput_0 f_0;
- FragmentOutput_0 _S4 = { vec4(0.0, 0.0, 0.0, 0.0), vec4(0.0, 0.0, 0.0, 0.0) };
- f_0 = _S4;
+ f_0.a_0 = _S4;
+ f_0.b_0 = _S4;
f_0.a_0 = _S3;
f_0.b_0 = _S3;
-
FragmentOutput_0 _S5 = f_0;
- _S1 = _S5.a_0;
+ _S1 = f_0.a_0;
_S2 = _S5.b_0;
return;
diff --git a/tests/cross-compile/geometry-shader.slang.glsl b/tests/cross-compile/geometry-shader.slang.glsl
index 1664e8468..38dbd72ba 100644
--- a/tests/cross-compile/geometry-shader.slang.glsl
+++ b/tests/cross-compile/geometry-shader.slang.glsl
@@ -64,8 +64,8 @@ void main()
CoarseVertex_0 _S10[3] = { _S7, _S8, _S9 };
- int ii_0;
- ii_0 = 0;
+ int ii_0 = 0;
+
for(;;)
{
if(ii_0 < 3)
@@ -75,17 +75,14 @@ void main()
break;
}
- CoarseVertex_0 coarseVertex_0 = _S10[ii_0];
-
RasterVertex_0 rasterVertex_0;
- rasterVertex_0.position_0 = coarseVertex_0.position_1;
- rasterVertex_0.color_0 = coarseVertex_0.color_1;
- rasterVertex_0.id_0 = coarseVertex_0.id_1 + _S6;
-
+ rasterVertex_0.position_0 = _S10[ii_0].position_1;
+ rasterVertex_0.color_0 = _S10[ii_0].color_1;
+ rasterVertex_0.id_0 = _S10[ii_0].id_1 + _S6;
RasterVertex_0 _S11 = rasterVertex_0;
+ _S4 = rasterVertex_0.position_0;
+ _S5 = _S11.color_0;
- output_position = _S11.position_0;
- output_color = _S11.color_0;
gl_Layer = int(_S11.id_0);
EmitVertex();
diff --git a/tests/cross-compile/unknown-image-format.slang.glsl b/tests/cross-compile/unknown-image-format.slang.glsl
index 329405ab6..5ccc30767 100644
--- a/tests/cross-compile/unknown-image-format.slang.glsl
+++ b/tests/cross-compile/unknown-image-format.slang.glsl
@@ -3,6 +3,8 @@
#version 450
#extension GL_EXT_shader_image_load_formatted : require
+layout(row_major) uniform;
+layout(row_major) buffer;
struct SLANG_ParameterGroup_C_0
{
@@ -41,25 +43,24 @@ out vec4 _S2;
void main()
{
- const vec4 result_0 = vec4(0);
float _S3 = (imageLoad((gNoFormat_0), ivec2((C_0._data.index_0))).x);
- vec4 result_1 = result_0 + _S3;
+ vec4 _S4 = vec4(_S3);
- float _S4 = (imageLoad((gExplicitFormat_0), ivec2((C_0._data.index_0))).x);
- vec4 result_2 = result_1 + _S4;
+ float _S5 = (imageLoad((gExplicitFormat_0), ivec2((C_0._data.index_0))).x);
+ vec4 result_0 = _S4 + _S5;
- vec4 _S5 = (imageLoad((gBlock_noFormat_0), ivec2((C_0._data.index_0))));
- vec4 result_3 = result_2 + _S5;
+ vec4 _S6 = (imageLoad((gBlock_noFormat_0), ivec2((C_0._data.index_0))));
+ vec4 result_1 = result_0 + _S6;
- vec4 _S6 = (imageLoad((gBlock_explicitFormat_0), ivec2((C_0._data.index_0))));
- vec4 result_4 = result_3 + _S6;
+ vec4 _S7 = (imageLoad((gBlock_explicitFormat_0), ivec2((C_0._data.index_0))));
+ vec4 result_2 = result_1 + _S7;
- vec4 _S7 = (imageLoad((entryPointParams_noFormat_0), ivec2((C_0._data.index_0))));
- vec4 result_5 = result_4 + _S7;
+ vec4 _S8 = (imageLoad((entryPointParams_noFormat_0), ivec2((C_0._data.index_0))));
+ vec4 result_3 = result_2 + _S8;
- vec4 _S8 = (imageLoad((entryPointParams_explicitFormat_0), ivec2((C_0._data.index_0))));
- _S2 = result_5 + _S8;
+ vec4 _S9 = (imageLoad((entryPointParams_explicitFormat_0), ivec2((C_0._data.index_0))));
+ _S2 = result_3 + _S9;
return;
}
diff --git a/tests/cross-compile/vector-comparison.slang.glsl b/tests/cross-compile/vector-comparison.slang.glsl
index 77578a368..2497055a0 100644
--- a/tests/cross-compile/vector-comparison.slang.glsl
+++ b/tests/cross-compile/vector-comparison.slang.glsl
@@ -19,8 +19,6 @@ out vec4 _S2;
void main()
{
- vec4 v0_0 = params_0._data.a_0;
- vec4 v1_0 = params_0._data.b_0;
- _S2 = mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), equal(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), lessThan(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), greaterThan(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), lessThanEqual(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), greaterThanEqual(v0_0,v1_0)) + mix(vec4(3.00000000000000000000), vec4(2.00000000000000000000), notEqual(v0_0,v1_0));
+ _S2 = mix(vec4(3.0), vec4(2.0), (equal(params_0._data.a_0,params_0._data.b_0))) + mix(vec4(3.0), vec4(2.0), (lessThan(params_0._data.a_0,params_0._data.b_0))) + mix(vec4(3.0), vec4(2.0), (greaterThan(params_0._data.a_0,params_0._data.b_0))) + mix(vec4(3.0), vec4(2.0), (lessThanEqual(params_0._data.a_0,params_0._data.b_0))) + mix(vec4(3.0), vec4(2.0), (greaterThanEqual(params_0._data.a_0,params_0._data.b_0))) + mix(vec4(3.0), vec4(2.0), (notEqual(params_0._data.a_0,params_0._data.b_0)));
return;
}
diff --git a/tests/experimental/liveness/liveness-3.slang.expected b/tests/experimental/liveness/liveness-3.slang.expected
index dac9ff1bd..4dff6b37a 100644
--- a/tests/experimental/liveness/liveness-3.slang.expected
+++ b/tests/experimental/liveness/liveness-3.slang.expected
@@ -28,15 +28,15 @@ int calcThing_0(int offset_0)
{
int another_0[2];
livenessStart_0(another_0, 0);
- const int _S1[2] = { 1, 2 };
- another_0 = _S1;
+ another_0[0] = 1;
+ another_0[1] = 2;
int k_0;
- int _S2;
- int total_0;
livenessStart_1(k_0, 0);
k_0 = 0;
- livenessStart_1(_S2, 0);
- _S2 = offset_0;
+ int _S1;
+ livenessStart_1(_S1, 0);
+ _S1 = offset_0;
+ int total_0;
livenessStart_1(total_0, 0);
total_0 = 0;
for(;;)
@@ -50,15 +50,15 @@ int calcThing_0(int offset_0)
}
int idx_0[3];
livenessStart_2(idx_0, 0);
- const int _S3[3] = { 0, 0, 0 };
- idx_0 = _S3;
+ idx_0[0] = 0;
+ idx_0[1] = 0;
+ idx_0[2] = 0;
int i_0;
- int _S4;
- int _S5 = _S2;
livenessStart_1(i_0, 0);
i_0 = 0;
- livenessStart_1(_S4, 0);
- _S4 = _S5;
+ int _S2;
+ livenessStart_1(_S2, 0);
+ _S2 = _S1;
for(;;)
{
if(i_0 < 17)
@@ -70,74 +70,74 @@ int calcThing_0(int offset_0)
}
int modRange_0 = i_0 % 3;
another_0[i_0 & 1] = another_0[i_0 & 1] + modRange_0;
- int _S6 = i_0 % 3;
- int _S7;
- if(_S6 != 0)
+ int _S3 = i_0 % 3;
+ int _S4;
+ if(_S3 != 0)
{
- int _S8 = _S4;
- livenessEnd_0(_S4, 0);
- int _S9 = _S8 + 1;
- livenessStart_1(_S7, 0);
- _S7 = _S9;
+ int _S5 = _S2;
+ livenessEnd_0(_S2, 0);
+ int _S6 = _S5 + 1;
+ livenessStart_1(_S4, 0);
+ _S4 = _S6;
}
else
{
- int _S10 = _S4;
- livenessEnd_0(_S4, 0);
- livenessStart_1(_S7, 0);
- _S7 = _S10;
+ int _S7 = _S2;
+ livenessEnd_0(_S2, 0);
+ livenessStart_1(_S4, 0);
+ _S4 = _S7;
}
- idx_0[modRange_0] = idx_0[modRange_0] + (_S7 + i_0);
+ idx_0[modRange_0] = idx_0[modRange_0] + (_S4 + i_0);
i_0 = i_0 + 1;
- livenessStart_1(_S4, 0);
- int _S11 = _S7;
- livenessEnd_0(_S7, 0);
- _S4 = _S11;
+ livenessStart_1(_S2, 0);
+ int _S8 = _S4;
+ livenessEnd_0(_S4, 0);
+ _S2 = _S8;
}
livenessEnd_0(i_0, 0);
- livenessEnd_0(_S2, 0);
- int _S12 = (k_0 + 7) % 5;
- if(_S12 == 4)
+ livenessEnd_0(_S1, 0);
+ int _S9 = (k_0 + 7) % 5;
+ if(_S9 == 4)
{
- livenessEnd_0(_S4, 0);
+ livenessEnd_0(_S2, 0);
livenessEnd_1(idx_0, 0);
livenessEnd_0(k_0, 0);
livenessEnd_2(another_0, 0);
return total_0;
}
- int _S13 = idx_0[0] + idx_0[1];
- int _S14 = idx_0[2];
+ int _S10 = idx_0[0] + idx_0[1];
+ int _S11 = idx_0[2];
livenessEnd_1(idx_0, 0);
- int _S15 = _S13 + _S14;
- int _S16 = total_0;
+ int _S12 = _S10 + _S11;
+ int _S13 = total_0;
livenessEnd_0(total_0, 0);
- int total_1 = _S16 + _S15;
+ int total_1 = _S13 + _S12;
k_0 = k_0 + 1;
- livenessStart_1(_S2, 0);
- int _S17 = _S4;
- livenessEnd_0(_S4, 0);
- _S2 = _S17;
+ livenessStart_1(_S1, 0);
+ int _S14 = _S2;
+ livenessEnd_0(_S2, 0);
+ _S1 = _S14;
livenessStart_1(total_0, 0);
total_0 = total_1;
}
- livenessEnd_0(_S2, 0);
+ livenessEnd_0(_S1, 0);
livenessEnd_0(k_0, 0);
livenessEnd_2(another_0, 0);
- int _S18 = total_0;
+ int _S15 = total_0;
livenessEnd_0(total_0, 0);
- return - _S18;
+ return - _S15;
}
-layout(std430, binding = 0) buffer _S19 {
+layout(std430, binding = 0) buffer _S16 {
int _data[];
} outputBuffer_0;
layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
void main()
{
int index_0 = int(gl_GlobalInvocationID.x);
- uint _S20 = uint(index_0);
- int _S21 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(_S20)]) = _S21;
+ uint _S17 = uint(index_0);
+ int _S18 = calcThing_0(index_0);
+ ((outputBuffer_0)._data[(_S17)]) = _S18;
return;
}
diff --git a/tests/experimental/liveness/liveness-4.slang.expected b/tests/experimental/liveness/liveness-4.slang.expected
index 52c6ebb32..cd97f8057 100644
--- a/tests/experimental/liveness/liveness-4.slang.expected
+++ b/tests/experimental/liveness/liveness-4.slang.expected
@@ -22,8 +22,8 @@ int calcThing_0(int offset_0)
{
int another_0[2];
livenessStart_0(another_0, 0);
- const int _S1[2] = { 1, 2 };
- another_0 = _S1;
+ another_0[0] = 1;
+ another_0[1] = 2;
int k_0;
livenessStart_1(k_0, 0);
k_0 = 0;
@@ -52,8 +52,8 @@ int calcThing_0(int offset_0)
i_0 = i_0 + 1;
}
livenessEnd_0(i_0, 0);
- int _S2 = (k_0 + 7) % 5;
- if(_S2 == 4)
+ int _S1 = (k_0 + 7) % 5;
+ if(_S1 == 4)
{
livenessEnd_0(k_0, 0);
livenessEnd_1(another_0, 0);
@@ -66,16 +66,16 @@ int calcThing_0(int offset_0)
return -2;
}
-layout(std430, binding = 0) buffer _S3 {
+layout(std430, binding = 0) buffer _S2 {
int _data[];
} outputBuffer_0;
layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
void main()
{
int index_0 = int(gl_GlobalInvocationID.x);
- uint _S4 = uint(index_0);
- int _S5 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(_S4)]) = _S5;
+ uint _S3 = uint(index_0);
+ int _S4 = calcThing_0(index_0);
+ ((outputBuffer_0)._data[(_S3)]) = _S4;
return;
}
diff --git a/tests/experimental/liveness/liveness-5.slang.expected b/tests/experimental/liveness/liveness-5.slang.expected
index a8a9707d7..3693d3fde 100644
--- a/tests/experimental/liveness/liveness-5.slang.expected
+++ b/tests/experimental/liveness/liveness-5.slang.expected
@@ -22,12 +22,12 @@ int calcThing_0(int offset_0)
{
int another_0[2];
livenessStart_0(another_0, 0);
- const int _S1[2] = { 1, 2 };
- another_0 = _S1;
+ another_0[0] = 1;
+ another_0[1] = 2;
int k_0;
- int total_0;
livenessStart_1(k_0, 0);
k_0 = 0;
+ int total_0;
livenessStart_1(total_0, 0);
total_0 = 0;
for(;;)
@@ -55,12 +55,11 @@ int calcThing_0(int offset_0)
i_0 = i_0 + 1;
}
livenessEnd_0(i_0, 0);
- int _S2 = another_0[k_0 & 1];
- int _S3 = total_0;
+ int _S1 = total_0;
livenessEnd_0(total_0, 0);
- int total_1 = _S3 + _S2;
- int _S4 = (k_0 + 7) % 5;
- if(_S4 == 4)
+ int total_1 = _S1 + another_0[k_0 & 1];
+ int _S2 = (k_0 + 7) % 5;
+ if(_S2 == 4)
{
livenessEnd_0(k_0, 0);
livenessEnd_1(another_0, 0);
@@ -82,16 +81,16 @@ int calcThing_0(int offset_0)
return total_0;
}
-layout(std430, binding = 0) buffer _S5 {
+layout(std430, binding = 0) buffer _S3 {
int _data[];
} outputBuffer_0;
layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
void main()
{
int index_0 = int(gl_GlobalInvocationID.x);
- uint _S6 = uint(index_0);
- int _S7 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(_S6)]) = _S7;
+ uint _S4 = uint(index_0);
+ int _S5 = calcThing_0(index_0);
+ ((outputBuffer_0)._data[(_S4)]) = _S5;
return;
}
diff --git a/tests/experimental/liveness/liveness-6.slang.expected b/tests/experimental/liveness/liveness-6.slang.expected
index 402e19886..9c3bae815 100644
--- a/tests/experimental/liveness/liveness-6.slang.expected
+++ b/tests/experimental/liveness/liveness-6.slang.expected
@@ -22,12 +22,12 @@ int calcThing_0(int offset_0)
{
int another_0[2];
livenessStart_0(another_0, 0);
- const int _S1[2] = { 1, 2 };
- another_0 = _S1;
+ another_0[0] = 1;
+ another_0[1] = 2;
int k_0;
- int total_0;
livenessStart_1(k_0, 0);
k_0 = 0;
+ int total_0;
livenessStart_1(total_0, 0);
total_0 = 0;
for(;;)
@@ -41,8 +41,8 @@ int calcThing_0(int offset_0)
}
int arr_0[2];
livenessStart_0(arr_0, 0);
- const int _S2[2] = { 2, 3 };
- arr_0 = _S2;
+ arr_0[0] = 2;
+ arr_0[1] = 3;
int i_0;
livenessStart_1(i_0, 0);
i_0 = 0;
@@ -60,16 +60,15 @@ int calcThing_0(int offset_0)
i_0 = i_0 + 1;
}
livenessEnd_0(i_0, 0);
- int _S3 = k_0 & 1;
- int _S4 = another_0[_S3];
- int _S5 = total_0;
+ int _S1 = k_0 & 1;
+ int _S2 = total_0;
livenessEnd_0(total_0, 0);
- int total_1 = _S5 + _S4;
- int _S6 = arr_0[_S3];
+ int total_1 = _S2 + another_0[_S1];
+ int _S3 = arr_0[_S1];
livenessEnd_1(arr_0, 0);
- int total_2 = total_1 + _S6;
- int _S7 = (k_0 + 7) % 5;
- if(_S7 == 4)
+ int total_2 = total_1 + _S3;
+ int _S4 = (k_0 + 7) % 5;
+ if(_S4 == 4)
{
livenessEnd_0(k_0, 0);
livenessEnd_1(another_0, 0);
@@ -91,16 +90,16 @@ int calcThing_0(int offset_0)
return total_0;
}
-layout(std430, binding = 0) buffer _S8 {
+layout(std430, binding = 0) buffer _S5 {
int _data[];
} outputBuffer_0;
layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
void main()
{
int index_0 = int(gl_GlobalInvocationID.x);
- uint _S9 = uint(index_0);
- int _S10 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(_S9)]) = _S10;
+ uint _S6 = uint(index_0);
+ int _S7 = calcThing_0(index_0);
+ ((outputBuffer_0)._data[(_S6)]) = _S7;
return;
}
diff --git a/tests/experimental/liveness/liveness.slang.expected b/tests/experimental/liveness/liveness.slang.expected
index e50ecac5a..4a81b8855 100644
--- a/tests/experimental/liveness/liveness.slang.expected
+++ b/tests/experimental/liveness/liveness.slang.expected
@@ -22,9 +22,9 @@ int someSlowFunc_0(int a_0)
{
uint _S1 = uint(a_0);
uint v_0;
- int i_0;
livenessStart_0(v_0, 0);
v_0 = _S1;
+ int i_0;
livenessStart_1(i_0, 0);
i_0 = 0;
for(;;)
@@ -91,9 +91,9 @@ void main()
{
int index_0 = int(gl_GlobalInvocationID.x);
int i_2;
- int res_0;
livenessStart_1(i_2, 0);
i_2 = 0;
+ int res_0;
livenessStart_1(res_0, 0);
res_0 = index_0;
for(;;)
@@ -113,30 +113,33 @@ void main()
SomeStruct_0 _S8 = makeSomeStruct_0();
t_0 = _S8;
const int _S9[100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- SomeStruct_0 u_0 = { 0, 0, _S9 };
- SomeStruct_0 u_1;
+ SomeStruct_0 u_0;
if((v_1 & 256) != 0)
{
s_3.x_0 = ((anotherBuffer_0)._data[(uint(v_1 & 3))]);
t_0.x_0 = ((anotherBuffer_0)._data[(uint(v_1 & 3))]);
- livenessStart_2(u_1, 0);
- u_1 = u_0;
+ livenessStart_2(u_0, 0);
+ u_0.a_1 = 0;
+ u_0.x_0 = 0;
+ u_0.c_0 = _S9;
}
else
{
SomeStruct_0 x_1;
livenessStart_2(x_1, 0);
- x_1 = u_0;
+ x_1.a_1 = 0;
+ x_1.x_0 = 0;
+ x_1.c_0 = _S9;
x_1.x_0 = ((anotherBuffer_0)._data[(uint(v_1 & 3))]) + 1;
SomeStruct_0 _S10 = x_1;
livenessEnd_2(x_1, 0);
- livenessStart_2(u_1, 0);
- u_1 = _S10;
+ livenessStart_2(u_0, 0);
+ u_0 = _S10;
}
s_3.c_0[index_0 & 7] = s_3.c_0[index_0 & 7] + 1;
int _S11 = s_3.x_0 + t_0.x_0;
- SomeStruct_0 _S12 = u_1;
- livenessEnd_2(u_1, 0);
+ SomeStruct_0 _S12 = u_0;
+ livenessEnd_2(u_0, 0);
int _S13 = _S11 + _S12.x_0;
int _S14 = doThing_0(t_0);
int _S15 = _S13 + _S14;
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected
index 22affc22e..d921747af 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected
@@ -25,19 +25,17 @@ void main()
uvec3 _S3 = ((gl_LaunchSizeEXT));
int idx_0 = launchID_0.x;
RayDesc_0 ray_0;
- ray_0.Origin_0 = vec3(float(idx_0), 0.00000000000000000000, 0.00000000000000000000);
+ ray_0.Origin_0 = vec3(float(idx_0), 0.0, 0.0);
ray_0.TMin_0 = 0.00999999977648258209;
- ray_0.Direction_0 = vec3(0.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000);
- ray_0.TMax_0 = 10000.00000000000000000000;
- RayDesc_0 _S4 = ray_0;
+ ray_0.Direction_0 = vec3(0.0, 1.0, 0.0);
+ ray_0.TMax_0 = 10000.0;
hitObjectNV hitObj_0;
- hitObjectRecordMissNV(hitObj_0, uint(idx_0), _S4.Origin_0, _S4.TMin_0, _S4.Direction_0, _S4.TMax_0);
- RayDesc_0 _S5 = ray_0;
+ hitObjectRecordMissNV(hitObj_0, uint(idx_0), ray_0.Origin_0, ray_0.TMin_0, ray_0.Direction_0, ray_0.TMax_0);
hitObjectNV hitObj_1;
- hitObjectRecordMissNV(hitObj_1, uint(idx_0 + 1), _S5.Origin_0, _S5.TMin_0, _S5.Direction_0, _S5.TMax_0);
- bool _S6 = (hitObjectIsMissNV((hitObj_1)));
- uint _S7 = uint(int(_S6));
- ((outputBuffer_0)._data[(uint(idx_0))]) = _S7;
+ hitObjectRecordMissNV(hitObj_1, uint(idx_0 + 1), ray_0.Origin_0, ray_0.TMin_0, ray_0.Direction_0, ray_0.TMax_0);
+ bool _S4 = (hitObjectIsMissNV((hitObj_1)));
+ uint _S5 = uint(int(_S4));
+ ((outputBuffer_0)._data[(uint(idx_0))]) = _S5;
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected
index 847eab926..09e389c32 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected
@@ -55,17 +55,16 @@ uint calcValue_0(hitObjectNV hit_0)
uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hit_0)));
uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hit_0)));
uint hitKind_0 = (hitObjectGetHitKindNV((hit_0)));
- uint r_1 = 0U + hitKind_0 + instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0;
+ uint r_1 = hitKind_0 + instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0;
RayDesc_0 ray_1 = HitObject_GetRayDesc_0(hit_0);
- float _S6 = ray_1.TMin_0;
- uint r_2 = r_1 + uint(_S6 > 0.00000000000000000000) + uint(ray_1.TMax_0 < _S6);
+ uint r_2 = r_1 + uint(ray_1.TMin_0 > 0.0) + uint(ray_1.TMax_0 < ray_1.TMin_0);
SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0);
r_0 = r_2 + uint(objSomeValues_0.a_0);
}
else
{
- bool _S7 = (hitObjectIsMissNV((hit_0)));
- if(_S7)
+ bool _S6 = (hitObjectIsMissNV((hit_0)));
+ if(_S6)
{
r_0 = 1U;
}
@@ -77,29 +76,29 @@ uint calcValue_0(hitObjectNV hit_0)
return r_0;
}
-layout(std430, binding = 1) buffer _S8 {
+layout(std430, binding = 1) buffer _S7 {
uint _data[];
} outputBuffer_0;
void main()
{
- uvec3 _S9 = ((gl_LaunchIDEXT));
- ivec2 launchID_0 = ivec2(_S9.xy);
- uvec3 _S10 = ((gl_LaunchSizeEXT));
+ uvec3 _S8 = ((gl_LaunchIDEXT));
+ ivec2 launchID_0 = ivec2(_S8.xy);
+ uvec3 _S9 = ((gl_LaunchSizeEXT));
int idx_0 = launchID_0.x;
RayDesc_0 ray_2;
- ray_2.Origin_0 = vec3(float(idx_0), 0.00000000000000000000, 0.00000000000000000000);
+ ray_2.Origin_0 = vec3(float(idx_0), 0.0, 0.0);
ray_2.TMin_0 = 0.00999999977648258209;
- ray_2.Direction_0 = vec3(0.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000);
- ray_2.TMax_0 = 10000.00000000000000000000;
- RayDesc_0 _S11 = ray_2;
+ ray_2.Direction_0 = vec3(0.0, 1.0, 0.0);
+ ray_2.TMax_0 = 10000.0;
+ RayDesc_0 _S10 = ray_2;
hitObjectNV hitObj_0;
- hitObjectRecordHitWithIndexNV(hitObj_0, scene_0, int(uint(idx_0)), int(uint(idx_0 * 2)), int(uint(idx_0 * 3)), 0U, 0U, _S11.Origin_0, _S11.TMin_0, _S11.Direction_0, _S11.TMax_0, (0));
+ hitObjectRecordHitWithIndexNV(hitObj_0, scene_0, int(uint(idx_0)), int(uint(idx_0 * 2)), int(uint(idx_0 * 3)), 0U, 0U, _S10.Origin_0, _S10.TMin_0, _S10.Direction_0, _S10.TMax_0, (0));
uint r_3 = calcValue_0(hitObj_0);
- RayDesc_0 _S12 = ray_2;
+ RayDesc_0 _S11 = ray_2;
hitObjectNV hitObj_1;
- hitObjectRecordHitNV(hitObj_1, scene_0, int(uint(idx_0)), int(uint(idx_0 * 3)), int(uint(idx_0 * 2)), 0U, 0U, 4U, _S12.Origin_0, _S12.TMin_0, _S12.Direction_0, _S12.TMax_0, (0));
- uint _S13 = calcValue_0(hitObj_1);
- uint r_4 = r_3 + _S13;
+ hitObjectRecordHitNV(hitObj_1, scene_0, int(uint(idx_0)), int(uint(idx_0 * 3)), int(uint(idx_0 * 2)), 0U, 0U, 4U, _S11.Origin_0, _S11.TMin_0, _S11.Direction_0, _S11.TMax_0, (0));
+ uint _S12 = calcValue_0(hitObj_1);
+ uint r_4 = r_3 + _S12;
((outputBuffer_0)._data[(uint(idx_0))]) = r_4;
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected
index 33eb46da3..2bedf5743 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected
@@ -23,16 +23,15 @@ void main()
{
int idx_0 = int(gl_GlobalInvocationID.x);
RayDesc_0 ray_0;
- ray_0.Origin_0 = vec3(float(idx_0), 0.00000000000000000000, 0.00000000000000000000);
+ ray_0.Origin_0 = vec3(float(idx_0), 0.0, 0.0);
ray_0.TMin_0 = 0.00999999977648258209;
- ray_0.Direction_0 = vec3(0.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000);
- ray_0.TMax_0 = 10000.00000000000000000000;
- RayDesc_0 _S2 = ray_0;
+ ray_0.Direction_0 = vec3(0.0, 1.0, 0.0);
+ ray_0.TMax_0 = 10000.0;
hitObjectNV hitObj_0;
- hitObjectRecordMissNV(hitObj_0, uint(idx_0), _S2.Origin_0, _S2.TMin_0, _S2.Direction_0, _S2.TMax_0);
- bool _S3 = (hitObjectIsMissNV((hitObj_0)));
- uint _S4 = uint(int(_S3));
- ((outputBuffer_0)._data[(uint(idx_0))]) = _S4;
+ hitObjectRecordMissNV(hitObj_0, uint(idx_0), ray_0.Origin_0, ray_0.TMin_0, ray_0.Direction_0, ray_0.TMax_0);
+ bool _S2 = (hitObjectIsMissNV((hitObj_0)));
+ uint _S3 = uint(int(_S2));
+ ((outputBuffer_0)._data[(uint(idx_0))]) = _S3;
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected
index f250c1c92..58f06cfec 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected
@@ -41,7 +41,7 @@ uint calcValue_0(hitObjectNV hit_0)
uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hit_0)));
uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hit_0)));
SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0);
- r_0 = 0U + instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0 + uint(objSomeValues_0.a_0);
+ r_0 = instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0 + uint(objSomeValues_0.a_0);
}
else
{
@@ -80,36 +80,40 @@ void main()
uvec3 _S4 = ((gl_LaunchSizeEXT));
int idx_0 = launchID_0.x;
float _S5 = float(idx_0);
- SomeValues_0 someValues_0 = { idx_0, _S5 * 2.00000000000000000000 };
+ float _S6 = _S5 * 2.0;
RayDesc_0 ray_0;
- ray_0.Origin_0 = vec3(_S5, 0.00000000000000000000, 0.00000000000000000000);
+ ray_0.Origin_0 = vec3(_S5, 0.0, 0.0);
ray_0.TMin_0 = 0.00999999977648258209;
- ray_0.Direction_0 = vec3(0.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000);
- ray_0.TMax_0 = 10000.00000000000000000000;
- RayDesc_0 _S6 = ray_0;
- p_0 = someValues_0;
+ ray_0.Direction_0 = vec3(0.0, 1.0, 0.0);
+ ray_0.TMax_0 = 10000.0;
+ RayDesc_0 _S7 = ray_0;
+ p_0.a_0 = idx_0;
+ p_0.b_0 = _S6;
hitObjectNV hitObj_0;
- hitObjectTraceRayNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S6.Origin_0, _S6.TMin_0, _S6.Direction_0, _S6.TMax_0, (0));
+ hitObjectTraceRayNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S7.Origin_0, _S7.TMin_0, _S7.Direction_0, _S7.TMax_0, (0));
uint r_1 = calcValue_0(hitObj_0);
reorderThreadNV(hitObj_0);
+ float _S8 = _S5 * 4.0;
SomeValues_0 otherValues_0;
- SomeValues_0 _S7 = { idx_0 * -1, _S5 * 4.00000000000000000000 };
- otherValues_0 = _S7;
+ otherValues_0.a_0 = idx_0 * -1;
+ otherValues_0.b_0 = _S8;
HitObject_Invoke_0(scene_0, hitObj_0, otherValues_0);
- uint _S8 = calcValue_0(hitObj_0);
- uint r_2 = r_1 + _S8;
+ uint _S9 = calcValue_0(hitObj_0);
+ uint r_2 = r_1 + _S9;
reorderThreadNV(hitObj_0, uint(idx_0 & 3), 2U);
- SomeValues_0 _S9 = { idx_0 * -2, _S5 * 8.00000000000000000000 };
- otherValues_0 = _S9;
+ float _S10 = _S5 * 8.0;
+ otherValues_0.a_0 = idx_0 * -2;
+ otherValues_0.b_0 = _S10;
HitObject_Invoke_0(scene_0, hitObj_0, otherValues_0);
- uint _S10 = calcValue_0(hitObj_0);
- uint r_3 = r_2 + _S10;
+ uint _S11 = calcValue_0(hitObj_0);
+ uint r_3 = r_2 + _S11;
reorderThreadNV(uint(idx_0 & 1), 1U);
- SomeValues_0 _S11 = { idx_0 * -4, _S5 * 16.00000000000000000000 };
- otherValues_0 = _S11;
+ float _S12 = _S5 * 16.0;
+ otherValues_0.a_0 = idx_0 * -4;
+ otherValues_0.b_0 = _S12;
HitObject_Invoke_0(scene_0, hitObj_0, otherValues_0);
- uint _S12 = calcValue_0(hitObj_0);
- uint r_4 = r_3 + _S12;
+ uint _S13 = calcValue_0(hitObj_0);
+ uint r_4 = r_3 + _S13;
((outputBuffer_0)._data[(uint(idx_0))]) = r_4;
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected
index f6f6f132d..e6d31a3c8 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected
@@ -42,7 +42,7 @@ uint calcValue_0(hitObjectNV hit_0)
uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hit_0)));
uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hit_0)));
SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0);
- r_0 = 0U + instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0 + uint(objSomeValues_0.a_0);
+ r_0 = instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0 + uint(objSomeValues_0.a_0);
}
else
{
@@ -71,19 +71,20 @@ void main()
int _S5 = idx_0 / 4;
float currentTime_0 = float(_S5);
float _S6 = float(idx_0);
- SomeValues_0 someValues_0 = { idx_0, _S6 * 2.00000000000000000000 };
+ float _S7 = _S6 * 2.0;
RayDesc_0 ray_0;
- ray_0.Origin_0 = vec3(_S6, 0.00000000000000000000, 0.00000000000000000000);
+ ray_0.Origin_0 = vec3(_S6, 0.0, 0.0);
ray_0.TMin_0 = 0.00999999977648258209;
- ray_0.Direction_0 = vec3(0.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000);
- ray_0.TMax_0 = 10000.00000000000000000000;
- RayDesc_0 _S7 = ray_0;
- p_0 = someValues_0;
+ ray_0.Direction_0 = vec3(0.0, 1.0, 0.0);
+ ray_0.TMax_0 = 10000.0;
+ RayDesc_0 _S8 = ray_0;
+ p_0.a_0 = idx_0;
+ p_0.b_0 = _S7;
hitObjectNV hitObj_0;
- hitObjectTraceRayMotionNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S7.Origin_0, _S7.TMin_0, _S7.Direction_0, _S7.TMax_0, currentTime_0, (0));
- uint _S8 = uint(idx_0);
- uint _S9 = calcValue_0(hitObj_0);
- ((outputBuffer_0)._data[(_S8)]) = _S9;
+ hitObjectTraceRayMotionNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S8.Origin_0, _S8.TMin_0, _S8.Direction_0, _S8.TMax_0, currentTime_0, (0));
+ uint _S9 = uint(idx_0);
+ uint _S10 = calcValue_0(hitObj_0);
+ ((outputBuffer_0)._data[(_S9)]) = _S10;
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected
index 16099b5e2..9b5a4d193 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected
@@ -41,7 +41,7 @@ uint calcValue_0(hitObjectNV hit_0)
uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hit_0)));
uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hit_0)));
SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0);
- r_0 = 0U + instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0 + uint(objSomeValues_0.a_0);
+ r_0 = instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0 + uint(objSomeValues_0.a_0);
}
else
{
@@ -68,19 +68,20 @@ void main()
uvec3 _S4 = ((gl_LaunchSizeEXT));
int idx_0 = launchID_0.x;
float _S5 = float(idx_0);
- SomeValues_0 someValues_0 = { idx_0, _S5 * 2.00000000000000000000 };
+ float _S6 = _S5 * 2.0;
RayDesc_0 ray_0;
- ray_0.Origin_0 = vec3(_S5, 0.00000000000000000000, 0.00000000000000000000);
+ ray_0.Origin_0 = vec3(_S5, 0.0, 0.0);
ray_0.TMin_0 = 0.00999999977648258209;
- ray_0.Direction_0 = vec3(0.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000);
- ray_0.TMax_0 = 10000.00000000000000000000;
- RayDesc_0 _S6 = ray_0;
- p_0 = someValues_0;
+ ray_0.Direction_0 = vec3(0.0, 1.0, 0.0);
+ ray_0.TMax_0 = 10000.0;
+ RayDesc_0 _S7 = ray_0;
+ p_0.a_0 = idx_0;
+ p_0.b_0 = _S6;
hitObjectNV hitObj_0;
- hitObjectTraceRayNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S6.Origin_0, _S6.TMin_0, _S6.Direction_0, _S6.TMax_0, (0));
- uint _S7 = uint(idx_0);
- uint _S8 = calcValue_0(hitObj_0);
- ((outputBuffer_0)._data[(_S7)]) = _S8;
+ hitObjectTraceRayNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S7.Origin_0, _S7.TMin_0, _S7.Direction_0, _S7.TMax_0, (0));
+ uint _S8 = uint(idx_0);
+ uint _S9 = calcValue_0(hitObj_0);
+ ((outputBuffer_0)._data[(_S8)]) = _S9;
return;
}
diff --git a/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl b/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl
index bad4dd370..79c6232f3 100644
--- a/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl
+++ b/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl
@@ -55,11 +55,9 @@ struct RayDesc_0
void TraceMotionRay_0(accelerationStructureEXT AccelerationStructure_0, uint RayFlags_0, uint InstanceInclusionMask_0, uint RayContributionToHitGroupIndex_0, uint MultiplierForGeometryContributionToHitGroupIndex_0, uint MissShaderIndex_0, RayDesc_0 Ray_0, float CurrentTime_0, inout ShadowRay_0 Payload_0)
{
p_0 = Payload_0;
-
traceRayMotionNV(AccelerationStructure_0, RayFlags_0, InstanceInclusionMask_0, RayContributionToHitGroupIndex_0, MultiplierForGeometryContributionToHitGroupIndex_0, MissShaderIndex_0, Ray_0.Origin_0, Ray_0.TMin_0, Ray_0.Direction_0, Ray_0.TMax_0, CurrentTime_0, (0));
Payload_0 = p_0;
-
return;
}
@@ -68,7 +66,7 @@ uniform accelerationStructureEXT as_0;
float saturate_0(float x_0)
{
- float _S2 = clamp(x_0, float(0), float(1));
+ float _S2 = clamp(x_0, 0.0, 1.0);
return _S2;
}
@@ -85,11 +83,9 @@ ReflectionRay_0 p_1;
void TraceRay_0(accelerationStructureEXT AccelerationStructure_1, uint RayFlags_1, uint InstanceInclusionMask_1, uint RayContributionToHitGroupIndex_1, uint MultiplierForGeometryContributionToHitGroupIndex_1, uint MissShaderIndex_1, RayDesc_0 Ray_1, inout ReflectionRay_0 Payload_1)
{
p_1 = Payload_1;
-
traceRayEXT(AccelerationStructure_1, RayFlags_1, InstanceInclusionMask_1, RayContributionToHitGroupIndex_1, MultiplierForGeometryContributionToHitGroupIndex_1, MissShaderIndex_1, Ray_1.Origin_0, Ray_1.TMin_0, Ray_1.Direction_0, Ray_1.TMax_0, (1));
Payload_1 = p_1;
-
return;
}
@@ -99,8 +95,6 @@ uniform image2D outputImage_0;
void main()
{
- float atten_0;
-
uvec3 _S3 = ((gl_LaunchIDEXT));
ivec2 launchID_0 = ivec2(_S3.xy);
@@ -108,8 +102,8 @@ void main()
ivec2 launchSize_0 = ivec2(_S4.xy);
- float _S5 = (float(launchID_0.x) + 0.50000000000000000000) / float(launchSize_0.x);
- float _S6 = (float(launchID_0.y) + 0.50000000000000000000) / float(launchSize_0.y);
+ float _S5 = (float(launchID_0.x) + 0.5) / float(launchSize_0.x);
+ float _S6 = (float(launchID_0.y) + 0.5) / float(launchSize_0.y);
vec2 inUV_0 = vec2(_S5, _S6);
@@ -118,27 +112,28 @@ void main()
vec3 P_0 = _S7.xyz;
vec4 _S8 = (texture(sampler2D(samplerNormal_0,sampler_0), (inUV_0)));
- vec3 N_0 = _S8.xyz * 2.00000000000000000000 - 1.00000000000000000000;
+ vec3 N_0 = _S8.xyz * 2.0 - 1.0;
vec3 lightDelta_0 = ubo_0._data.light_0.position_0.xyz - P_0;
float lightDist_0 = length(lightDelta_0);
vec3 L_0 = normalize(lightDelta_0);
- float _S9 = 1.00000000000000000000 / (lightDist_0 * lightDist_0);
+ float _S9 = 1.0 / (lightDist_0 * lightDist_0);
RayDesc_0 ray_0;
ray_0.Origin_0 = P_0;
- ray_0.TMin_0 = 0.00000100000000000000;
+ ray_0.TMin_0 = 0.00000099999999747524;
ray_0.Direction_0 = lightDelta_0;
ray_0.TMax_0 = lightDist_0;
ShadowRay_0 shadowRay_0;
- shadowRay_0.hitDistance_0 = float(0);
+ shadowRay_0.hitDistance_0 = 0.0;
+ TraceMotionRay_0(as_0, 1U, 255U, 0U, 0U, 2U, ray_0, 1.0, shadowRay_0);
- TraceMotionRay_0(as_0, uint(1), uint(255), uint(0), uint(0), uint(2), ray_0, float(1), shadowRay_0);
+ float atten_0;
if(shadowRay_0.hitDistance_0 < lightDist_0)
{
- atten_0 = 0.00000000000000000000;
+ atten_0 = 0.0;
}
else
{
@@ -154,8 +149,8 @@ void main()
vec3 color_2 = _S10 * _S12 * atten_0;
ReflectionRay_0 reflectionRay_0;
- TraceRay_0(as_0, uint(1), uint(255), uint(0), uint(0), uint(2), ray_0, reflectionRay_0);
+ TraceRay_0(as_0, 1U, 255U, 0U, 0U, 2U, ray_0, reflectionRay_0);
- imageStore((outputImage_0), ivec2((uvec2(launchID_0))), vec4(color_2 + reflectionRay_0.color_1, 1.00000000000000000000));
+ imageStore((outputImage_0), ivec2((uvec2(launchID_0))), vec4(color_2 + reflectionRay_0.color_1, 1.0));
return;
} \ No newline at end of file
diff --git a/tests/pipeline/rasterization/mesh/hello.slang.glsl b/tests/pipeline/rasterization/mesh/hello.slang.glsl
index c2c35915a..3a0848dcb 100644
--- a/tests/pipeline/rasterization/mesh/hello.slang.glsl
+++ b/tests/pipeline/rasterization/mesh/hello.slang.glsl
@@ -2,8 +2,9 @@
#extension GL_EXT_mesh_shader : require
layout(row_major) uniform;
layout(row_major) buffer;
-const vec3 colors_0[3] = { vec3(1.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000), vec3(0.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000), vec3(1.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000) };
-const vec2 positions_0[3] = { vec2(0.00000000000000000000, -0.50000000000000000000), vec2(0.50000000000000000000, 0.50000000000000000000), vec2(-0.50000000000000000000, 0.50000000000000000000) };
+const vec3 colors_0[3] = { vec3(1.0, 1.0, 0.0), vec3(0.0, 1.0, 1.0), vec3(1.0, 0.0, 1.0) };
+const vec2 positions_0[3] = { vec2(0.0, -0.5), vec2(0.5, 0.5), vec2(-0.5, 0.5) };
+
layout(location = 0)
out vec3 _S1[3];
@@ -23,9 +24,8 @@ void main()
SetMeshOutputsEXT(3U, 1U);
if(gl_LocalInvocationIndex < 3U)
{
- vec3 _S2 = colors_0[gl_LocalInvocationIndex];
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(positions_0[gl_LocalInvocationIndex], 0.00000000000000000000, 1.00000000000000000000);
- _S1[gl_LocalInvocationIndex] = _S2;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(positions_0[gl_LocalInvocationIndex], 0.0, 1.0);
+ _S1[gl_LocalInvocationIndex] = colors_0[gl_LocalInvocationIndex];
}
else
{
diff --git a/tests/pipeline/rasterization/mesh/hello.slang.hlsl b/tests/pipeline/rasterization/mesh/hello.slang.hlsl
index ea41895b1..a10dc6884 100644
--- a/tests/pipeline/rasterization/mesh/hello.slang.hlsl
+++ b/tests/pipeline/rasterization/mesh/hello.slang.hlsl
@@ -2,24 +2,26 @@
#ifdef SLANG_HLSL_ENABLE_NVAPI
#include "nvHLSLExtns.h"
#endif
+#pragma warning(disable: 3557)
-static const float3 colors_0[int(3)] = { float3(1.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000), float3(0.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000), float3(1.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000) };
-static const float2 positions_0[int(3)] = { float2(0.00000000000000000000, -0.50000000000000000000), float2(0.50000000000000000000, 0.50000000000000000000), float2(-0.50000000000000000000, 0.50000000000000000000) };
+static const float3 colors_0[int(3)] = { float3(1.0, 1.0, 0.0), float3(0.0, 1.0, 1.0), float3(1.0, 0.0, 1.0) };
+static const float2 positions_0[int(3)] = { float2(0.0, -0.5), float2(0.5, 0.5), float2(-0.5, 0.5) };
struct Vertex_0
{
float4 pos_0 : SV_Position;
float3 color_0 : Color;
};
+[shader("mesh")]
[numthreads(3, 1, 1)]
[outputtopology("triangle")]
-void main(uint tig_0 : SV_GROUPINDEX, vertices out Vertex_0 verts_0[int(3)], indices out uint3 triangles_0[int(1)])
+void main(uint tig_0 : SV_GROUPINDEX, vertices vertices out Vertex_0 verts_0[int(3)], indices indices out uint3 triangles_0[int(1)])
{
SetMeshOutputCounts(3U, 1U);
if(tig_0 < 3U)
{
- Vertex_0 _S1 = { float4(positions_0[tig_0], 0.00000000000000000000, 1.00000000000000000000), colors_0[tig_0] };
- verts_0[tig_0] = _S1;
+ verts_0[tig_0].pos_0 = float4(positions_0[tig_0], 0.0, 1.0);
+ verts_0[tig_0].color_0 = colors_0[tig_0];
}
else
{
diff --git a/tests/pipeline/rasterization/mesh/hlsl-syntax.slang.glsl b/tests/pipeline/rasterization/mesh/hlsl-syntax.slang.glsl
index 96d681c5c..5e059a8a3 100644
--- a/tests/pipeline/rasterization/mesh/hlsl-syntax.slang.glsl
+++ b/tests/pipeline/rasterization/mesh/hlsl-syntax.slang.glsl
@@ -2,8 +2,8 @@
#extension GL_EXT_mesh_shader : require
layout(row_major) uniform;
layout(row_major) buffer;
-const vec3 colors_0[3] = { vec3(1.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000), vec3(0.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000), vec3(1.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000) };
-const vec2 positions_0[3] = { vec2(0.00000000000000000000, -0.50000000000000000000), vec2(0.50000000000000000000, 0.50000000000000000000), vec2(-0.50000000000000000000, 0.50000000000000000000) };
+const vec3 colors_0[3] = { vec3(1.0, 1.0, 0.0), vec3(0.0, 1.0, 1.0), vec3(1.0, 0.0, 1.0) };
+const vec2 positions_0[3] = { vec2(0.0, -0.5), vec2(0.5, 0.5), vec2(-0.5, 0.5) };
layout(location = 0)
out vec3 _S1[3];
@@ -13,13 +13,13 @@ out gl_MeshPerVertexEXT
} gl_MeshVerticesEXT[3];
+out uvec3 gl_PrimitiveTriangleIndicesEXT[1];
void foo_0(uint _S2)
{
if(_S2 < 3U)
{
- vec3 _S3 = colors_0[_S2];
- gl_MeshVerticesEXT[_S2].gl_Position = vec4(positions_0[_S2], 0.00000000000000000000, 1.00000000000000000000);
- _S1[_S2] = _S3;
+ gl_MeshVerticesEXT[_S2].gl_Position = vec4(positions_0[_S2], 0.0, 1.0);
+ _S1[_S2] = colors_0[_S2];
}
else
{
diff --git a/tests/pipeline/rasterization/mesh/passing-outputs.slang.glsl b/tests/pipeline/rasterization/mesh/passing-outputs.slang.glsl
index db8a69ef3..31c2f0db2 100644
--- a/tests/pipeline/rasterization/mesh/passing-outputs.slang.glsl
+++ b/tests/pipeline/rasterization/mesh/passing-outputs.slang.glsl
@@ -17,57 +17,65 @@ struct Vertex_0
void just_two_0(out Vertex_0 v_0, out Vertex_0 w_0)
{
- Texes_0 _S1 = { vec2(0.00000000000000000000, 0.00000000000000000000), vec4(0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000) };
- Vertex_0 _S2 = { vec4(0.00000000000000000000), vec3(1.00000000000000000000), _S1 };
- v_0 = _S2;
- w_0 = v_0;
+ const vec4 _S1 = vec4(0.0);
+ const vec3 _S2 = vec3(1.0);
+ Texes_0 _S3 = { vec2(0.0, 0.0), vec4(0.0, 0.0, 0.0, 0.0) };
+ v_0.pos_0 = _S1;
+ v_0.col_0 = _S2;
+ v_0.ts_0 = _S3;
+ w_0.pos_0 = _S1;
+ w_0.col_0 = _S2;
+ w_0.ts_0 = _S3;
return;
}
void just_one_0(out Vertex_0 v_1)
{
- Texes_0 _S3 = { vec2(0.00000000000000000000, 0.00000000000000000000), vec4(0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000) };
- Vertex_0 _S4 = { vec4(0.00000000000000000000), vec3(1.00000000000000000000), _S3 };
- v_1 = _S4;
+ const vec3 _S4 = vec3(1.0);
+ Texes_0 _S5 = { vec2(0.0, 0.0), vec4(0.0, 0.0, 0.0, 0.0) };
+ v_1.pos_0 = vec4(0.0);
+ v_1.col_0 = _S4;
+ v_1.ts_0 = _S5;
return;
}
void part_of_one_0(out vec4 p_0)
{
- p_0 = vec4(1.00000000000000000000, 2.00000000000000000000, 3.00000000000000000000, 4.00000000000000000000);
+ p_0 = vec4(1.0, 2.0, 3.0, 4.0);
return;
}
void write_struct_0(out Texes_0 t_0)
{
- t_0.tex1_0 = vec2(0.00000000000000000000);
- t_0.tex2_0 = vec4(1.00000000000000000000);
+ t_0.tex1_0 = vec2(0.0);
+ t_0.tex2_0 = vec4(1.0);
return;
}
layout(location = 0)
-out vec3 _S5[3];
+out vec3 _S6[3];
layout(location = 1)
-out vec2 _S6[3];
+out vec2 _S7[3];
layout(location = 2)
-out vec4 _S7[3];
+out vec4 _S8[3];
out gl_MeshPerVertexEXT
{
vec4 gl_Position;
} gl_MeshVerticesEXT[3];
+out uvec3 gl_PrimitiveTriangleIndicesEXT[1];
void everything_0()
{
- vec3 _S8 = vec3(1.00000000000000000000);
- vec2 _S9 = vec2(0.00000000000000000000, 0.00000000000000000000);
- vec4 _S10 = vec4(0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000);
- gl_MeshVerticesEXT[0U].gl_Position = vec4(0.00000000000000000000);
- _S5[0U] = _S8;
+ vec3 _S9 = vec3(1.0);
+ vec2 _S10 = vec2(0.0, 0.0);
+ vec4 _S11 = vec4(0.0, 0.0, 0.0, 0.0);
+ gl_MeshVerticesEXT[0U].gl_Position = vec4(0.0);
_S6[0U] = _S9;
_S7[0U] = _S10;
+ _S8[0U] = _S11;
return;
}
@@ -79,66 +87,61 @@ void a_0()
void b_0()
{
- Vertex_0 _S11;
Vertex_0 _S12;
- just_two_0(_S12, _S11);
- Vertex_0 _S13 = _S12;
+ Vertex_0 _S13;
+ just_two_0(_S13, _S12);
+ Vertex_0 _S14 = _S13;
gl_MeshVerticesEXT[0U].gl_Position = _S13.pos_0;
- _S5[0U] = _S13.col_0;
- Texes_0 _S14 = _S13.ts_0;
- _S6[0U] = _S14.tex1_0;
- _S7[0U] = _S14.tex2_0;
- Vertex_0 _S15 = _S11;
- gl_MeshVerticesEXT[0U].gl_Position = _S15.pos_0;
- _S5[0U] = _S15.col_0;
- Texes_0 _S16 = _S15.ts_0;
- _S6[0U] = _S16.tex1_0;
- _S7[0U] = _S16.tex2_0;
+ _S6[0U] = _S14.col_0;
+ _S7[0U] = _S14.ts_0.tex1_0;
+ _S8[0U] = _S14.ts_0.tex2_0;
+ Vertex_0 _S15 = _S12;
+ gl_MeshVerticesEXT[0U].gl_Position = _S12.pos_0;
+ _S6[0U] = _S15.col_0;
+ _S7[0U] = _S15.ts_0.tex1_0;
+ _S8[0U] = _S15.ts_0.tex2_0;
return;
}
-void c_0(uint _S17)
+void c_0(uint _S16)
{
- Vertex_0 _S18;
- just_one_0(_S18);
- Vertex_0 _S19 = _S18;
- gl_MeshVerticesEXT[_S17].gl_Position = _S19.pos_0;
- _S5[_S17] = _S19.col_0;
- Texes_0 _S20 = _S19.ts_0;
- _S6[_S17] = _S20.tex1_0;
- _S7[_S17] = _S20.tex2_0;
+ Vertex_0 _S17;
+ just_one_0(_S17);
+ Vertex_0 _S18 = _S17;
+ gl_MeshVerticesEXT[_S16].gl_Position = _S17.pos_0;
+ _S6[_S16] = _S18.col_0;
+ _S7[_S16] = _S18.ts_0.tex1_0;
+ _S8[_S16] = _S18.ts_0.tex2_0;
return;
}
-void d_0(uint _S21)
+void d_0(uint _S19)
{
- Vertex_0 _S22;
- Vertex_0 _S23;
- just_two_0(_S23, _S22);
- Vertex_0 _S24 = _S23;
- gl_MeshVerticesEXT[_S21].gl_Position = _S24.pos_0;
- _S5[_S21] = _S24.col_0;
- Texes_0 _S25 = _S24.ts_0;
- _S6[_S21] = _S25.tex1_0;
- _S7[_S21] = _S25.tex2_0;
- Vertex_0 _S26 = _S22;
- gl_MeshVerticesEXT[0U].gl_Position = _S26.pos_0;
- _S5[0U] = _S26.col_0;
- Texes_0 _S27 = _S26.ts_0;
- _S6[0U] = _S27.tex1_0;
- _S7[0U] = _S27.tex2_0;
+ Vertex_0 _S20;
+ Vertex_0 _S21;
+ just_two_0(_S21, _S20);
+ Vertex_0 _S22 = _S21;
+ gl_MeshVerticesEXT[_S19].gl_Position = _S21.pos_0;
+ _S6[_S19] = _S22.col_0;
+ _S7[_S19] = _S22.ts_0.tex1_0;
+ _S8[_S19] = _S22.ts_0.tex2_0;
+ Vertex_0 _S23 = _S20;
+ gl_MeshVerticesEXT[0U].gl_Position = _S20.pos_0;
+ _S6[0U] = _S23.col_0;
+ _S7[0U] = _S23.ts_0.tex1_0;
+ _S8[0U] = _S23.ts_0.tex2_0;
return;
}
-void e_0(uint _S28)
+void e_0(uint _S24)
{
- part_of_one_0(gl_MeshVerticesEXT[_S28].gl_Position);
- Texes_0 _S29;
- write_struct_0(_S29);
- Texes_0 _S30 = _S29;
- _S6[_S28] = _S30.tex1_0;
- _S7[_S28] = _S30.tex2_0;
- part_of_one_0(_S7[_S28]);
+ part_of_one_0(gl_MeshVerticesEXT[_S24].gl_Position);
+ Texes_0 _S25;
+ write_struct_0(_S25);
+ Texes_0 _S26 = _S25;
+ _S7[_S24] = _S25.tex1_0;
+ _S8[_S24] = _S26.tex2_0;
+ part_of_one_0(_S8[_S24]);
return;
}
diff --git a/tests/pipeline/rasterization/mesh/primitive-output.slang.glsl b/tests/pipeline/rasterization/mesh/primitive-output.slang.glsl
index 6ff2dbce8..35efcf4af 100644
--- a/tests/pipeline/rasterization/mesh/primitive-output.slang.glsl
+++ b/tests/pipeline/rasterization/mesh/primitive-output.slang.glsl
@@ -2,8 +2,9 @@
#extension GL_EXT_mesh_shader : require
layout(row_major) uniform;
layout(row_major) buffer;
-const vec3 colors_0[3] = { vec3(1.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000), vec3(0.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000), vec3(1.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000) };
-const vec2 positions_0[3] = { vec2(0.00000000000000000000, -0.50000000000000000000), vec2(0.50000000000000000000, 0.50000000000000000000), vec2(-0.50000000000000000000, 0.50000000000000000000) };
+const vec3 colors_0[3] = { vec3(1.0, 1.0, 0.0), vec3(0.0, 1.0, 1.0), vec3(1.0, 0.0, 1.0) };
+const vec2 positions_0[3] = { vec2(0.0, -0.5), vec2(0.5, 0.5), vec2(-0.5, 0.5) };
+out uvec3 gl_PrimitiveTriangleIndicesEXT[1];
layout(location = 0)
out vec3 _S1[3];
@@ -30,9 +31,8 @@ void main()
SetMeshOutputsEXT(3U, 1U);
if(gl_LocalInvocationIndex < 3U)
{
- vec3 _S3 = colors_0[gl_LocalInvocationIndex];
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(positions_0[gl_LocalInvocationIndex], 0.00000000000000000000, 1.00000000000000000000);
- _S1[gl_LocalInvocationIndex] = _S3;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(positions_0[gl_LocalInvocationIndex], 0.0, 1.0);
+ _S1[gl_LocalInvocationIndex] = colors_0[gl_LocalInvocationIndex];
}
else
{
@@ -40,7 +40,7 @@ void main()
if(gl_LocalInvocationIndex < 1U)
{
gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0U, 1U, 2U);
- _S2[gl_LocalInvocationIndex] = vec3(0.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000);
+ _S2[gl_LocalInvocationIndex] = vec3(0.0, 0.0, 1.0);
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveID = int(gl_LocalInvocationIndex);
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_CullPrimitiveEXT = false;
}
diff --git a/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl b/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl
index 389dae05a..04ef5a6fe 100644
--- a/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl
+++ b/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl
@@ -74,8 +74,7 @@ void main()
rayQueryEXT query_0;
MyRayPayload_0 payload_5;
- MyRayPayload_0 _S2 = { -1 };
- payload_5 = _S2;
+ payload_5.value_1 = -1;
rayQueryInitializeEXT((query_0), (myAccelerationStructure_0), (C_0._data.rayFlags_0 | 512), (C_0._data.instanceMask_0), (C_0._data.origin_0), (C_0._data.tMin_0), (C_0._data.direction_0), (C_0._data.tMax_0));
MyProceduralHitAttrs_0 committedProceduralAttrs_0;
@@ -83,37 +82,34 @@ void main()
for(;;)
{
- bool _S3 = rayQueryProceedEXT(query_0);
+ bool _S2 = rayQueryProceedEXT(query_0);
- if(!_S3)
+ if(!_S2)
{
break;
}
- uint _S4 = (rayQueryGetIntersectionTypeEXT((query_0), false));
+ uint _S3 = (rayQueryGetIntersectionTypeEXT((query_0), false));
MyProceduralHitAttrs_0 committedProceduralAttrs_1;
- switch(_S4)
+ switch(_S3)
{
case 1U:
{
MyProceduralHitAttrs_0 candidateProceduralAttrs_0;
- MyProceduralHitAttrs_0 _S5 = { 0 };
+ candidateProceduralAttrs_0.value_0 = 0;
+ float tHit_1 = 0.0;
+ bool _S4 = myProceduralIntersection_0(tHit_1, candidateProceduralAttrs_0);
- candidateProceduralAttrs_0 = _S5;
- float tHit_1;
- tHit_1 = 0.00000000000000000000;
- bool _S6 = myProceduralIntersection_0(tHit_1, candidateProceduralAttrs_0);
-
- if(_S6)
+ if(_S4)
{
- bool _S7 = myProceduralAnyHit_0(payload_5);
+ bool _S5 = myProceduralAnyHit_0(payload_5);
- if(_S7)
+ if(_S5)
{
rayQueryGenerateIntersectionEXT(query_0, tHit_1);
- MyProceduralHitAttrs_0 _S8 = candidateProceduralAttrs_0;
+ MyProceduralHitAttrs_0 _S6 = candidateProceduralAttrs_0;
if(C_0._data.shouldStopAtFirstHit_0 != 0U)
{
rayQueryTerminateEXT(query_0);
@@ -122,7 +118,7 @@ void main()
{
}
- committedProceduralAttrs_1 = _S8;
+ committedProceduralAttrs_1 = _S6;
}
else
@@ -145,9 +141,9 @@ void main()
case 0U:
{
- bool _S9 = myTriangleAnyHit_0(payload_5);
+ bool _S7 = myTriangleAnyHit_0(payload_5);
- if(_S9)
+ if(_S7)
{
rayQueryConfirmIntersectionEXT(query_0);
if(C_0._data.shouldStopAtFirstHit_0 != 0U)
@@ -179,9 +175,9 @@ void main()
}
- uint _S10 = (rayQueryGetIntersectionTypeEXT((query_0), true));
+ uint _S8 = (rayQueryGetIntersectionTypeEXT((query_0), true));
- switch(_S10)
+ switch(_S8)
{
case 1U:
{