Skip to content

gvn does not remove loads after loop #19222

@tobiasgrosser

Description

@tobiasgrosser
Bugzilla Link 18848
Version trunk
OS Linux
Attachments The LLVM-IR file to reproduce this bug
CC @hfinkel

Extended Description

When computing the following C code:

void f(float *restrict A, float *restrict B, long N) {
B[0] = A[0];
for (long i = 1; i < N - 1; i += 1) {
B[i - 1] += A[i];
B[i] = A[i]; // Last iteration: B[N-2] = A[N-2];
}
B[N - 2] += A[N - 1];
}

global value numbering successfully eliminates redundant loads from B within the loop body, but it does not eliminate the redundant load of B right after the loop body.

The attached test case was slightly simplified to ensure the loop body dominates the statement after it.

When running the following command 'opt -basicaa store.preopt.ll -gvn -scalar-evolution -analyze' we get the following information:

Index of store in the loop body:

%arrayidx6 = getelementptr inbounds float* %B, i64 %storemerge9
--> {(4 + %B),+,4}<%for.body> Exits: (-8 + (4 * %N) + %B)

Index of load after the loop:
%arrayidx11 = getelementptr inbounds float* %B, i64 %sub10
--> (-8 + (4 * %N) + %B)

Both registers have the same value after the loop. We should eliminate both the load that comes right after the store as well as the unnecessary index computation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillallvm:GVNGVN and NewGVN stages (Global value numbering)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions