When a return value's type has no precision qualification (e.g., the return
expression is formed from a constructor), and the formal function return type
has a precision qualification, back propagate that from the return type to the
type of the return value's expression.
This adds or changes binding/location decorations in 100s of shaders.
It also allows more output (spv.register.autoassign.rangetest.frag)
due to allowing ioMap() to fail.
This simplifies and enforces use of precision in many more places,
to help avoid accidental loss of RelaxedPrecision through intermediate
operations. Known fixes are:
- ?:
- function return values with mis-matched precision
- precision of function return values when a copy was needed to fix types
When arguments are copied to make space for a writable formal parameter,
and the formal parameter is relaxed precision, make the copy also
relaxed precision.
A removed block releases its instructions, so Module::idToInstruction
suddenly contains dangling references. The original motivation for
block removal was to skip some unreachable blocks, but that's already
achieved by InReadableOrder.cpp.
Also updated stale comments.
To ensure back branches always go to a header block, create a header
block even for !testFirst loops. Then unify common code between the
testFirst/!testFirst cases.
Generate the header-block code first, so update golden files.
Realize that certain infinite loops generate invalid SPIR-V, so put a
TODO to instead abort code generation in such cases.
Change-Id: I1e173c8f73daad186cfc666b7d72bd563ed7665d
Structured control-flow rules allow leaving the middle of a construct through
a return, but not through a jump to a block that does a return.
Addresses issue #58.
After construction, the Loop is effectively const.
This perturbs the IDs in SPIR-V tests because the body block
is created before generating any of the loop code, rather than
only when the body is first referenced.