1207 Commits

Author SHA1 Message Date
elhewaty
9efb07f261
[IR] Add samesign flag to icmp instruction (#111419)
Inspired by
https://discourse.llvm.org/t/rfc-signedness-independent-icmps/81423
2024-10-15 17:11:25 +08:00
Noah Goldstein
82ac399733 [SimplifyCFG] Allow merging invoke's with different attrs
Same logic as other callsites, if the attributes are intersectable, we
merge.

Closes #111713
2024-10-10 01:07:59 -05:00
Noah Goldstein
cd04a9d401 [SimplifyCFG] Add/update tests for merging invokes with different attrs; NFC 2024-10-10 01:07:59 -05:00
Matt Arsenault
a8e1311a1c
[RFC] IR: Define noalias.addrspace metadata (#102461)
This is intended to solve a problem with lowering atomics in
OpenMP and C++ common to AMDGPU and NVPTX.

In OpenCL and CUDA, it is undefined behavior for an atomic instruction
to modify an object in thread private memory. In OpenMP, it is defined.
Correspondingly, the hardware does not handle this correctly. For
AMDGPU,
32-bit atomics work and 64-bit atomics are silently dropped. We
therefore
need to codegen this by inserting a runtime address space check,
performing
the private case without atomics, and fallback to issuing the real
atomic
otherwise. This metadata allows us to avoid this extra check and branch.

Handle this by introducing metadata intended to be applied to atomicrmw,
indicating they cannot access the forbidden address space.
2024-10-07 23:21:42 +04:00
Noah Goldstein
e343af777e [SimplifyCFG][Attributes] Enabling sinking calls with differing number of attrsets
Prior impl would fail if the number of attribute sets on the two calls
wasn't the same which is unnecessary as long as we aren't throwing
away and must-preserve attrs.

Closes #110896
2024-10-02 15:15:07 -05:00
Noah Goldstein
baf008ac29 [SimplifyCFG] Add tests for sinking calls with differing number of attrs; NFC 2024-10-02 15:15:07 -05:00
Noah Goldstein
4d4beeb43c [SimplifyCFG] Supporting hoisting/sinking callbases with differing attrs
Some (many) attributes can safely be dropped to enable sinking. For
example removing `nonnull` on a return/param can't affect correctness.

Closes #109472
2024-10-01 18:27:08 -05:00
Noah Goldstein
c42659417f [SimplifyCFG] Add tests for hoisting/sinking callbases with differing attrs; NFC 2024-10-01 18:27:08 -05:00
Nikita Popov
f445e39ab2
[SimplifyCFG] Use isWritableObject() API (#110127)
SimplifyCFG store speculation currently has some homegrown code to check
for a writable object, handling the alloca special case only.

Switch it to use the generic isWritableObject() API, which means that we
also support byval arguments, allocator return values, and writable
arguments.

I've adjusted isWritableObject() to also check for the noalias attribute
when handling writable. Otherwise, I don't think that we can generalize
from at-entry writability. This was not relevant for previous uses of
the function, because they'd already require noalias for other reasons
anyway.
2024-09-30 10:03:46 +02:00
Nikita Popov
8f21459777 [SimplifyCFG] Add additional store speculation tests (NFC) 2024-09-26 16:20:06 +02:00
Chengjun
e4688b98cd
[SimplifyCFG] Avoid increasing too many phi entries when removing empty blocks (#104887)
Now in the simplifycfg and jumpthreading passes, we will remove the
empty blocks (blocks only have phis and an unconditional branch).
However, in some cases, this will increase size of the IR and slow down
the compile of other passes dramatically. For example, we have the
following CFG:

1. BB1 has 100 predecessors, and unconditionally branches to BB2 (does
not have any other instructions).
2. BB2 has 100 phis.

Then in this case, if we remove BB1, for every phi in BB2, we need to
increase 99 entries (replace the incoming edge from BB1 with 100 edges
from its predecessors). Then in total, we will increase 9900 phi
entries, which can slow down the compile time for many other passes.

Therefore, in this change, we add a check to see whether removing the
empty blocks will increase lots of phi entries. Now, the threshold is
1000 (can be controlled by the command line option
`max-phi-entries-increase-after-removing-empty-block`), which means that
we will not remove an empty block if it will increase the total number
of phi entries by 1000. This threshold is conservative and for most of
the cases, we will not have such a large phi. So, this will only be
triggered in some unusual IRs.
2024-09-25 12:41:13 +02:00
Nikita Popov
6f194a6dea [SimplifyCFG] Avoid truncation in linear map overflow check
This is supposed to test multiplication of the linear multiplifier
with the largest value it can be multiplied with. However, if
we truncate TableSize-1 here, it might not actually be the largest
value. I think in practice this still works out, because in cases
where we'd truncate the value here we'd also fail the NonMonotonic
check. But to match the intent of the code, we should treat the
truncating case as overflowing.
2024-09-23 15:13:32 +02:00
Phoebe Wang
7773dcd163
[X86][NFC] Change test name and add a new test (#109638)
Address post commit comments in #108754.
2024-09-23 20:21:11 +08:00
Nikita Popov
8a6248b739
[SimplifyCFG] Don't separate a load/store from its gep during sinking (#102318)
If we can sink the a load/store, but not the gep producing its pointer
operand, don't sink the load/store either. This may prevent the gep from
being folded into an addressing mode, and may also negatively affect
further analysis.

Fixes https://github.com/llvm/llvm-project/issues/96838.
2024-09-23 09:32:24 +02:00
Nikita Popov
5a4c6f9799
[Loads] Check context instruction for context-sensitive derefability (#109277)
If a dereferenceability fact is provided through `!dereferenceable` (or
similar), it may only hold on the given control flow path. When we use
`isSafeToSpeculativelyExecute()` to check multiple instructions, we
might make use of `!dereferenceable` information that does not hold at
the speculation target. This doesn't happen when speculating
instructions one by one, because `!dereferenceable` will be dropped
while speculating.

Fix this by checking whether the instruction with `!dereferenceable`
dominates the context instruction. If this is not the case, it means we
are speculating, and cannot guarantee that it holds at the speculation
target.

Fixes https://github.com/llvm/llvm-project/issues/108854.
2024-09-23 09:13:09 +02:00
Nikita Popov
30cdf1e959
[SimplifyCFG] Pass context instruction to isSafeToSpeculativelyExecute() (#109132)
Pass speculation target and assumption cache to
isSafeToSpeculativelyExecute() calls.

This allows speculating based on dereferenceable/align assumptions, but
the primary motivation here is to avoid regressions from planned changes
to fix https://github.com/llvm/llvm-project/issues/108854.
2024-09-19 10:19:15 +02:00
Noah Goldstein
37932643ab [SimplifyCFG] Deduce paths unreachable if they cause div/rem UB
Same we way mark a path unreachable if it may cause a nullptr
dereference, div/rem by zero or signed div/rem of INT_MIN by -1 cause
immediate UB.

Closes #109008
2024-09-18 12:59:52 -05:00
Noah Goldstein
f5d62d7647 [SimplifyCFG] Add tests for deducing paths unreachable if they cause div/rem UB; NFC 2024-09-18 12:59:52 -05:00
Nikita Popov
13b4d1bfea [SimplifyCFG][LICM] Add additional speculation tests
These are related to https://github.com/llvm/llvm-project/issues/108854.
2024-09-18 14:48:58 +02:00
Noah Goldstein
419c53477e [SimplifyCFG] Mark div/rem as not-cheap to sink if we are replacing const denominator
Close #109007
2024-09-17 12:04:34 -05:00
Noah Goldstein
ae8d0200b0 [SimplifyCFG] Add test for sinking div/rem with const remainder; NFC 2024-09-17 12:04:34 -05:00
Andreas Jonson
a0d00c94c2
[SimplifyCFG] Swap range metadata to attribute for calls. (#108984)
Among the last usages of range metadata for call before being able to
deprecate and only have the range attribute for calls.
2024-09-17 18:25:53 +02:00
Csanád Hajdú
bc8a5d104c
[Patchpoint] Add immarg attributes to patchpoint arguments (#97276) 2024-09-17 14:00:24 +04:00
Phoebe Wang
af5a45b34b
[X86,SimplifyCFG] Use passthru to reduce select (#108754) 2024-09-16 20:20:36 +08:00
AdityaK
3c9022c965
Bail out jump threading on indirect branches (#103688)
The bug was introduced by
https://github.com/llvm/llvm-project/pull/68473

Fixes: #102351
2024-09-10 22:39:02 -07:00
Shengchen Kan
87c86aa6b9
[X86,SimplifyCFG] Support hoisting load/store with conditional faulting (Part I) (#96878)
This is simplifycfg part of
https://github.com/llvm/llvm-project/pull/95515

In this PR, we support hoisting load/store with conditional faulting in
`SimplifyCFGOpt::speculativelyExecuteBB` to eliminate conditional
branches.
This is for cases like
```
void test (int a, int *b) {
  if (a)
   *b = a;
}
``` 

In the following patches, we will support the hoist in
`SimplifyCFGOpt::hoistCommonCodeFromSuccessors`.
That is for cases like
```
void test (int a, int *c, int *d) {
  if (a)
   *c = a;
  else 
   *d = a;
}
```
2024-08-29 10:42:44 +08:00
Nikita Popov
84497c6f4f
[SimplifyCFG] Remove limitation on sinking of load/store of alloca (#104788)
This is a followup to https://github.com/llvm/llvm-project/pull/104579
to remove the limitation on sinking loads/stores of allocas entirely,
even if this would introduce a phi node.

Nowadays, SROA supports speculating load/store over select/phi.
Additionally, SimplifyCFG with sinking only runs at the end of the
function simplification pipeline, after SROA. I checked that the two
tests modified here still successfully SROA after the SimplifyCFG
transform.

We should, however, keep the limitation on lifetime intrinsics. SROA
does not have speculation support for these, and I've also found that
the way these are handled in the backend is very problematic
(https://github.com/llvm/llvm-project/issues/104776), so I think we
should leave them alone.
2024-08-26 10:14:43 +02:00
Nikita Popov
4d85285ff6
[SimplifyCFG] Fold switch over ucmp/scmp to icmp and br (#105636)
If we switch over ucmp/scmp and have two switch cases going to the same
destination, we can convert into icmp+br.

Fixes https://github.com/llvm/llvm-project/issues/105632.
2024-08-22 16:57:09 +02:00
Nikita Popov
716f7e2d18 [SimplifyCFG] Add tests for switch over cmp intrinsic (NFC) 2024-08-22 11:52:02 +02:00
Nikita Popov
b3fa45b642
[SimplifyCFG] Add support for hoisting commutative instructions (#104805)
This extends SimplifyCFG hoisting to also hoist instructions with
commuted operands, for example a+b on one side and b+a on the other
side.

This should address the issue mentioned in:
https://github.com/llvm/llvm-project/pull/91185#issuecomment-2097447927
2024-08-20 12:48:06 +02:00
Nikita Popov
b64e7e07e5 [SimplifyCFG] Add tests for hoisting of commutative instructions (NFC) 2024-08-19 17:13:21 +02:00
Nikita Popov
83879f4f53
[SimplifyCFG] Don't block sinking for allocas if no phi created (#104579)
SimplifyCFG sinking currently does not sink loads/stores of allocas,
because historically SROA was unable to handle the resulting IR. Since
then, SROA both learned to speculate loads/stores over selects and phis,
*and* SimplifyCFG sinking has been deferred to the end of the function
simplification pipeline, which means that SROA happens before it.

As such, I believe that this workaround should no longer be necessary.
Given how sensitive SimplifyCFG sinking seems to be, this patch takes a
very conservative step towards removing this, by allowing sinking if we
don't actually need to form a phi over the pointer argument.

This fixes https://github.com/llvm/llvm-project/issues/104567, where
sinking a store to an escaped alloca allows converting a switch into
arithmetic.
2024-08-19 09:55:30 +02:00
Nikita Popov
65390f9d6f [SimplifyCFG] Add test for #104567 (NFC) 2024-08-16 12:37:18 +02:00
Nikita Popov
1139dee910 [SimplifyCFG] Add more sinking tests (NFC) 2024-08-08 15:13:59 +02:00
Nikita Popov
999bab711e [SimplifyCFG] Add tests for sinking of load/store + gep (NFC) 2024-08-07 16:51:18 +02:00
Jan Patrick Lehr
a347bdb2b8
Revert "[SimplifyCFG] Skip threading if the target may have divergent branches" (#100994)
Reverts llvm/llvm-project#100185

See comments on PR (PR not accepted, outstanding review comments, breaks HIP-clang buildbot)
2024-07-29 11:34:26 +02:00
darkbuck
ba45453c0a
[SimplifyCFG] Skip threading if the target may have divergent branches
- This patch skips the threading on known values if the target has
  divergent branch.
- So far, threading on known values is skipped when the basic block has
  covergent calls. However, even without convergent calls, if that
  condition is divergent, threading duplicates the execution of that
  block threaded and hence results in lower performance. E.g.,
  ```
  BB1:
    if (cond) BB3, BB2

  BB2:
    // work2
    br BB3

  BB3:
    // work3
    if (cond) BB5, BB4

  BB4:
    // work4
    br BB5

  BB5:
  ```

  after threading,

  ```
  BB1:
    if (cond) BB3', BB2'

  BB2':
    // work3
    br BB5

  BB3':
    // work2
    // work3
    // work4
    br BB5

  BB5:

  ```

  After threading, work3 is executed twice if 'cond' is a divergent one.

Reviewers: yxsamliu, nikic

Pull Request: https://github.com/llvm/llvm-project/pull/100185
2024-07-26 12:15:49 -04:00
Tianqing Wang
03e92bf483
[SimplifyCFG] Fix LIT failure introduced in 3d494bfc7. (#100049) 2024-07-23 09:50:04 +08:00
Tianqing Wang
3d494bfc7f
[SimplifyCFG] Increase budget for FoldTwoEntryPHINode() if the branch is unpredictable. (#98495)
The `!unpredictable` metadata has been present for a long time, but
it's usage in optimizations is still limited. This patch teaches
`FoldTwoEntryPHINode()` to be more aggressive with an unpredictable
branch to reduce mispredictions.

A TTI interface `getBranchMispredictPenalty()` is added to distinguish
between different hardwares to ensure we don't go too far for simpler
cores. For simplicity, only a naive x86 implementation is included for
the time being.
2024-07-23 07:47:21 +08:00
DianQK
8afb6432c2
[SimplifyCFG] Select the first instruction that we can handle in passingValueIsAlwaysUndefined (#98802)
Fixes #98799.
2024-07-16 19:06:32 +08:00
Shan Huang
7c4dbad550
[DebugInfo][SimplifyCFGPass] Fix the missing debug location update for the new br instruction (#97389)
Fix #97388 .
2024-07-05 14:10:04 +08:00
Yingwei Zheng
4997af98a0
[SimplifyCFG] Simplify nested branches (#97067)
This patch folds the following pattern (I don't know what to call this):
```
bb0:
  br i1 %cond1, label %bb1, label %bb2
bb1:
  br i1 %cond2, label %bb3, label %bb4
bb2:
  br i1 %cond2, label %bb4, label %bb3
bb3:
  ...
bb4:
  ...
```
into
```
bb0:
  %cond = xor i1 %cond1, %cond2
  br i1 %cond, label %bb4, label %bb3
bb3:
  ...
bb4:
  ...
```

Alive2: https://alive2.llvm.org/ce/z/5iOJEL
Closes https://github.com/llvm/llvm-project/issues/97022.
Closes https://github.com/llvm/llvm-project/issues/83417.

I found this pattern in some verilator-generated code, which is widely
used in RTL simulation. This fold will reduces branches and improves the
performance of CPU frontend. To my surprise, this pattern is also common
in C/C++ code base.
Affected libraries/applications:
cmake/cvc5/freetype/git/gromacs/jq/linux/openblas/openmpi/openssl/php/postgres/ruby/sqlite/wireshark/z3/...
2024-07-01 03:35:39 +08:00
Florian Hahn
001da2214c
[SimplifyCFG] Add test for hoisting loads with tbaa metadata. 2024-06-29 10:39:02 +01:00
DianQK
5a052ef76a
Reapply "[SimplifyCFG] Forward indirect switch condition value if it can help fold the PHI (#95932)"
This reverts commit c7adfb5e715334c9de176f434088bd9f89aa9eb3.
2024-06-27 07:23:59 +08:00
DianQK
c7adfb5e71
Revert "[SimplifyCFG] Forward indirect switch condition value if it can help fold the PHI (#95932)"
This reverts commit 0c56fd0a29ffb0425ca2ee2a4ff8f380880fdbfa.
This is breaking https://lab.llvm.org/buildbot/#/builders/72/builds/483.
2024-06-27 06:49:40 +08:00
DianQK
0c56fd0a29
[SimplifyCFG] Forward indirect switch condition value if it can help fold the PHI (#95932)
Fixes #95919.
2024-06-27 05:49:33 +08:00
DianQK
1d76bf900b
[SimplifyCFG] Remove unnecessary content in ForwardSwitchConditionToPHI.ll (NFC)
Also rename `t` to forward_multiple`.
2024-06-18 22:01:36 +08:00
Nikita Popov
ede27d8d39
[SimplifyCFG] Add support for sinking instructions with multiple uses (#95521)
Sinking currently only supports instructions that have zero or one uses.
Extend this to handle instructions with any number of uses, as long as
all uses are consistent (i.e. the "same" for all sinking candidates).

After #94462 this is basically just a matter of looping over all uses
instead of checking the first one only.
2024-06-17 08:48:30 +02:00
Stephen Tozer
094572701d
[RemoveDIs] Print IR with debug records by default (#91724)
This patch makes the final major change of the RemoveDIs project, changing the
default IR output from debug intrinsics to debug records. This is expected to
break a large number of tests: every single one that tests for uses or
declarations of debug intrinsics and does not explicitly disable writing
records. 

If this patch has broken your downstream tests (or upstream tests on a
configuration I wasn't able to run):
1. If you need to immediately unblock a build, pass
`--write-experimental-debuginfo=false` to LLVM's option processing for all
failing tests (remember to use `-mllvm` for clang/flang to forward arguments to
LLVM).
2. For most test failures, the changes are trivial and mechanical, enough that
they can be done by script; see the migration guide for a guide on how to do
this: https://llvm.org/docs/RemoveDIsDebugInfo.html#test-updates
3. If any tests fail for reasons other than FileCheck check lines that need
updating, such as assertion failures, that is most likely a real bug with this
patch and should be reported as such.

For more information, see the recent PSA:
https://discourse.llvm.org/t/psa-ir-output-changing-from-debug-intrinsics-to-debug-records/79578
2024-06-14 15:07:27 +01:00
Nikita Popov
bd5fbab38f [SimplifyCFG] Add tests for sinking with multiple uses (NFC) 2024-06-14 11:00:45 +02:00