[PATCH] D29428: [SimplifyCFG] Merge similar fatal error blocks ending in unreachable

Reid Kleckner via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 1 14:53:24 PST 2017

rnk created this revision.

The goal is to canonicalize these examples to the same code:

  void f(unsigned x) {
    if (x < 7) abort();
    if (x > 40) abort();

- void g(unsigned x) { if (x < 7 || x > 40) abort(); }

Macros similar to 'assert' are very popular, and not all assertions are
compiled out from release builds. Assertion failures are usually very
cold, so we should try to optimize them for code size as much as
possible. Merging blocks ending in noreturn calls followed by
unreachable helps with that. It also enables follow-on optimizations
from instcombine, which can turn the above example into something like:

  void f(unsigned x) {
    if (x - 7 > 33) abort();

These code patterns appear in MSVC's std::string destructor, which is
analyzed in PR31774, but they appear in LLVM Release+Asserts builds as

This would be a net code size win on Release+Asserts clang if it weren't
for the inliner. By default, my clang is built with -O3, and this patch
increases the code size of that binary by 6% (70MB -> 75MB) and
regresses performance of compiling tramp3d-v4.cpp from test-suite by a
tiny amount. If I rebuild clang with -O1, this patch saves 111KB of code
from the 97MB of code in clang, which isn't much, but is nice. It
improves performance by 1.2% (42.50s -> 41.97s).

As a result, this transformation seems like a nice canonicalization, but
it's off by default for now. The -merge-noreturn-bbs flag enables it.
We can enable it by default when we address the issues in the inliner.



-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29428.86732.patch
Type: text/x-patch
Size: 35090 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170201/8cc1fc8f/attachment-0001.bin>

More information about the llvm-commits mailing list