Zero/sign extension of Bool

I’m brand new to SPIR-V, so apologies for not being able to answer this question given the tooling… I don’t know how to make glslangValidator do my bidding yet.

How do you express a zero/sign extension of Bool to an integer type in SPIRV? An obvious use case is comparisons on bools:

int main() {
  bool x = false;
  bool y = true;
  bool z = x < y;
}

The comparison should zero-extend x and y to int, then yield the comparison of those. But the only instruction I can find for this operation is OpSelect, which seems out of character for an IR with this level of specificity. Being able to sign-extend into floats would also be very useful for vector instructions, as this is already common practice in AVX coding.

I assume your example source is from C++? I never would have thought to use the less-than operator on bool (!). I learned something.

In SPIR-V bool is not an integer scalar type. (This is different from LLVM, where a bool is represented by i1, a 1-bit integer scalar type.)
To get what you want, use OpSelect to do the equivalent of sign-extension:

%uint = OpTypeInt 32 0
%uint_0 = OpConstant %uint 0
%uint_1 = OpConstant %uint 1
%bool = OpTypeBool
%true = OpConstantTrue %bool
%false = OpConstantFalse %bool


%x = OpCopyObject %bool %true
%y = OpCopyObject %bool %false
%x_extended = OpSelect %uint %x %uint_1 %uint_0
%y_extended = OpSelect %uint %y %uint_1 %uint_0
%z = OpULessThan %bool %x_extended %y_extended

I hope that makes sense and answers your question.

But you may ask why bool is not considered an integer type? Maybe it’s so we can have different rules for it and other integer scalars. For example, a SPIR-V bool is not allowed to appear in a storage buffer, since we don’t want to force a particular representation for booleans. The host side and the shader side must agree on their own convention and do their own conversions from some other representable type, most likely an integer.