SPIR-V, Confusion about the sign especially because of OpIMul
I am currently working on a SPIR-V to GLSL decompiler and I am confused about the behaviour of signed integers.
The description of most instructions (e.g. OpIAdd) does not specifiy if both integer operands must have the same type and signedness. I would assume that they don't have to but to my understanding that would defeat the purpose of the integer type distinction. Also the OpenGL reference compiler inserts bitcast instruction to cast beforehand.
The other thing that confuses me is the OpIMul instruction. Is it signed or unsigned? If it is one of those, how is the other encoded? Or does it depend on the signedness of the type? The reference compiler generates an OpIMul instruction both for signed and unsigned multiplications. But how does it work in OpenCL kernels where all types are unsigned? Why is it different for division? There are separate OpUDiv and OpSDiv instructions.
Thanks in advance for clarifying.
Last edited by The_Deviloper; 04-30-2016 at 08:30 AM.
SPIR-V does not distinguish between signed and unsigned integers, it is the matter of interpretation. Different instructions for addition and substraction are redundant due to the way integers are represented in hardware. Same for multiplication, apparently, although OpSMulExtended and OpUMulExtended are present.
For some reason I was thinking it would make a difference for multiplication.
Apparently that is not the case.
If the signed integer type is completely redundant, I will scrap the integer signedness information and regenerate it for GLSL operations where necessary.
Last edited by The_Deviloper; 05-01-2016 at 08:39 AM.
Signed integer types are not "redundant". They contain very useful semantic information, which implementations can use to make decisions. Not to mention that the signed/unsigned distinction matters to Vulkan, in vertex shader inputs and fragment shader outputs, if not other places. Mismatches are not allowed by the Vulkan specification.
If SPIR-V code treats some integer using unsigned operations, it means that variable was declared as unsigned in initial GLSL code. SPIR-V is supposed to be close-to-metal for easier translation into machine code, but if you discard such a valuable information when decompiling into high level language, you will obscure a programmer's intention, which defeats the purpose of decompiler in the first place.
Originally Posted by The_Deviloper