I can’t reproduce it with a small example for the time being. If you have encountered the same scene, please help to post a test case.
I used GDB to debug it. The reason for the problem is that the function is divided into hot and cold blocks. Somewhere in the function, the je instruction is used to jump to the cold block. The hot block exchanges the r15 and rbx registers, but the cold block There is no exchange.
In the following figure, after the function mlog_write_ulint is executed for a while, we enter the cold block. (It was placed far away because it was not often executed) , %rbx in the right figure is not replaced with r15 in this block.
Then, 0x6011707 and 0x6911757 are executed in sequence. In this case, an incorrect value is written to %ebx in the previous step. As a result, a difference occurs in the subsequent comparison, and an incorrect address is jumped to. And then the command execution won’t be able to match.
I don’t think this optimization pass was designed with this in mind, I’m trying to fix this bug, but I’m not familiar with it, I hope someone familiar with it can help fix this bug
In this question, do this ‘jmp’ need to have a record in the GOT table or generate a GOT item to facilitate bolt analysis? I was reading the bolt source code yet, and have no idea how to fix it.
-reg-reassign is an experimental pass that we used to evaluate whether we could get performance wins by using registers which would yield shorter x86 instruction encodings, but we couldn’t measure any benefits of doing so. So I wouldn’t bother with trying to use it to mysqld as it is unlikely to make a difference.
@maksfb I will take a look at this to see what is happening. If it can’t be fixed, perhaps we should remove this experimental pass.
Thanks for the reply, I tested the option -reg-assign --infer-fall-throughs combined has a good benefits (without pgo), it is a pity to remove the pass.