Some large shaders exhibit a behavior where phi nodes are created for resources, in which one of the possible incoming values is undef. This gets cleaned up later such that there are no undef resources left. However the fail-undef-resources pass has already failed compilation by that point. The fix is to change that pass to invalidate-undef-resources and replace the undefs with a special invalid value, such that we can produce an error later if still necessary, when optimization passes have been run such that temporary undef resources have been eliminated.
The clang type we generate for HLSL vectors contains a single field h of type DependentSizedExtVectorType, which shows up as an int[4] in DWARF. This change specifically emits debug info for x, y, z and w fields instead.
With this change, we also stop emitting a vector member for operator[], whose implementation was marked "external" so I don't think it'll have any impact.
FXC treats scalars, vector1s and matrix1x1s the same, at least as far as conversions go. We allowed splats from scalars to aggregates, but not from vector1s or matrix1x1s.
Also fixes a bug where we would crash on conversions to aggregates where the result was ignored, because clang wouldn't allocate an AggValueSlot and we didn't handle the destination pointer being nullptr.
1. Constant buffer globals could get removed, causing the layout of the implicit constant buffer to change.
2. For cases like static struct { int x; } s; (which happen in some commercial shaders), we would be left with struct { int x; }; at the global scope, which is illegal. This change cleans up anonymous records if we remove their last declared variable.
Disable CompileWhenNoMemThenOOM when debug iterators are enabled
Note that debug iterators are still disabled in the build by default.
We will do internal runs with debug iterators on to catch these bugs
sooner, but we do not want to enable them by default because it blocks
the OOF memory handling tests CompileWhenNoMemThenOOM.
We were systematically losing input vector debug info because of HLSignatureLower, which would replace them by per-element loadInput calls and then re-creating the vector through an insertelement chain. The llvm.dbg.value intrinsic was preserved for the recomposed vector, but this is not the authoritative source of data anymore - its elements are. Further optimizations would read past the insertelements and eventually we'd drop the vector and its debug info. To fix this, I'm now migrating the debug info to the individual vector elements as loaded from loadInput.
Also standardized on bitpieceexpression arguments being in bits everywhere, because it was becoming too confusing. The header for createBitPieceExpression had OffsetInBits while the source file had OffsetInBytes and various places converted counter-intuitively between the two.
When compiling with debug info and passing in a full path, we ended up with a bogus !DIFile metadata entry where the path had the drive and directory components twice before the filename. Other code would compute the correct path and create a second !DIFile metadata entry.
Apparently we're misusing CodeGenOptions::MainFileName, because it should not contain a full path but, due to other code of ours, it seems like a riskier change to fix that because we depend on it in CodeGeneratorImpl::HandleTranslationUnit.
- Change algorithm to no longer assume that getScope() returns either
DICompileUnit or DISubprogram, searching for the global var in each
compile unit until found instead.
TODO: drill into ConstantBuffer<> type to make cbuffer reflection useful here. The change would be something like this: CShaderReflectionConstantBuffer::Initialize:
if (!annotation)
return;
+ if (ST->getNumElements() == 1 &&
+ isa<StructType>(Ty->getContainedType(0)) &&
+ annotation->GetFieldAnnotation(0).GetFieldName() == CB.GetGlobalName()) {
+ // Assume we need to drill one level deeper into struct.
+ // This is the case when you use ConstantBuffer<MyStruct> ...
+ // It could also misfire in a narrow case where you use:
+ // struct MyStruct { ... }; cbuffer MyCBuffer { MyStruct MyCBuffer; }
+ // But the effect would be to drill one level into MyCBuffer for cbuffer VarDesc,
+ // which wouldn't be bad.
+ ST = cast<StructType>(Ty->getContainedType(0));
+ annotation =
+ typeSys.GetStructAnnotation(cast<StructType>(ST));
+ }
+
m_Desc.Variables = ST->getNumContainedTypes();
unsigned lastIndex = ST->getNumContainedTypes() - 1;
Those tests reach into HLSL, CodeGenHLSL, Samples and even quick-test directories to find the files they need. With this change, I move or copy files around to make sure that these test files are attributable to their consumer. I copied rather than moved files only in the case where a test in code explicitly reached into quick-test or Samples, because that essentially means that the file serves two different tests since they are also run as batch.
* [spirv] Fix handling of literals for constants.
Deducing literal types works by traversing the SPIR-V module in the
reverse order. We were only performing the reverse oreder within
functions, but we should have also reversed the order for SPIR-V
instructions that lay outside of functions. For example: constants,
constant composites, etc.
Before this fix, constants were visited before functions, and therefore
if they had a literal type, it wouldn't be deduced properly.
* Address comments.
There is no reason to keep a SetVector for SpirvFunction pointers. It
does not stop duplicate functions being used (the caller may have called
`new SpirvFunction` twice for the same function). There are already
mechanisms in place in SpirvEmitter class that prevent the same
function from being visited more than once.
Now that we have switched from SetVector to std::vector, it is better to
also do the reverse traversal of functions from the end to the
beginning.
Our codegen for Append/Consume is unfortunate because it happens after initial codegen and we don't have access to lots of what would have made this easy. I've had to duplicate the register to memory conversion logic.
We normally check for recursion from the entry point in hlsl::DiagnoseTranslationUnit, at the end of AST parsing, but we can't do that when we compile for library targets because we have no entry point. This adds a test that we still fail validation.