Description
HLSL 2021 introduced the select
intrinsic as a replacement for the ternary operator on vector types.
The select
intrinsic has the following approximate forms:
template<typename T, int Sz>
void select(vector<bool, Sz> Conds, vector<T, Sz> TrueVals, vector<T, Sz> FalseVals) {
vector<T, Sz> Result;
for (int I = 0; I < Sz; ++I) {
if (Conds[I])
Result[I] = TrueVals[I];
else
Result[I] = FalseVals[I];
}
return Result;
}
template<typename T>
void select(bool Cond, T TrueVal, T FalseVal) {
if (T)
return TrueVal;
return FalseVal;
}
The vector case can lower to a shufflevector mask:
template<typename T, int Sz>
void select(vector<bool, Sz> Conds, vector<T, Sz> TrueVals, vector<T, Sz> FalseVals) {
vector<int, Sz> Mask;
for (int I = 0; I < Sz; ++I) {
Mask[I] = I;
if (!Conds[I])
Mask[I] += Sz;
}
return __builtin_shufflevector(TrueVals, FalseVals, Mask);
}
Acceptance Criteria
Implementation of the select intrinsic in the HLSL builtin headers and corresponding lowering to LLVM IR with appropriate test coverage.
- Implement
select
clang builtin, - Link
select
clang builtin withhlsl_intrinsics.h
- Add sema checks for
select
toCheckHLSLBuiltinFunctionCall
inSemaChecking.cpp
- Add codegen for
select
toEmitHLSLBuiltinExpr
inCGBuiltin.cpp
- Add codegen tests to
clang/test/CodeGenHLSL/builtins/select.hlsl
- Add sema tests to
clang/test/SemaHLSL/BuiltIns/select-errors.hlsl
- Create the
int_spv_select
intrinsic inIntrinsicsSPIRV.td
- In SPIRVInstructionSelector.cpp create the
select
lowering and map it toint_spv_select
inSPIRVInstructionSelector::selectIntrinsic
. - Create SPIR-V backend test case in
llvm/test/CodeGen/SPIRV/hlsl-intrinsics/select.ll
DirectX
There were no DXIL opcodes found for select
.
SPIR-V
OpSelect:
Description:
Select between two objects. Before version 1.4, results are only
computed per component.
Before version 1.4, Result Type must be a pointer, scalar, or
vector. Starting with version 1.4, Result Type can additionally be
a composite type other than a vector.
The types of Object 1 and Object 2 must be the same as Result
Type.
Condition must be a scalar or vector of Boolean type.
If Condition is a scalar and true, the result is Object 1. If
Condition is a scalar and false, the result is Object 2.
If Condition is a vector, Result Type must be a vector with the same
number of components as Condition and the result is a mix of Object
1 and Object 2: If a component of Condition is true, the
corresponding component in the result is taken from Object 1,
otherwise it is taken from Object 2.
Word Count | Opcode | Results | Operands | |||
---|---|---|---|---|---|---|
6 |
169 |
<id> |
<id> |
<id> |
<id> |
Test Case(s)
Example 1
//dxc select_test.hlsl -T lib_6_8 -E fn -enable-16bit-types -spirv -fspv-target-env=universal1.5 -fcgl -O0
export float4 fn(bool4 p1, float4 p2, float4 p3) {
return select(p1, p2, p3);
}
Example 2
//dxc select_1_test.hlsl -T lib_6_8 -E fn -enable-16bit-types -spirv -fspv-target-env=universal1.5 -fcgl -O0
export float4 fn(bool p1, float4 p2, float4 p3) {
return select(p1, p2, p3);
}
HLSL:
Syntax
any<> select(bool<> cond, any<> t, any<> f);
any_sampler select(bool cond, any_sampler t, any_sampler f);
Type Description
Name | Template Type | Component Type | Size |
---|---|---|---|
ret | scalar, vector, or matrix | bool, float, or int | any |
cond | scalar, vector, or matrix | bool | any |
t | scalar, vector, or matrix | bool, float, or int | any |
f | scalar, vector, or matrix | bool, float, or int | any |
Type Description
Name | Template Type | Component Type | Size |
---|---|---|---|
ret | scalar | float, int, or uint | 1 |
cond | scalar | bool | 1 |
t | scalar | float, int, or uint | 1 |
f | scalar | float, int, or uint | 1 |
Minimum Shader Model
This function is supported in the following shader models.
Shader Model | Supported |
---|---|
HLSL 2021 and higher shader models | yes |
Shader Stages
Remarks
In HLSL 2021 int3 Z = select(X, 1, 0);
is a replacement for
int3 X = {1, 1, 1};
int3 Z = X ? 1 : 0;
See also
Metadata
Metadata
Assignees
Labels
Type
Projects
Status