Clang-11 compiles this fine, but since Clang-12.0.0 until at least Clang-18.1.0 there is some confusion in the compiler.
In the code associated with the case statements, an 8-byte value is "reloaded" from rbp - 56.
Unfortunately, this is not a location to which a register has previously been spilled!
This then causes cmp rdx, offset .LBB0_x to be not equal, and 0xffff800000000000 is or-ed into rsp in the epilogue of the function, generating a Segmentation fault (I believe this is supposed to only or in a non-zero value non-architecturally as part of speculative load hardening).
Simple repro is here, with a switch statement with >=5 cases:
https://godbolt.org/z/9ozTKGP48
Clang-11 compiles this fine, but since Clang-12.0.0 until at least Clang-18.1.0 there is some confusion in the compiler.
In the code associated with the case statements, an 8-byte value is "reloaded" from `rbp - 56`.
Unfortunately, this is not a location to which a register has previously been spilled!
This then causes `cmp rdx, offset .LBB0_x` to be not equal, and `0xffff800000000000` is or-ed into rsp in the epilogue of the function, generating a Segmentation fault (I believe this is supposed to only or in a non-zero value non-architecturally as part of speculative load hardening).
Simple repro is here, with a switch statement with >=5 cases: https://godbolt.org/z/9ozTKGP48
Clang-11 compiles this fine, but since Clang-12.0.0 until at least Clang-18.1.0 there is some confusion in the compiler.
In the code associated with the case statements, an 8-byte value is "reloaded" from
rbp - 56
. Unfortunately, this is not a location to which a register has previously been spilled!This then causes
cmp rdx, offset .LBB0_x
to be not equal, and0xffff800000000000
is or-ed into rsp in the epilogue of the function, generating a Segmentation fault (I believe this is supposed to only or in a non-zero value non-architecturally as part of speculative load hardening).