Commit Graph

428 Commits

Author SHA1 Message Date
Davide Italiano
2037eb7f15 [SCCP] Teach the pass how to handle div with overdefined operands.
This can prove that:

extern int f;
int g() {
    int x = 0;
    for (int i = 0; i < 365; ++i) {
        x /= f;
    }
    return x;
}

always returns zero. Thanks to Sanjoy for confirming this
transformation actually made sense (bugs are mine).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292531 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-19 23:07:51 +00:00
Davide Italiano
f3e9b57b20 [SCCP] Update comment in visitBinaryOp() after recent changes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292519 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-19 21:07:42 +00:00
Davide Italiano
fd00f62380 [SCCP] Unknown instructions are sent to overdefined anyway. NFCI.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291400 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-08 21:19:05 +00:00
Davide Italiano
22f8c83c85 [SCCP] Debug diagnostic goes under DEBUG(). NFCI.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289519 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-13 05:56:04 +00:00
Davide Italiano
24d39f3563 [SCCP] Use the appropriate helper function. NFCI.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289406 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-11 21:19:03 +00:00
Davide Italiano
45b7e0e48d [SCCP] Teach the pass about mul %x 0 even if %x is overdefined.
The motivating example is:

extern int patatino;
int goo() {
    int x = 0;
    for (int i = 0; i < 1000000; ++i) {
        x *= patatino;
    }
    return x;
}

Currently SCCP will not realize that this function returns always zero,
therefore will try to unroll and vectorize the loop at -O3 producing an
awful lot of (useless) code. With this change, it will just produce:

0000000000000000 <g>:
   xor    %eax,%eax
   retq

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289175 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-09 03:08:42 +00:00
Davide Italiano
a47129de89 [SCCP] Make sure SCCP and ConstantFolding agree on undef >> a.
Currently SCCP folds the value to -1, while ConstantProp folds to
0. This changes SCCP to do what ConstantFolding does.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289147 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-08 22:28:53 +00:00
Davide Italiano
4b6e5ecd86 Revert "[SCCP] Remove manual folding of terminator instructions."
This reverts commit r288725 as it broke a bot.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288759 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-06 02:26:50 +00:00
Davide Italiano
8ea5797013 [SCCP] Remove manual folding of terminator instructions.
There are two cases handled here:
1) a branch on undef
2) a switch with an undef condition.

