llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.39k stars 12.15k forks source link

Promote loop access to scalars (LICM) blocked by unrelated volatile access #38764

Open brunodefraine opened 6 years ago

brunodefraine commented 6 years ago
Bugzilla Link 39416
Version trunk
OS All
CC @hfinkel,@dobbelaj-snps

Extended Description

Consider the following example:

extern int x; extern volatile int v; int f(int) attribute((const));

void test() { for (int i = 0; i < 100; ++i) { x = f(x); v = 1; } }

Godbolt URL: https://godbolt.org/z/yZo4lj

I expect that LICM optimization would move the load/store of "x" outside of this loop, but this seems blocked by the access to volatile "v".

Note that GCC does move the load/store of "x" outside of the loop.

While only a missed optimization, this is unexpected, because the optimization is otherwise done (if you comment out the access to "v", which you would expect to be unrelated, LICM does promote the accesses of "x" to scalars). Also, when you unroll such a loop, LLVM can eliminate the redundant intermediate load/store operations. Consider:

void test_unrolled() { x = f(x); v = 1; x = f(x); v = 1; x = f(x); v = 1; }

Godbolt URL: https://godbolt.org/z/0Iwsno

This has only a single load and store of "x", respectively at the beginning and end. So the optimization in case of the loop is certainly safe (or both GCC and LLVM outside of a loop are wrong...).

brunodefraine commented 6 years ago

Without pointing any blame, from an analysis of the LICM code, the relevant parts in the code base seem to be: