I am working on porting some code used on a STM32F4 based device from C to Rust. I am puzzled why the Rust equivalent is inserting an extra bx lr compared to the C version. Following is an excerpt from the C code:
I suspect the difference isn't the language but rather the compiler, were you using GCC or Clang for the C code? Regardless, the solution is probably to add mem::unreachable at the end of your function.
As said, this is no big concern, I'm just interested in understanding why Rust/LLVM adds this extra instruction while C/gcc don't. Somehow gcc understands that this function is never called and can optimize away the branch and exchange instruction, right?
This seems to be a real difference between Rust and Clang. Rust always inserts a "return;" at the end of a naked function, whereas Clang does not. Clang always inserts the "unreachable" instruction at the end, Rust does not. I don't think much thought was given to this behavior when implementing naked functions, if you have a particular opinion one way or another, you should voice it in the naked functions tracking issue
It's identical to the file produced by gcc, at least for this excerpt (the main function is different between gcc/Clang, but that's another story). So at least in this case, Clang does not insert the udf instruction which appeared after the adding of unreachable().
As far as I understand naked functions, this seems very strange. Is not the purpose of these to skip all prologue/epilogue? I would guess this included returning. I guess I will voice it in the tracking issue, thanks to pointing me there.