Nice! Clever compiler.. On 07/28/2012 08:55 PM, Michael Gottesman wrote:> I can get clang/llvm to emit a rotate instruction on x86-64 when compiling C by just using -Os and the rotate from Hacker's Delight i.e., > > =====> #include<stdlib.h> > #include<stdint.h> > > uint32_t ror(uint32_t input, size_t rot_bits) > { > return (input>> rot_bits) | (input<< ((sizeof(input)<< 3) - rot_bits)); > } > =====> > Then compile with (assuming you are on OS X): > =====> ISYSROOT=$(xcodebuild -sdk macosx -version PlatformPath)/Developer/SDKs/MacOSX10.8.sdk > $(xcrun -find clang) -isysroot $ISYSROOT ror.c -c -S -Os -o - > =====> > yielding an assembly output of: > =====> .section __TEXT,__text,regular,pure_instructions > .globl _rotr > _rotr: ## @rotr > .cfi_startproc > ## BB#0: > pushq %rbp > Ltmp2: > .cfi_def_cfa_offset 16 > Ltmp3: > .cfi_offset %rbp, -16 > movq %rsp, %rbp > Ltmp4: > .cfi_def_cfa_register %rbp > movb %sil, %cl > rorl %cl, %edi<==== Rotate instruction > movl %edi, %eax > popq %rbp > ret > .cfi_endproc > .subsections_via_symbols > =====> > I hope this helps. > > Michael > > On Jul 28, 2012, at 8:29 PM, reed kotler<rkotler at mips.com> wrote: > >> in C or C++, how can I get clang/llvm to try and do a "rotate". >> >> (want to test this code in the mips16 port) >> >> i.e. emit rotr node. >> >> tia. >> >> reed >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
*NOTE* IIRC compiling this with -O0 on x86-64 can yield the wrong result since clang will emit shifts and on intel shifts are mod the register size: ==== .section __TEXT,__text,regular,pure_instructions .globl _ror .align 4, 0x90 _ror: ## @ror .cfi_startproc ## BB#0: pushq %rbp Ltmp2: .cfi_def_cfa_offset 16 Ltmp3: .cfi_offset %rbp, -16 movq %rsp, %rbp Ltmp4: .cfi_def_cfa_register %rbp movl %edi, -4(%rbp) movq %rsi, -16(%rbp) movl -4(%rbp), %edi movq -16(%rbp), %rsi movl %esi, %eax movl %eax, %ecx ## kill: CL<def> ECX<kill> shrl %cl, %edi movl -4(%rbp), %eax movabsq $32, %rsi subq -16(%rbp), %rsi movl %esi, %edx movl %edx, %ecx ## kill: CL<def> ECX<kill> shll %cl, %eax orl %eax, %edi movl %edi, %eax popq %rbp ret .cfi_endproc .subsections_via_symbols ==== Michael On Jul 28, 2012, at 9:04 PM, reed kotler <rkotler at mips.com> wrote:> Nice! > > Clever compiler.. > > > On 07/28/2012 08:55 PM, Michael Gottesman wrote: >> I can get clang/llvm to emit a rotate instruction on x86-64 when compiling C by just using -Os and the rotate from Hacker's Delight i.e., >> >> =====>> #include<stdlib.h> >> #include<stdint.h> >> >> uint32_t ror(uint32_t input, size_t rot_bits) >> { >> return (input>> rot_bits) | (input<< ((sizeof(input)<< 3) - rot_bits)); >> } >> =====>> >> Then compile with (assuming you are on OS X): >> =====>> ISYSROOT=$(xcodebuild -sdk macosx -version PlatformPath)/Developer/SDKs/MacOSX10.8.sdk >> $(xcrun -find clang) -isysroot $ISYSROOT ror.c -c -S -Os -o - >> =====>> >> yielding an assembly output of: >> =====>> .section __TEXT,__text,regular,pure_instructions >> .globl _rotr >> _rotr: ## @rotr >> .cfi_startproc >> ## BB#0: >> pushq %rbp >> Ltmp2: >> .cfi_def_cfa_offset 16 >> Ltmp3: >> .cfi_offset %rbp, -16 >> movq %rsp, %rbp >> Ltmp4: >> .cfi_def_cfa_register %rbp >> movb %sil, %cl >> rorl %cl, %edi<==== Rotate instruction >> movl %edi, %eax >> popq %rbp >> ret >> .cfi_endproc >> .subsections_via_symbols >> =====>> >> I hope this helps. >> >> Michael >> >> On Jul 28, 2012, at 8:29 PM, reed kotler<rkotler at mips.com> wrote: >> >>> in C or C++, how can I get clang/llvm to try and do a "rotate". >>> >>> (want to test this code in the mips16 port) >>> >>> i.e. emit rotr node. >>> >>> tia. >>> >>> reed >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
> *NOTE* IIRC compiling this with -O0 on x86-64 can yield the wrong result > since clang will emit shifts and on intel shifts are mod the register > size [...snip...]I remember finding the same thing (although I haven't tried it on a recent clang version) and what I wondered was whether there was mileage in having an explicit intrinsic for rotation (like there is for bit counting, as in __builtin_clz and __builtin_ctz and so on). Microsoft's compiler has an explicit intrinsic in the form of _rotl8 and _rotl16 (IIRC -- this is from memory!). It would be nice to have a __builtin_rotl family in clang, in my opinion, but it would need back-end support from llvm. I would expect it to find use in code relating to hashing and cryptology. I know that the compiler *should* optimise uint32_t ror(uint32_t input, size_t rot_bits) { return (input >> rot_bits) | (input << ((sizeof(input) << 3) - rot_bits)); } and such macros / inline functions are common, but an intrinsic specifies intent better and could provide for better code optimisation. Would this be worthwhile pursuing? Cheers Andy
On Sat, Jul 28, 2012 at 09:11:13PM -0700, Michael Gottesman wrote:> *NOTE* IIRC compiling this with -O0 on x86-64 can yield the wrong > result since clang will emit shifts and on intel shifts are mod the > register size:The original code is depending on UB, if it doesn't mask. Joerg