| Issue |
86788
|
| Summary |
Optimization: x86 "shl" condition codes can be reused
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
Explorer09
|
This example codes shows a possible reuse of the SF (sign flag) after a left shift (<<) operation. But Clang seems to always generate a 'test' instruction after the shift; it doesn't reuse the condition code of the 'shl' when possible.
(Note: [I also reported this issue in GCC](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114490).)
```c
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
bool my_isxdigit(unsigned char ch) {
uint32_t mask1 = 0x7E00FFC0;
// Prevent the compiler from transforming the constants.
// Suppose we have to use them as written.
__asm__ ("" : "+r" (mask1));
if (!((mask1 << (ch & 0x1F)) >> 31))
return false;
uint32_t mask2 = 0x1A << 24;
__asm__ ("" : "+r" (mask2));
if (!((mask2 << (ch >> 4)) >> 31))
return false;
return true;
}
```
x86-64 Clang with "-O3" option
(Actually I tested this in Compiler Explorer (godbolt.org))
```x86asm
my_isxdigit:
movl %edi, %ecx
movl $2113994688, %eax
shll %cl, %eax
testl %eax, %eax
js .LBB0_2
xorl %eax, %eax
retq
.LBB0_2:
movl $436207616, %eax
shrl $4, %ecx
shll %cl, %eax
shrl $31, %eax
retq
```
Possible smaller code (I show this tweak specifically for Clang; in the [GCC bug report](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114490) I wrote an even smaller one):
```x86asm
my_isxdigit_2:
movl %edi, %ecx
movl $2113994688, %edx
xorl %eax, %eax # Sets SF to 0 if 'shll' does not affect flags.
shll %cl, %edx
js .L1
retq
.L1:
movl $436207616, %eax
shrl $4, %ecx
shll %cl, %eax
shrl $31, %eax
retq
```
The FLAGS register might be unmodified if the shift count is zero (i.e. value in `%cl` register is zero), but optimization is still possible if we set the FLAGS to a known state prior to the shift operation. (Thanks GCC developers for hinting this for me.) For example, `xorl %eax, %eax` sets CF and SF bits to 0, so the `my_isxdigit_2` code can work.
This optimization might require tracking on whether the FLAGS states are known. If this is impossible internally in LLVM, feel free to close this report.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs