Vector type promotion

From cppreference.com

Vector type promotion refers to a common set of rules that specify the return type of library-provided binary functions that accept multiple vector types as their parameters. Like the type promotion rules in C, they describe what happens when a generic operation is applied to different vector types. Effectively this is description of what vector types do library functions return for certain arguments.

The rules are intuitive and resemble the C type promotion rules. The rules are as follows:

  • The rules only apply to vectors of the same size
  • The element data type of the result vector is defined as follows:
  • if either of the vectors is float, the result is also float
  • otherwise, if either of the vectors is uint, the result is also uint
  • otherwise, if either of the vectors is int, the result is also int
  • otherwise, if either of the vectors is mask_float, the result is also mask_float
  • otherwise, the result is mask_int
  • The number of bits per element in the result vector is the maximum of the argument vectors. For example, operation on int32x4 and int64x2 results in int64x2.

Examples:

First type Second type Result type
int32x4 int16x8 int32x4
uint32x4 mask_float64x2 uint64x2
float64x2 uint8x16 float64x2
mask_int8x16 mask_float64x2 mask_float64x2


The following tables illustrate the promotion rules in more detail:

If the arguments have the same element size XX, then:

First type Second type Result type
intXX intXX intXX
intXX uintXX uintXX
uintXX uintXX uintXX
floatXX intXX floatXX
floatXX uintXX floatXX
floatXX floatXX floatXX
mask_intXX intXX intXX
mask_intXX uintXX uintXX
mask_intXX mask_intXX mask_intXX
mask_intXX floatXX floatXX
mask_intXX mask_floatXX mask_floatXX
mask_floatXX floatXX floatXX
mask_floatXX mask_floatXX mask_floatXX

If the arguments have different element sizes XX and YY, then:

First type Second type Result type
intXX intYY int{ max(XX, YY) }
intXX uintYY uint{ max(XX, YY) }
uintXX uintYY uint{ max(XX, YY) }
floatXX intYY float{ max(XX, YY) }
floatXX uintYY float{ max(XX, YY) }
floatXX floatYY float{ max(XX, YY) }
mask_intXX intYY int{ max(XX, YY) }
mask_intXX uintYY uint{ max(XX, YY) }
mask_intXX mask_intYY uint{ max(XX, YY) }
mask_intXX floatYY float{ max(XX, YY) }
mask_intXX mask_floatYY uint{ max(XX, YY) }
mask_floatXX floatYY float{ max(XX, YY) }
mask_floatXX mask_floatYY uint{ max(XX, YY) }