Both cases are currently handled by ResolvedUndefsIn. If we have
a branch on undef, we force its value to false (which is trivially
foldable). If we have a switch on undef, we force to the first
constant (which is also foldable).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288725 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-05 23:04:21 +00:00
Davide Italiano
9217738fa8 [SCCP] Switch over to DEBUG() and drop an #ifdef.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288325 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-01 08:48:14 +00:00
Davide Italiano
236801ef98 [SCCP] Prefer auto when the type is obvious. NFCI.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288324 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-01 08:36:12 +00:00
Davide Italiano
4f65080637 [SCCP] Remove code in visitBinaryOperator (and add tests).
We visit and/or, we try to derive a lattice value for the
instruction even if one of the operands is overdefined.
If the non-overdefined value is still 'unknown' just return and wait
for ResolvedUndefsIn to "plug in" the correct value. This simplifies
the logic a bit. While I'm here add tests for missing cases.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287709 91177308-0d34-0410-b5e6-96231b3b80d8
2016-11-22 22:11:25 +00:00
Sanjoy Das
09f0b3c147 [SCCP] Don't delete side-effecting instructions
I'm not sure if the `!isa<CallInst>(Inst) &&
!isa<TerminatorInst>(Inst))` bit is correct either, but this fixes the
case we know is broken.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279647 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-24 18:10:21 +00:00
David Majnemer
dc9c737666 Use range algorithms instead of unpacking begin/end
No functionality change is intended.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278417 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-11 21:15:00 +00:00
Sean Silva
2fb9a98752 Consistently use ModuleAnalysisManager
Besides a general consistently benefit, the extra layer of indirection
allows the mechanical part of https://reviews.llvm.org/D23256 that
requires touching every transformation and analysis to be factored out
cleanly.

Thanks to David for the suggestion.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278078 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-09 00:28:38 +00:00
Sean Silva
20b343c051 Consistently use FunctionAnalysisManager
Besides a general consistently benefit, the extra layer of indirection
allows the mechanical part of https://reviews.llvm.org/D23256 that
requires touching every transformation and analysis to be factored out
cleanly.

Thanks to David for the suggestion.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278077 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-09 00:28:15 +00:00
Davide Italiano
c2a8447473 [SCCP] Zap multiple return values.
We can replace the return values with undef if we replaced all
the call uses with a constant/undef.

Differential Revision:  https://reviews.llvm.org/D22336

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276174 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-20 20:17:13 +00:00
Davide Italiano
bd7732211f [SCCP] Improve assert messages. NFCI.
I've been hitting those already while working on SCCP and I think
it's be useful to provide a more explanatory diagnostic.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276007 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-19 18:31:07 +00:00
Davide Italiano
df5741e5fd [SCCP] Merge two conditions into one. NFCI.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275593 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-15 18:33:16 +00:00
Davide Italiano
f3702b696c [SCCP] Pass the Solver by reference, copies are expensive ...
.. enough to cause LTO compile time to regress insanely.
Thanks *a lot* to Rafael for reporting the problem and testing
the fix!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275468 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-14 20:25:54 +00:00
Davide Italiano
fb51249413 [SCCP] Pass a Value * instead of templating this function. NFC.
Thanks to Eli for the suggestion!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275366 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-14 03:02:34 +00:00
Davide Italiano
20837ca4c3 [IPSCCP] Constant fold struct argument/instructions when all the lattice values are constant.
This now should also work with the interprocedural variant of the pass.
Slightly easier now that the yak is shaved.

Differential Revision:   http://reviews.llvm.org/D22329

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275363 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-14 02:51:41 +00:00
Davide Italiano
0f630b6089 [SCCP] Generalize tryToReplaceInstWithConstant to work also with arguments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275357 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-14 01:27:29 +00:00
Davide Italiano
1fed24e4d7 [SCCP] Have the logic for replacing insts with constant in a single place.
The code was pretty much copy-pasted between SCCP and IPSCCP. The situation
became clearly worse after I introduced the support for folding structs in
SCCP.  This commit is NFC as we currently (still) skip the replacement
step in IPSCCP, but I'll change this soon.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275339 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-13 23:20:04 +00:00
Davide Italiano
c57350c893 [SCCP] Factor out common code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275308 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-13 19:33:25 +00:00
Davide Italiano
06c68c215f [SCCP] Use early return. NFCI.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275307 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-13 19:23:30 +00:00
Davide Italiano
e0deca8874 [SCCP] Constant fold structs if all the lattice value are constant.
Differential Revision:   http://reviews.llvm.org/D22269

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275208 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-12 19:54:19 +00:00
Davide Italiano
84af877236 [SCCP] Try to follow the DRY principle, use OpSt.
Thanks to Eli Friedman for pointing out in his post-commit review!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275084 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-11 18:21:29 +00:00
Davide Italiano
4c6356e8c6 [SCCP] Rename undefined -> unknown.
In the solver, isUndefined() does really mean "we don't know the
value yet" rather than "this is an UndefinedValue". Discussed with
Eli Friedman.

Differential Revision:  http://reviews.llvm.org/D22192

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275004 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-10 00:35:15 +00:00
Davide Italiano
81fe784be2 [SCCP] Remove wrong and misleading vector handling code.
This code was already commented out and it made some weird assumptions,
e.g. using isUndefined() as "this value is UndefValue" instead of
"we haven't computed this value is yet". Thanks to Eli Friedman for
pointing out where I was wrong (and where this code was wrong).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274995 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-09 22:49:35 +00:00
Davide Italiano
a5b3bc1479 [SCCP] Fold constants as we build them whne visiting cast instructions.
This should be slightly more efficient and could avoid spurious overdefined
markings, as Eli pointed out.

Differential Revision:  http://reviews.llvm.org/D22122

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274905 91177308-0d34-0410-b5e6-96231b3b80d8
2016-07-08 19:13:40 +00:00
Benjamin Kramer
5288df58b7 Apply clang-tidy's modernize-loop-convert to most of lib/Transforms.
Only minor manual fixes. No functionality change intended.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273808 91177308-0d34-0410-b5e6-96231b3b80d8
2016-06-26 12:28:59 +00:00
David Majnemer
db5173a31d Revert "[SimplifyCFG] Stop inserting calls to llvm.trap for UB"
This reverts commit r273778, it seems to break UBSan :/

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273779 91177308-0d34-0410-b5e6-96231b3b80d8
2016-06-25 08:19:55 +00:00
David Majnemer
46e1183e69 [SimplifyCFG] Stop inserting calls to llvm.trap for UB
SimplifyCFG had logic to insert calls to llvm.trap for two very
particular IR patterns: stores and invokes of undef/null.

While InstCombine canonicalizes certain undefined behavior IR patterns
to stores of undef, phase ordering means that this cannot be relied upon
in general.

There are much better tools than llvm.trap: UBSan and ASan.

N.B. I could be argued into reverting this change if a clear argument as
to why it is important that we synthesize llvm.trap for stores, I'd be
hard pressed to see why it'd be useful for invokes...

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273778 91177308-0d34-0410-b5e6-96231b3b80d8
2016-06-25 08:04:19 +00:00
David Majnemer
e77d9ad231 [SCCP] Don't assume all Constants are ConstantInt
This fixes PR28269.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273521 91177308-0d34-0410-b5e6-96231b3b80d8
2016-06-23 00:14:29 +00:00
Davide Italiano
e557ebe45a [PM] SCCP should preserve GlobalsAA even if the IR is mutated.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271149 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-29 00:31:15 +00:00
Davide Italiano
88f5077adc [SCCP] Prefer class to struct.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270074 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-19 15:58:02 +00:00
Davide Italiano
d77d4c07fb [PM] Port per-function SCCP to the new pass manager.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269937 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-18 15:18:25 +00:00
Davide Italiano
99d340ac17 [PM/SCCP] Fix pass dependencies.
TargetLibraryInfoWrapperPass is a dependency of
SCCP but it's not listed as such. Chandler pointed
out this is an easy mistake to make which only
surfaces in weird crashes with some flag combinations.
This code will go away anyway at some point in the
future, but as long as it's (still) exercised, try
to make it correct.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269589 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-15 08:04:28 +00:00
Davide Italiano
4f31f3a2fd [SCCP] Use range-based for loops. NFC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269578 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-14 20:59:09 +00:00
David Majnemer
b0f9f5bfc7 [SCCP] Resolve shifts beyond the bitwidth to undef
Shifts beyond the bitwidth are undef but SCCP resolved them to zero.
Instead, DTRT and resolve them to undef.

This reimplements the transform which caused PR27712.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269269 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-12 03:07:40 +00:00
Davide Italiano
e5b9c737be Revert "[SCCP] Partially propagate informations when the input is not fully defined."
This reverts commit r269105 as it caused PR27712.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269252 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-11 23:06:10 +00:00
Davide Italiano
5f206cf7b0 [SCCP] Partially propagate informations when the input is not fully defined.
With this patch:
%r1 = lshr i64 -1, 4294967296 -> undef

Before this patch:
%r1 = lshr i64 -1, 4294967296 -> 0

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269105 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-10 19:49:47 +00:00
Davide Italiano
2d1483c124 [PM] Port Interprocedural SCCP to the new pass manager.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268684 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-05 21:05:36 +00:00
Davide Italiano
252a6d1f04 Revert "[SCCP] Throw away dead code. NFC."
This reverts commit r268568, as it broke the bots.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268570 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-04 23:27:13 +00:00
Davide Italiano
9c9f877ca2 [SCCP] Throw away dead code. NFC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268568 91177308-0d34-0410-b5e6-96231b3b80d8
2016-05-04 23:05:59 +00:00
Andrew Kaylor
1e455c5cfb Re-commit optimization bisect support (r267022) without new pass manager support.
The original commit was reverted because of a buildbot problem with LazyCallGraph::SCC handling (not related to the OptBisect handling).

Differential Revision: http://reviews.llvm.org/D19172



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267231 91177308-0d34-0410-b5e6-96231b3b80d8
2016-04-22 22:06:11 +00:00
Vedant Kumar
8866d94a61 Revert "Initial implementation of optimization bisect support."
This reverts commit r267022, due to an ASan failure:

  http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/1549

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267115 91177308-0d34-0410-b5e6-96231b3b80d8
2016-04-22 06:51:37 +00:00
Andrew Kaylor
c852398cbc Initial implementation of optimization bisect support.
This patch implements a optimization bisect feature, which will allow optimizations to be selectively disabled at compile time in order to track down test failures that are caused by incorrect optimizations.

The bisection is enabled using a new command line option (-opt-bisect-limit).  Individual passes that may be skipped call the OptBisect object (via an LLVMContext) to see if they should be skipped based on the bisect limit.  A finer level of control (disabling individual transformations) can be managed through an addition OptBisect method, but this is not yet used.

The skip checking in this implementation is based on (and replaces) the skipOptnoneFunction check.  Where that check was being called, a new call has been inserted in its place which checks the bisect limit and the optnone attribute.  A new function call has been added for module and SCC passes that behaves in a similar way.

Differential Revision: http://reviews.llvm.org/D19172



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267022 91177308-0d34-0410-b5e6-96231b3b80d8
2016-04-21 17:58:54 +00:00
Sanjoy Das
c9e3e3cbfd Don't IPO over functions that can be de-refined
Summary:
Fixes PR26774.

If you're aware of the issue, feel free to skip the "Motivation"
section and jump directly to "This patch".

Motivation:

I define "refinement" as discarding behaviors from a program that the
optimizer has license to discard.  So transforming:

```
void f(unsigned x) {
  unsigned t = 5 / x;
  (void)t;
}
```

to

```
void f(unsigned x) { }
```

is refinement, since the behavior went from "if x == 0 then undefined
else nothing" to "nothing" (the optimizer has license to discard
undefined behavior).

Refinement is a fundamental aspect of many mid-level optimizations done
by LLVM.  For instance, transforming `x == (x + 1)` to `false` also
involves refinement since the expression's value went from "if x is
`undef` then { `true` or `false` } else { `false` }" to "`false`" (by
definition, the optimizer has license to fold `undef` to any non-`undef`
value).

Unfortunately, refinement implies that the optimizer cannot assume
that the implementation of a function it can see has all of the
behavior an unoptimized or a differently optimized version of the same
function can have.  This is a problem for functions with comdat
linkage, where a function can be replaced by an unoptimized or a
differently optimized version of the same source level function.

For instance, FunctionAttrs cannot assume a comdat function is
actually `readnone` even if it does not have any loads or stores in
it; since there may have been loads and stores in the "original
function" that were refined out in the currently visible variant, and
at the link step the linker may in fact choose an implementation with
a load or a store.  As an example, consider a function that does two
atomic loads from the same memory location, and writes to memory only
if the two values are not equal.  The optimizer is allowed to refine
this function by first CSE'ing the two loads, and the folding the
comparision to always report that the two values are equal.  Such a
refined variant will look like it is `readonly`.  However, the
unoptimized version of the function can still write to memory (since
the two loads //can// result in different values), and selecting the
unoptimized version at link time will retroactively invalidate
transforms we may have done under the assumption that the function
does not write to memory.

Note: this is not just a problem with atomics or with linking
differently optimized object files.  See PR26774 for more realistic
examples that involved neither.

This patch:

This change introduces a new set of linkage types, predicated as
`GlobalValue::mayBeDerefined` that returns true if the linkage type
allows a function to be replaced by a differently optimized variant at
link time.  It then changes a set of IPO passes to bail out if they see
such a function.

Reviewers: chandlerc, hfinkel, dexonsmith, joker.eph, rnk

Subscribers: mcrosier, llvm-commits

Differential Revision: http://reviews.llvm.org/D18634

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265762 91177308-0d34-0410-b5e6-96231b3b80d8
2016-04-08 00:48:30 +00:00