[RFC] Extend ExtVectorElementExpr for HLSL Matrix Accessors (original) (raw)

November 6, 2025, 6:46pm 1

Motivation & Background

In HLSL, matrix types (e.g., float4x4, float3x2, etc) support component-accessors via “swizzle”-style suffixes, for example:

float4x4 M;

float2 v = M._m01_m00;  // selects components (0,0) and (0,1)  

The spec for this is in progress but defined here.

In Clang there is a dedicated AST node `**MatrixSubscriptExpr**` (for [row][col] access) and an AST node `**ExtVectorElementExpr**` (for vector swizzles) for vector component access.

This RFC proposes to extend `**ExtVectorElementExpr**` to support matrix-extension types (HLSL matrix swizzle suffixes) rather than introducing a new AST node type. The goal is to reuse the existing infrastructure, minimize new AST node proliferation, and maintain consistency with vector swizzle semantics.

Goals

  1. Support HLSL matrix swizzle accessors of the form Base._mij_mkl_… where each suffix identifies one or more matrix elements (row, column).
  2. Integrate cleanly into Clang with minimal HLSL specific changes needed for Sema (though obviously some matrix-specific logic is required hopefully this can be useful for the existing clang matrix type so we don’t pollute `**ExtVectorElementExpr**` HLSL LangOpts).

Non-Goals

  1. Change the semantics of vector swizzles for ExtVectorElementExpr.
  2. Support arbitrary new syntax beyond HLSL matrix-swizzle style (i.e., no attempt to introduce fully generalized arbitrary multi-dimensional swizzle syntax).
  3. Modify existing vector swizzle syntax or semantics.

Design Specification

We propose that `**ExtVectorElementExpr**` be extended such that when its base expression (Base) has a matrix type, the accessor suffix is interpreted as matrix-elements rather than vector-elements. Proposed changes:

  1. A new boolean flag (or enumeration) in ExtVectorElementExpr to distinguish vector vs matrix mode.
  2. For matrix mode:
    1. Expr *Base — the matrix-typed expression.
    2. SourceLocation DotLoc — location of the dot before the accessor.
    3. IdentifierInfo *Accessor — pointer to the identifier info for the suffix (e.g., “_m00_m01”).
  3. toggle the accessor to the set of matrix specific swizzle naming conventions.

This change should mostly be in Sema because `**ExtVectorElementExpr**` already supports vector swizzle lowering. In other words we reuse similar patterns but adjust for matrix layout (row/col) rather than vector index because we must make sure codegen uses the right index of the vector to get the flattened matrix index.

Advantages

`**ExtVectorElementExpr**` Already has all the l-value and r-value rules defined. The HLSL already has the 4 max restrictions on size that we would need for matrix types. In other words all the infrastructure to support what we need exists and doing a new AST node would be a whole bunch of copying behavior just to operate on a different base type.

Alternatives Considered

We were considering a new Matrix Element Expression Node: https://github.com/llvm/wg-hlsl/pull/357/commits/c8698ed4fe3c632add239f2b91100e66a9228422 .

upon further consideration It seems like extending `**ExtVectorElementExpr**` might be the better path forward.

CC: @fhahn

:white_check_mark: this RFC was accepted in this message.

beanz November 7, 2025, 8:28pm 2

(tagging a few extra people: @AaronBallman, @svenvh, & @efriedma-quic)

I think my one main concern about extending the ExtVectorElementExpr in this way comes down to the name. The name of that AST node contains the type it applies to, so if we’re going to extend it to support other types we probably should consider renaming the AST node.

If we don’t rename it but we do reuse it in this way it will linger forever as a slightly confusing oddity.

farzonl November 18, 2025, 9:50pm 3

Ping on this thread. Is the concern just about naming?

That could be a big NFC change I do before I start. Looks like 162 changes in total across source and tests.

Would help to know what name people would want before I make the change.

My guess is that either 1) folks don’t feel comfortable commenting on HLSL due to lack of expertise with it, or 2) there’s a lack of interest in the RFC itself.

Yeah, this makes me share the concerns from Chris about the name of the AST node. It’s a bit weird for it to be named vector when it’s actually a maxtrix.

Have you considered factoring into a common base class and then using subclasses to express the maxtrix vs vector differences?

farzonl December 8, 2025, 11:14pm 5

Thanks for the feeback this is my updated proposal:

This is my working draft:

Thank you for the update! We discussed this proposal briefly at today’s Clang Area Team meeting. We believe this has consensus to proceed despite the lack of community engagement because it’s a necessary HLSL feature.

farzonl December 11, 2025, 9:11pm 7

Thanks! We are accepting this proposal on our end and moving towards moving the implementation out of draft.