1191 Commits

Author SHA1 Message Date
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
Nikita Popov
dfde0773fd
[SimplifyCFG] More accurate use legality check for sinking (#94462)
When sinking instructions, we have to make sure that the uses of that
instruction are consistent: If used in a phi node in the sink target,
then the phi operands have to match the sink candidates. This allows the
phi to be removed when the instruction is sunk. This case is already
handled accurately.

However, what the current code doesn't handle are uses in the same
block. These are just unconditionally accepted, even though this needs
the same consistency check for the phi node that sinking the using
instruction would introduce.

Instead, the code has another check when actually performing the
sinking, which repeats the phi check (just at a later time, where all
the later instructions have already been sunk and any new phis
introduced).

This is problematic, because it messes up the profitability heuristic.
The code will think that certain instructions will get sunk, but they
actually won't. This may result in more phi nodes being created than is
considered profitable. See the changed test for a case where we no
longer do this after this patch.

The new approach makes sure that the uses are consistent during the
initial legality check. This is based on PhiOperands, which we already
collect.

The primary motivation for this is to generalize sinking to support more
than one use, and doing that generalization is hard with the current
split checking approach.
2024-06-14 10:38:50 +02:00
DaPorkchop_
540f68c44f
[SimplifyCFG] Don't use a mask for lookup tables generated from switches with an unreachable default case (#94468)
When transforming a switch with holes into a lookup table, we currently
use a mask to check if the current index is handled by the switch or if
it is a hole. If it is a hole, we skip loading from the lookup table.
Normally, if the switch's default case is unreachable this has no
impact, as the mask test gets optimized away by subsequent passes.
However, if the switch is large enough that the number of lookup table
entries exceeds the target's register width, we won't be able to fit all
the cases into a mask and the switch won't get transformed into a lookup
table. If we know that the switch's default case is unreachable, we know
that the mask is unnecessary and can skip constructing it entirely,
which allows us to transform the switch into a lookup table.

[Example](https://godbolt.org/z/7x7qfx8M1)

In the future, it might be interesting to consider allowing lookup table
masks to be more than one register large (e.g. using a constant array of
bit flags, similar to `std::bitset`).
2024-06-08 21:32:34 +08:00
Nikita Popov
8719cb88e3 [SimplifyCFG] Regenerate switch to lookup tests (NFC)
Regenerate these with --check-globals. The manual global CHECKS
get dropped during regeneration otherwise.

Annoyingly UTC insists on putting the globals directly before the
first function, so the first comment is a bit out of place now.
2024-06-07 11:51:51 +02:00
Nikita Popov
1934c1aa36 [SimplifyCFG] Remove bogus UTC line from test (NFC)
The check lines in this test were clearly not generated by UTC.
2024-06-07 11:51:51 +02:00
Nikita Popov
07b9d231ff [SimplifyCFG] Regenerate test checks (NFC)
The output for many of these slightly changed (mainly due to
switch indentation), so mass-regenerate them.
2024-06-05 17:06:25 +02:00
Simon Pilgrim
991d2fb3ea [SimplifyCFG] branch-fold-threshold.ll - regenerate checks 2024-06-05 15:33:56 +01:00
Nikita Popov
851710d791 [SimplifyCFG] Add additional tests for sinking (NFC)
This covers some interesting edge cases when the sink target is
a loop header.
2024-06-05 12:45:56 +02:00
Nikita Popov
775ebc1d71 [SimplifyCFG] Regenerate test checks (NFC) 2024-06-05 10:31:46 +02:00
Nikita Popov
deab451e7a
[IR] Remove support for icmp and fcmp constant expressions (#93038)
Remove support for the icmp and fcmp constant expressions.

This is part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179

As usual, many of the updated tests will no longer test what they were
originally intended to -- this is hard to preserve when constant
expressions get removed, and in many cases just impossible as the
existence of a specific kind of constant expression was the cause of the
issue in the first place.
2024-06-04 08:31:03 +02:00
Simon Pilgrim
1388562922 [SimplifyCFG] branch-fold-threshold.ll - fix broken CHECKs
Fix typos in AGGRESIVE-->AGGRESSIVE + WAYAGGRESIVE->WAYAGGRESSIVE

This also exposed an issue that the WAYAGGRESSIVE run removed a block entirely, so the LABEL check was silently failing.

Noticed while triaging the failures on #93673
2024-06-03 15:31:32 +01:00
Nikita Popov
63dc31b68b Reapply [IR] Avoid creating icmp/fcmp constant expressions (#92885)
Reapply after https://github.com/llvm/llvm-project/pull/93548,
which should address the lldb failure on macos.

-----

Do not create icmp/fcmp constant expressions in IRBuilder etc anymore,
i.e. treat them as "undesirable". This is in preparation for removing
them entirely.

Part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
2024-05-31 08:55:59 +02:00
Nikita Popov
8cdecd4d3a
[IR] Add getelementptr nusw and nuw flags (#90824)
This implements the `nusw` and `nuw` flags for `getelementptr` as
proposed at
https://discourse.llvm.org/t/rfc-add-nusw-and-nuw-flags-for-getelementptr/78672.

The three possible flags are encapsulated in the new `GEPNoWrapFlags`
class. Currently this class has a ctor from bool, interpreted as the
InBounds flag. This ctor should be removed in the future, as code gets
migrated to handle all flags.

There are a few places annotated with `TODO(gep_nowrap)`, where I've had
to touch code but opted to not infer or precisely preserve the new
flags, so as to keep this as NFC as possible and make sure any changes
of that kind get test coverage when they are made.
2024-05-27 16:05:17 +02:00
Qiongsi Wu
7dc2f66022
Reland "[SimplifyCFG] switch: Do Not Transform the Default Case if the Condition is Too Wide (#77831)"
https://github.com/llvm/llvm-project/pull/76669 taught SimplifyCFG to
handle switches when `default` has only one case. When the `switch`'s
condition is wider than 64 bit, the current implementation can calculate
the wrong default value. This PR skips cases where the condition is too
wide.

(cherry picked from commit 39bb790b906f4921a5d9fc09e856abe53ae7a320)
2024-05-25 10:38:44 +08:00
DianQK
64ed699b3d
Reland "[SimplifyCFG] When only one case value is missing, replace default with that case (#76669)"
When the default branch is the last case, we can transform that branch
into a concrete branch with an unreachable default branch.

```llvm
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i64 @src(i64 %0) {
  %2 = urem i64 %0, 4
  switch i64 %2, label %5 [
    i64 1, label %3
    i64 2, label %3
    i64 3, label %4
  ]

3:                                                ; preds = %1, %1
  br label %5

4:                                                ; preds = %1
  br label %5

5:                                                ; preds = %1, %4, %3
  %.0 = phi i64 [ 2, %4 ], [ 1, %3 ], [ 0, %1 ]
  ret i64 %.0
}

define i64 @tgt(i64 %0) {
  %2 = urem i64 %0, 4
  switch i64 %2, label %unreachable [
    i64 0, label %5
    i64 1, label %3
    i64 2, label %3
    i64 3, label %4
  ]

unreachable:                              ; preds = %1
  unreachable

3:                                                ; preds = %1, %1
  br label %5

4:                                                ; preds = %1
  br label %5

5:                                                ; preds = %1, %4, %3
  %.0 = phi i64 [ 2, %4 ], [ 1, %3 ], [ 0, %1 ]
  ret i64 %.0
}
```

Alive2: https://alive2.llvm.org/ce/z/Y-PGXv

After transform to a lookup table, I believe `tgt` is better code.

The final instructions are as follows:

```asm
src:                                    # @src
        and     edi, 3
        lea     rax, [rdi - 1]
        cmp     rax, 2
        ja      .LBB0_1
        mov     rax, qword ptr [8*rdi + .Lswitch.table.src-8]
        ret
.LBB0_1:
        xor     eax, eax
        ret
tgt:                                    # @tgt
        and     edi, 3
        mov     rax, qword ptr [8*rdi + .Lswitch.table.tgt]
        ret
.Lswitch.table.src:
        .quad   1                               # 0x1
        .quad   1                               # 0x1
        .quad   2                               # 0x2

.Lswitch.table.tgt:
        .quad   0                               # 0x0
        .quad   1                               # 0x1
        .quad   1                               # 0x1
        .quad   2                               # 0x2
```

Godbolt: https://llvm.godbolt.org/z/borME8znd

Closes #73446.

(cherry picked from commit 7d81e072712f4e6a150561b5538ccebda289aa13)
2024-05-25 10:38:19 +08:00
Daniel Thornburgh
8baf96f306
Revert "[IR] Avoid creating icmp/fcmp constant expressions" (#93087)
Reverts llvm/llvm-project#92885 due to LLDB CI breakages.
2024-05-22 11:27:55 -07:00
Nikita Popov
108575f02e
[IR] Avoid creating icmp/fcmp constant expressions (#92885)
Do not create icmp/fcmp constant expressions in IRBuilder etc anymore,
i.e. treat them as "undesirable". This is in preparation for removing
them entirely.

Part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
2024-05-22 07:40:08 +02:00