In most cases Elixir and Erlang intrinsically moving to BigInt is remarkably helpful and satisfying to work with, so I know this exercise is academic. Still if I wanted to work with integers as if they were restricted to signed 32-bit integers, how would I handle overflow/wrapping?
I’m thinking the easiest way is working with integers as binaries, something like:

Addition of two N-bit integers can result with at most (N+1)-bit integer. So as we are adding 32-bit integers then we will end with at most 33-bit result. That will give us the knowledge to achieve what we want:

defmodule Carry do
@u32_max 2 ** 32 - 1
import Bitwise
def add_u32(a, b) do
r = a + b
{r &&& @u32_max, (r >>> 32) == 1}
end
end
a = 0xFFFF_FFFF
b = 1
{result, carry} = Carry.add_u32(a, b)
IO.puts("#{a} + #{b} = #{result} (carried? #{carry})")
#=> 4294967295 + 1 = 0 (carried? true)