Starting with code like this
void lib_memset( unsigned char *dest, unsigned char c, unsigned int n)
{
while(n--)
{
*dest=c;
dest++;
clang -Wall -m32 -emit-llvm -fno-builtin --target=arm-none-eabi -ffreestanding -c lib_memset.c -o lib_memset.bc
opt -std-compile-opts -strip-debug -march=arm -mcpu=mpcore -mtriple=arm-none-eabi -disable-simplify-libcalls lib_memset.bc -o lib_memset.opt.bc
llc -march=arm -mcpu=mpcore -disable-simplify-libcalls -mtriple=arm-none-eabi lib_memset.opt.bc -o lib_memset.opt.s
llc -march=arm -mcpu=mpcore -disable-simplify-libcalls -mtriple=arm-none-eabi lib_memset.bc -o lib_memset.s
thanks to artless noise while adding -ffreestanding, I decided to re-read all the --help options for llc and opt, and found the -disable-simpilfy-libcalls is an option for both opt and llc, adding it to opt fixed the problem.
lib_memset:
cmp r2, #0
bxeq lr
.LBB0_1:
strb r1, [r0], #1
subs r2, r2, #1
bne .LBB0_1
bx lr
I dont like answering my own question, can sit here for a bit so I can maybe find the answer next time or if the SO gods decide to leave it here that is fine...
I encounter the same problem and if it still can help anyone this is what I did to solve it - I modify the LoopIdiomRecognize.cpp file in the llvm source code: there is a code that checks if the name of the function is memset or memcpy it cancel the optimization, so I changed it from:
StringRef Name = L->getHeader()->getParent()->getName();
if (Name == "memset" || Name == "memcpy")
to
StringRef Name = L->getHeader()->getParent()->getName();
if (Name.endswith("memset") || Name == "memcpy")