<no subject>

Hi, ALL

I have something unclear about calling memset for array storage, the case is showing as below.

// cat test.c

void foo(int *p);

void test (int len) {

int a[7];

for (int i = 0; i < len; i++) a[i] = 0;

foo(a);

}

; Function Attrs: nounwind

define void @test(i32 signext %len) {

entry:

%a = alloca [7 x i32], align 4

%0 = bitcast [7 x i32]* %a to i8*

%cmp4 = icmp sgt i32 %len, 0

for.body.preheader: ; preds = %entry

%1 = zext i32 %len to i64

%2 = shl nuw nsw i64 %1, 2

call void @llvm.memset.p0i8.i64(i8* nonnull align 4 %0, i8 0, i64 %2, i1 false)

br label %for.cond.cleanup

for.cond.cleanup: ; preds = %for.body.preheader, %entry

%arraydecay = getelementptr inbounds [7 x i32], [7 x i32]* %a, i64 0, i64 0

call void @foo(i32* nonnull %arraydecay) #4

ret void

}

There are two issues:

1.ScalarEvolution could not get the exact loop max trip count , but such loop only allowed to run 7 times.

2.We know that LoopIdiomRecognize pass will transform this Loop into a libcall of memset, and llvm.memset won’t be expand because of SIZE of memory space( %2) is unknown.

But if function test is a HOT SPOT, calling memset in libc is unwise.

In summary, I wrote a patch to infer loop max trip count from array access in loop, and disabled

Loop Idiom while loop trip count is small enough, and also we can enable Loop Idiom regardless of loop trip count by passing “-use-lir-loop-max-tripcount=0” in command line.

We can discuss the overall idea in this thread.

For the implementation details, please comment on this patch : https://reviews.llvm.org/D109821

Thank you all.