https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94779
--- Comment #5 from Gabriel Ravier <gabravier at gmail dot com> --- Going to take a quick look at how it gets optimized in the tree passes. This is the first case : int f1(unsigned x) { if (x >= 2) __builtin_unreachable(); switch (x) { case 0: return 1; case 1: return 2; } } This is the case which properly compiles down to `return x + 1;`, and should be equivalent to the other code. The ssa tree pass ends up, early in optimization, combining some expressions into `# _1 = PHI <_4(5), _3(6)>` Then, phiopt1 optimizes it to `_3 = x_2(D) + 1;`, at which point the optimization we're talking about has been made This is the second case : int f1(unsigned x) { switch (x) { case 0: return 1; case 1: return 2; } } The ssa tree pass still combines some expressions into `# _1 = PHI <1(2), 2(3)>` However, phiopt1 doesn't optimize into `x + 1`. For me, this seems to be because in the first case, the tree is then this : f1 (unsigned int x) { int _1; <bb 2> : if (x_2(D) > 1) goto <bb 3>; [INV] else goto <bb 4>; [INV] <bb 3> : __builtin_unreachable (); <bb 4> : if (x_2(D) == 1) goto <bb 5>; [INV] else goto <bb 6>; [INV] <bb 5> : <L3>: <bb 6> : # _1 = PHI <1(4), 2(5)> <L6>: return _1; } And in the second case, it is instead this : f1 (unsigned int x) { int _1; <bb 2> : switch (x_2(D)) <default: <L2> [INV], case 0: <L4> [INV], case 1: <L1> [INV]> <bb 3> : <L1>: goto <bb 5>; [INV] <bb 4> : <L2>: __builtin_unreachable (); <bb 5> : # _1 = PHI <1(2), 2(3)> <L4>: return _1; } I believe phiopt1 is unable to optimize the PHI into `x + 1` in the second case because the `switch` hasn't been optimized away into an if yet It eventually gets optimized by switchlower1 phiopt4 is then, again, unable to optimize the PHI into `x + 1`. The tree is then as such : f1 (unsigned int x) { int _1; <bb 2> [local count: 1073741824]: if (x_2(D) == 0) goto <bb 5>; [65.00%] else goto <bb 3>; [35.00%] <bb 3> [local count: 1073741824]: if (x_2(D) == 1) goto <bb 5>; [100.00%] else goto <bb 4>; [0.00%] <bb 4> [count: 0]: <L2>: __builtin_unreachable (); <bb 5> [local count: 1073741824]: # _1 = PHI <2(3), 1(2)> <L4>: return _1; } And then there are no further tree passes that look like they should be relevant to this Assuming my analysis is correct (though considering I have little to no experience with gcc's tree system, there is a pretty big chance that my analysis is completely wrong), I believe that to solve this, there are two possibilities : - Either there is a missing tree pass that would make phiopt4 capable of optimizing the PHI into `x_2(D) + 1` - Or there should there be some extra code added to phiopt4 to recognise the idiom in this case