Since you recommend using __builtin_sadd_overflow can you explain what the compiler is doing that is causing the issue in the first place?
The short answer is that C compilers are allowed to do anything if arithmetic overflows.
Modern C compilers use this license to aggressively optimize. In this case, since (i <= e) the _expression_ (e-i+1) cannot result in a zero or negative value unless there is an overflow, so the compiler removes the test for negative or zero. The code is expressly trying to detect overflow, but the compiler doesn't know that. With the __builtin function, the compiler is informed of the intention.