Rotate by 1 is translated to 1 micro-op, while rotate with imm8 is translated to 2 micro-ops.
Fixes pr30644.
Differential D25399
[X86] Prefer rotate by 1 over rotate by imm zvi on Oct 8 2016, 12:08 PM. Authored by
Details Rotate by 1 is translated to 1 micro-op, while rotate with imm8 is translated to 2 micro-ops. Fixes pr30644.
Diff Detail
Event Timeline
Comment Actions Please can you confirm that the _lrotl/_lrotr intrinsics (I think they are only on clang-cl) can't create the removed rotr #1 pattern Comment Actions Seems like for 64-bit operand intrinsics we are not matching any rotate instructions: unsigned long ltestl(unsigned long _Value) { return _lrotl(_Value, 1); } leaq (%rdi,%rdi), %rax shrq $31, %rdi orq %rdi, %rax retq unsigned long ltestr(unsigned long _Value) { return _lrotr(_Value, 1); } movq %rdi, %rax shrq %rax shlq $31, %rdi orq %rax, %rdi movq %rdi, %rax retq But the 32-bit operand flavors are matching rotate instructions (these are withour this patch): unsigned long testl(unsigned long _Value) { return _rotl(_Value, 1); } roll %edi movq %rdi, %rax retq unsigned long testr(unsigned long _Value) { return _rotr(_Value, 1); } roll $31, %edi movq %rdi, %rax retq The 64-bit operand issue seems like out of scope of this patch, since the matching to ISD::ROTR/ROTL nodes happens in the target-independent phase of DagCombine. I will open a Bugzilla for this and will investigate it further. Comment Actions Actually, the relevant 64-bit operand intrinsics are _rotl64 and _rotr64 for which the generated code without this patch is: test_rotl64(unsigned long): # @test_rotl64(unsigned long) rolq %rdi movq %rdi, %rax retq test_rotr64(unsigned long): # @test_rotr64(unsigned long) rolq $63, %rdi movq %rdi, %rax retq |
Does rotr by 1 never get emitted or should we really have two patterns here?