Skip to content

dasSpirv: integer vector*scalar (splat + IMul) + bool constants (OpConstantTrue/False)#3244

Merged
borisbat merged 1 commit into
masterfrom
bbatkin/dasspirv-intvec-bool
Jun 21, 2026
Merged

dasSpirv: integer vector*scalar (splat + IMul) + bool constants (OpConstantTrue/False)#3244
borisbat merged 1 commit into
masterfrom
bbatkin/dasspirv-intvec-bool

Conversation

@borisbat

Copy link
Copy Markdown
Collaborator

Two dasSpirv emitter gaps surfaced by the GLSL.std.450 / arithmetic dispatch audit (the dasVulkan tutorial ladder is the forcing function). Both were fail-closed/missing, not silent-invalid.

1. Integer ivecN * int → splat + OpIMul

ivecN * int was rejected with "integer vector/scalar mixes need a splat" — a missing feature, since SPIR-V has no OpVectorTimesScalar for integers (that op is float-only). emit_mul now splats the scalar to the vector width via OpCompositeConstruct (new splat_to_vec helper) and does a component-wise OpIMul, for both operand orders (vec*scalar and scalar*vec) and both int + uint. Mirrors the existing float OpVectorTimesScalar path and the FMix scalar-broadcast.

2. Bool constants → OpConstantFalse / OpConstantTrue

false / true literals (ExprConstBool) had no rvalue path and failed the annotation patch with "no rvalue available for ExprConstBool". They now lower to OpConstantFalse / OpConstantTrue (new const_bool builder helper — these carry no literal word, the opcode is the value) via a visitExprConstBool override + an emit_const case. Bool locals, comparisons, &&/||/!, and bool if conditions already worked — only the literal constants were missing.

Tests

  • tests/spirv/test_int_vec_scalar.das — loads the vectors from SSBO array<ivec> elements (not constructed), so the only OpCompositeConstruct are the three splats: asserts exactly 3 OpIMul + 3 OpCompositeConstruct, no OpVectorTimesScalar (ints don't use it), and spirv-val clean.
  • tests/spirv/test_bool_const.das — asserts OpTypeBool + both bool constants, spirv-val clean.

160 tests/spirv pass; lint-clean. Self-contained inline-shader fixtures (the established test_math_* / test_ext_broadcast pattern); auto-discovered by the tests/spirv/*.das AOT glob, so test_aot_spirv exercises both through the AOT path too.

🤖 Generated with Claude Code

…nstantTrue/False)

Two emitter gaps surfaced by the GLSL.std.450 / arithmetic dispatch audit.

1. Integer `ivecN * int` was rejected ("integer vector/scalar mixes need
   a splat"): a missing feature, since SPIR-V has no OpVectorTimesScalar
   for integers (that op is float-only). emit_mul now splats the scalar to
   the vector width via OpCompositeConstruct (new splat_to_vec helper) and
   does a component-wise OpIMul, for both operand orders (vec*scalar and
   scalar*vec) and both int + uint.

2. Bool literals (`false` / `true`, ExprConstBool) had no rvalue path and
   failed the annotation patch with "no rvalue available for ExprConstBool".
   They now lower to OpConstantFalse / OpConstantTrue (new const_bool
   builder helper) via a visitExprConstBool override + an emit_const case.
   Bool locals, comparisons, &&/||/!, and bool `if` conditions already
   worked -- only the literal constants were missing.

Tests: tests/spirv/test_int_vec_scalar.das (loads ivec from SSBO so the
splats are the only OpCompositeConstruct -> exact counts) and
test_bool_const.das (OpTypeBool + both bool constants). Both assert
spirv-val clean. 160 tests/spirv pass; lint-clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 21, 2026 21:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR closes two missing lowering cases in the dasSpirv emitter that were previously fail-closed: (1) integer vecN * scalar multiplication and (2) boolean literal constants. These gaps surfaced during an audit of arithmetic/ext-inst dispatch and are exercised via new SPIR-V tests.

Changes:

  • Add const_bool support and emitter rvalue handling for ExprConstBool via OpConstantTrue / OpConstantFalse.
  • Add integer vector*scalar multiplication lowering by splatting the scalar with OpCompositeConstruct and using component-wise OpIMul.
  • Add two new tests/spirv gates validating opcode shapes and spirv-val cleanliness for both cases.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
tests/spirv/test_int_vec_scalar.das New gate test asserting integer vec*scalar lowers to scalar splat (OpCompositeConstruct) + OpIMul (and not OpVectorTimesScalar).
tests/spirv/test_bool_const.das New gate test asserting bool literals emit OpTypeBool plus OpConstantTrue/OpConstantFalse.
modules/dasSpirv/spirv/spirv_emit.das Implement integer vec*scalar multiply via splat helper + OpIMul; add ExprConstBool constant emission/visitor support.
modules/dasSpirv/spirv/spirv_builder.das Add const_bool constant pooling + emission using OpConstantTrue / OpConstantFalse.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@borisbat borisbat merged commit b8be527 into master Jun 21, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants