Call to non-constant memset() being generated where libc is not available

I am compiling something without standard libraries, including no libc.

Somehow, this bitcode is being generated by plain array manipulation code:

%12 = add i8 %11, -19
%tmp35 = icmp sgt i32 %9, 1

%smax36 = select i1 %tmp35, i32 %9, i32 1
call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([100 x i8]* @global_array_char, i32 0, i32 0), i8 %12, i32 %smax36, i32 1, i1 false)

(global_array_char is an array of length 100, which only partially gets used.)

This gets lowered by LLC to a library call to memset(), which cannot be satisfied.

Any advice?

Thanks,
David Meyer

Hi David,

I am compiling something without standard libraries, including no libc.

compile with -fno-builtin That said, note that GCC for example requires memset
to be available even in a freestanding environment.

Ciao, Duncan.

David Meyer wrote:

I am compiling something without standard libraries, including no libc.

Somehow, this bitcode is being generated by plain array manipulation code:

   %12 = add i8 %11, -19
   %tmp35 = icmp sgt i32 %9, 1
   %smax36 = select i1 %tmp35, i32 %9, i32 1
   call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([100 x
i8]* @global_array_char, i32 0, i32 0), i8 %12, i32 %smax36, i32 1, i1
false)

(global_array_char is an array of length 100, which only partially gets
used.)

That's not quite enough to go on. What's the original code, and what is this? Are we looking at an array initialization here?

This gets lowered by LLC to a library call to memset(), which cannot be
satisfied.

Any advice?

As Duncan pointed out, memset may be generated as part of the ABI even in a freestanding (ie., no libc) environment. I think memcpy is in the same boat.

If you have a different target with a different ABI that doesn't provide memset/memcpy, you could try writing your own generic lowering in Target/X86. Or you could always link against something native that provides memset/memcpy, which is what I strongly recommend.

David Meyer wrote:

I am compiling something without standard libraries, including no libc.

Somehow, this bitcode is being generated by plain array manipulation code:

%12 = add i8 %11, -19
%tmp35 = icmp sgt i32 %9, 1
%smax36 = select i1 %tmp35, i32 %9, i32 1
call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([100 x
i8]* @global_array_char, i32 0, i32 0), i8 %12, i32 %smax36, i32 1, i1
false)

(global_array_char is an array of length 100, which only partially gets
used.)

That's not quite enough to go on. What's the original code, and what is
this? Are we looking at an array initialization here?

This gets lowered by LLC to a library call to memset(), which cannot be
satisfied.

Any advice?

Pdox, is this happening on ARM as well?