nir_op_imod is incorrectly translated to LLVM's srem instruction in src/amd/common/ac_nir_to_llvm.c:1567.
If you use the operands -1 and 3, nir_op_imod should return 2, however srem returns -1.
compare with intel's implementation:
LLVM srem documentation:
I went looking to why there were no good CTS tests for this and found this in the vulkan spec:
For the OpSRem and OpSMod instructions, if either operand is negative the result is undefined.
While the OpSRem and OpSMod instructions are supported by the Vulkan
environment, they require non-negative values and thus do not enable additional
functionality beyond what OpUMod provides.
While I'm open to fixing this, you may want to rethink what you are doing.
(In reply to Bas Nieuwenhuizen from comment #1)
> I went looking to why there were no good CTS tests for this and found this
> in the vulkan spec:
> For the OpSRem and OpSMod instructions, if either operand is negative the
> result is undefined.
I think this bug should be fixed to support OpenCL. I have not found any references in the OpenCL specs to results of the remainder operator, so I'm guessing it uses the definition eventually derived from C99 section 184.108.40.206 which defines the results for negative operands.
radv is not a CL driver though, so you can't depend on this working on any unextended vulkan driver.
(In reply to Bas Nieuwenhuizen from comment #3)
> radv is not a CL driver though, so you can't depend on this working on any
> unextended vulkan driver.
NIR is not specific to Vulkan though.
yes, but GL_ARB_spirv has the same spec language and there currently is no CL driver based on the AMD NIR->LLVM code. So none of the currently supported frontends need it.