4 different implementations of modulo with fully defined behavior
Is there an error somewhere, something that i missed? Is there an error somewhere, something that i missed?

Certainly have most of main street covered.
if (y == -1) return 0; is a nice trick.
y = abs(y); fails 32-bit math when int is 16-bit.  Could use labs() or conditional code or an if() block.  (Only real portability bug I see.)
Pedantic: int32_t is an optional type.  It is missing and code fails to compile on select (dinosaur) machines that do not have 32-bit unpadded 2's complement.
Pedantic: On a select (unicorn) machine where int is 64-bit and int32_t exist, promotions occur.  I do not see a problem though.
Pedantic: Usage of x ^ y obliges 2's complement encoding for correct functionality which is the case with intN_t here , but not all integers on all machines.

Adding a test harness would help.


Can it be simplified?

A shot at simplifying Euclidean division (result is always non-negative).  Similar code may apply to the other 2 cases.
// Substitute `int` for `int32_t`, `long long`, etc.
int modulo_Euclidean(int x, int y) {
  if (y == 0) exit(-1);
  if (y == -1) return 0;
  int m = x % y;
  if (m &lt; 0) {
    m = (y &lt; 0) ? m - y : m + y;
  }
  return m;
}

Does not require intN_t math*, 2's complement, no padding, range constants, nor extended math.

It would be interesting to see if 64-bit math was really slower or a reasonable candidate.
int32_t mod_rem_or_euc(int32_t x, int32_t y) {
  if (y == 0) exit(-1);
  int_fast64_t m = (int_fast64_t) x % y;
  ...
}


* intN_t types are 2's complement, no padding.