LLVM function argument analysis

I have a simple function on which I am trying to detect whether the memory access instructions refer to the function arguments.

I am trying to do it using the MemoryLocation::get() function and then dyn_cast the pointer to the Argument class.

This all works fine if I run the analysis on IR that is generated using the O3 compiler flag. This is because the IR generated directly accesses the memory from the function arguments. But for the same function when generating IR using the O0 compiler flag, this analysis fails because the IR generated stores the arguments into stack and I am not able to perform the memory analysis on this IR.

Below is the IR snippet that is generated using O3 and O0.

IR Generated using O0:
define dso_local float @simple_fn(float* noundef %a, float* noundef %b, i32 noundef %N) #0 {
%a.addr = alloca float*, align 8
%b.addr = alloca float*, align 8
%N.addr = alloca i32, align 4
store float* %a, float** %a.addr, align 8 → Here I am not able to detect the Argument access

IR Generated using O3
define dso_local float @simple_fn(float* nocapture noundef readonly %a, float* nocapture noundef readonly %b, i32 noundef %N) local_unnamed_addr #0 {
%0 = load float, float* %a, align 4, !tbaa !3 → Here I am able to detect the Argument access

Is there any analysis that I can use to “run down” the load/store instructions in order to find out if I am accessing function arguments or not?

Also what is the pass that prevents storing of function arguments on the stack in O3?

Any help will be very much appreciated! Thanks in advance!

Clang (and most frontends, for that matter) generate code such that all local variables (including function parameters) are stored in alloca stack locations. There are two passes which can promote these stack locations to LLVM SSA locations that bypass the stack: the first is the mem2reg pass, which is not usually run in pass pipelines; the second is the SROA (scalar replacement of aggregates) pass, which can promote everything that mem2reg can and even more beyond that. The SROA pass is one of the earliest passes to run in the pipeline; at any level greater than -O0, you will see that pass run.

You can request the mem2reg pass run before your analysis pass runs to get as many stack locations eliminated as possible, but you might have to strip optnone attributes (that are added to functions when compiling with -O0) to get it to do anything.

Thanks for the reply.