[llvm-bugs] [Bug 45912] New: Call to consteval function isn't folded to a constant
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed May 13 12:57:41 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=45912
Bug ID: 45912
Summary: Call to consteval function isn't folded to a constant
Product: clang
Version: trunk
Hardware: PC
OS: All
Status: NEW
Severity: enhancement
Priority: P
Component: LLVM Codegen
Assignee: unassignedclangbugs at nondot.org
Reporter: ldionne at apple.com
CC: llvm-bugs at lists.llvm.org, neeilans at live.com,
richard-llvm at metafoo.co.uk
The following program calling a consteval function causes code to be emitted to
compute the result of maxFoo() at runtime, when one would expect it to be
computed at compile-time:
$ cat <<EOF | clang++ -xc++ - -std=c++2a -Os -S -o a.s && cat a.s
#include <array>
#include <algorithm>
struct Foo { int i; };
static constexpr std::array<Foo, 3> foos = {{{1}, {2}, {3}}};
static int consteval maxFoo() {
auto it = std::max_element(foos.begin(), foos.end(), [](auto lhs, auto
rhs) {
return lhs.i < rhs.i;
});
return it->i;
}
int main() { return maxFoo(); }
EOF
Here's a few interesting observations:
1. This only happens when -Os or -O1 are used.
2. Even slight modifications of the above code will cause it to be inlined, for
example implementing `maxFoo()` equivalently but in a single expression.
3. The same issue happens whether `consteval` is used or not (which leads me to
think this is a codegen issue, not a front-end issue).
Godbolt link: https://godbolt.org/z/MA9U8b
After playing around and debugging Clang for a bit, I am fairly confident that
this is not a bug per-se, but only an important QOI issue. In particular, I
think Clang behaves correctly with respect to the Standard, which only says
about immediate functions (http://eel.is/c++draft/expr.const#13):
> [...] An expression or conversion is an immediate invocation if
> it is a potentially-evaluated explicit or implicit invocation of
> an immediate function and is not in an immediate function context.
> An immediate invocation shall be a constant expression.
This doesn't talk about codegen, since the Standard doesn't have such a notion.
Also, Clang does treat `maxFoo()` as a constant expression, and in fact the
front-end even calculates the result properly in an APValue -- so Clang is
*correct* as far as the Standard is concerned.
However, the code generation appears to never be passed that knowledge, and as
a result it can sometimes fail to fold the immediate call, depending on
optimization levels. Since the intent of consteval was *specifically* to make
sure that no code is generated for such calls, I would argue this is an
important QOI issue (if we're being pedantic), and straight up a bug (as far as
99% of users are concerned).
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200513/29d79f52/attachment.html>
More information about the llvm-bugs
mailing list