698 Commits

Author SHA1 Message Date
Guozhi Wei
84bcfa0e1b [GVN] Improve PRE on load instructions
This patch implements the enhancement proposed by
https://github.com/llvm/llvm-project/issues/59312.

Suppose we have following code

   v0 = load %addr
   br %LoadBB

LoadBB:
   v1 = load %addr
   ...

PredBB:
   ...
   br %cond, label %LoadBB, label %SuccBB

SuccBB:
   v2 = load %addr
   ...

Instruction v1 in LoadBB is partially redundant, edge (PredBB, LoadBB) is a
critical edge. SuccBB is another successor of PredBB, it contains another load
v2 which is identical to v1. Current GVN splits the critical edge
(PredBB, LoadBB) and inserts a new load in it. A better method is move the load
of v2 into PredBB, then v1 can be changed to a PHI instruction.

If there are two or more similar predecessors, like the test case in the bug
entry, current GVN simply gives up because otherwise it needs to split multiple
critical edges. But we can move all loads in successor blocks into predecessors.

Differential Revision: https://reviews.llvm.org/D141712
2023-06-06 19:45:34 +00:00
Nikita Popov
97f0e7b06e [AA] Fix comparison of AliasResults (PR63019)
Comparison between two AliasResults implicitly decayed to comparison
of AliasResult::Kind. As a result, MergeAliasResults() ended up
considering two PartialAlias results with different offsets as
equivalent.

Fix this by adding an operator== implementation. To stay
compatible with extensive use of comparisons between AliasResult
and AliasResult::Kind, add an overload for that as well, which
will ignore the offset. In the future, it would probably be a
good idea to remove these implicit decays to AliasResult::Kind
and add dedicated methods to check for specific AliasResult kinds.

Fixes https://github.com/llvm/llvm-project/issues/63019.
2023-05-31 15:03:41 +02:00
Nikita Popov
4d64ffa941 [GVN] Add test for PR63019 (NFC) 2023-05-31 14:55:25 +02:00
Jay Foad
c86a1e6903 [GVN] Do not combine convergent calls in GVN/NewGVN
Note that this is very conservative since it will not even combine
convergent calls that appear in the same basic block, but EarlyCSE will
handle that case.

Differential Revision: https://reviews.llvm.org/D150974
2023-05-19 21:27:35 +01:00
Jay Foad
41a2c66aee [GVN] Precommit tests for convergent calls in GVN/NewGVN 2023-05-19 16:39:53 +01:00
Jay Foad
7084fb1e28 [GVN] Fix test case for convergent calls
Without "willreturn" this did not get as far as testing the convergent
handling in GVN.
2023-05-19 16:15:06 +01:00
Guozhi Wei
a3fbe5f7e6 Revert "[GVN] Improve PRE on load instructions"
This reverts commit d6811826371d82de074d0c3e10040114eee69897.

It caused sanitized bootstrap failure.
2023-05-17 07:38:22 +00:00
Guozhi Wei
d681182637 [GVN] Improve PRE on load instructions
This patch implements the enhancement proposed by
https://github.com/llvm/llvm-project/issues/59312.

Suppose we have following code

     v0 = load %addr
     br %LoadBB

  LoadBB:
     v1 = load %addr
     ...

  PredBB:
     ...
     br %cond, label %LoadBB, label %SuccBB

  SuccBB:
     v2 = load %addr
     ...

Instruction v1 in LoadBB is partially redundant, edge (PredBB, LoadBB) is a
critical edge. SuccBB is another successor of PredBB, it contains another load
v2 which is identical to v1. Current GVN splits the critical edge
(PredBB, LoadBB) and inserts a new load in it. A better method is move the load
of v2 into PredBB, then v1 can be changed to a PHI instruction.

If there are two or more similar predecessors, like the test case in the bug
entry, current GVN simply gives up because otherwise it needs to split multiple
critical edges. But we can move all loads in successor blocks into predecessors.

Differential Revision: https://reviews.llvm.org/D141712
2023-05-17 01:09:01 +00:00
Mingming Liu
b3cb950cf3 [PGO]Implement metadata combine for 'branch_weights' of direct
callsites when none of the instructions folds the rest away.

- Merge cases are added for simplify-cfg {sink,hoist}, based on https://gcc.godbolt.org/z/avGvc38W7 and https://gcc.godbolt.org/z/dbWbjGhaE
- When one instruction folds the others in, do not update branch_weights
  with sum (see test/Transforms/GVN/calls-readonly.ll)

Differential Revision: https://reviews.llvm.org/D148877
2023-04-27 13:04:17 -07:00
Nikita Popov
20e9b31f88 [GVN] Fix metadata combining for non-local loads
Make MaterializeAdjustedValue() responsible for adjusting load
metadata in all cases, so it also covers the non-local case.

In conjunction with that, we no longer need to call
patchReplacementInstruction() for the local case, which would
unnecessarily drop metadata if the replacement value just happened
to be a load (without actual load CSE).
2023-04-20 12:32:10 +02:00
Nikita Popov
998e823613 [GVN] Add additional metadata combining tests (NFC) 2023-04-20 12:17:53 +02:00
Nikita Popov
8cdca96690 [GVN] Adjust metadata for coerced load CSE
When reusing a load in a way that requires coercion (i.e. casts or
bit extraction) we currently fail to adjust metadata. Unfortunately,
none of our existing tooling for this is really suitable, because
combineMetadataForCSE() expects both loads to have the same type.
In this case we may work on loads of different types and possibly
offset memory location.

As such, what this patch does is to simply drop all metadata, with
the following exceptions:

* Metadata for which violation is known to always cause UB.
* If the load is !noundef, keep all metadata, as this will turn
  poison-generating metadata into UB as well.

This fixes the miscompile that was exposed by D146629.

Differential Revision: https://reviews.llvm.org/D148129
2023-04-17 12:52:31 +02:00
Nikita Popov
e4251fc6bb [LangRef][Local] dereferenceable metadata violation is UB
I believe !dereferencable violation is immediate undefined behavior,
but this was not explicitly spelled out in LangRef. We already
assume that !dereferenceable is implicitly !noundef and cannot
return poison in isGuaranteedNotToBeUndefOrPoison().

The reason why we made dereferenceable implicitly noundef is that
the purpose of this metadata is to allow speculation, and that
would not be legal on a potential poison pointer.

Differential Revision: https://reviews.llvm.org/D148202
2023-04-14 10:54:01 +02:00
Nikita Popov
1c656df581 [GVN][SimplifyCFG] Add tests for dereferenceable metadata combining (NFC) 2023-04-13 10:55:34 +02:00
Nikita Popov
6e56cdac30 [GVN] Regenerate test checks (NFC) 2023-04-12 16:16:29 +02:00
Nikita Popov
6e6dbae3ed [GVN] Add additional metadata adjustment tests (NFC) 2023-04-12 15:46:25 +02:00
Nikita Popov
e7f4ad13ae [Transforms] Convert some tests to opaque pointers (NFC) 2023-04-11 16:49:12 +02:00
Nikita Popov
d68800d15d [Local] Preserve !invariant.load of dominating instruction
Per LangRef:

> If a load instruction tagged with the !invariant.load metadata
> is executed, the memory location referenced by the load has to
> contain the same value at all points in the program where the
> memory location is dereferenceable; otherwise, the behavior is
> undefined.

As invariant.load violation is immediate undefined behavior, it
is sufficient for it to be present on the dominating load (for
the case where K does not move).
2023-04-03 16:05:02 +02:00
Nikita Popov
d527ace7d9 [GVN] Regenerate test checks (NFC)
And add an additional metadata preservation test.
2023-04-03 16:05:02 +02:00
luxufan
f44c7dec67 [Local] Use most generic range if K does not dominate J or K doesn't have a !noundef
Since D141386 has changed the return value of !range from IUB to poison,
metadata !range shouldn't be preserved even if K dominates J.

If this patch was accepted, I plan to adjust metadata !nonnull as well.
BTW, I found that metadata !noundef is not handled in combineMetadata,
is this intentional?

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D142687
2023-03-23 19:31:55 +08:00
Nikita Popov
e7618a6361 [GVN] Fix change reporting when removing assume (PR61574)
Report a change when removing a true/false assume.

Fixes https://github.com/llvm/llvm-project/issues/61574.
2023-03-22 15:23:31 +01:00
Nikita Popov
1a9d49524a [GVN] Regenerate test checks (NFC) 2023-03-22 11:40:07 +01:00
Nikita Popov
475f30dfc8 [ConstantFolding] Preserve inbounds when casting GEP indices
This canonicalization just makes the implicit sext/trunc explicit,
and does not affect the inbounds-ness of the GEP.
2023-03-09 13:08:19 +01:00
Sergey Kachkov
1aece0e5ed Revert "[GVN] Support address translation through select instructions"
This reverts commit b5bf6f6392a3408be1b7b7e036eb69358c5a2c29.
2023-02-27 12:57:59 +03:00
Sergey Kachkov
b5bf6f6392 [GVN] Support address translation through select instructions
Process cases when phi incoming in predecessor block has select
instruction, and this select address is unavailable, but there
are addresses translated from both sides of select instruction.

Differential Revision: https://reviews.llvm.org/D142705
2023-02-27 12:08:15 +03:00
Daniel Woodworth
a33f018b89 [Local][SimplifyCFG][GVN] Handle !nontemporal in combineMetadata
SimplifyCFG currently drops !nontemporal metadata when sinking
common instructions. With this change, SimplifyCFG and similar
transforms will preserve !nontemporal metadata as long as it is
set on both original instructions.

Differential Revision: https://reviews.llvm.org/D144298
2023-02-22 14:47:00 +01:00
Nick Desaulniers
c062e97acf [llvm][test] restrict 2 GVN tests to just test GVN (NFC)
Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D143681
2023-02-14 13:30:23 -08:00
Sergey Kachkov
203cc665cf [PHITransAddr] Simplify casts in PHITransAddr
Try to simplify cast in similar way as for GEP and ADD with
constant (e.g. sext/zext + trunc).

Differential Revision: https://reviews.llvm.org/D143167
2023-02-07 12:43:19 +03:00
Sergey Kachkov
2c8362b2a2 [NFC] Add pre-commit test for simplifyCastInst in PHITransAddr 2023-02-07 12:43:19 +03:00
luxufan
232698dc17 [Local][InstCombine][GVN] Handle !noundef metadata in combineMetadata
Handle !noundef metadata in comhineMetadata. The behavior of violating
!noundef metadata is undefined behavior. So if K dominates J, we can
preserve it uncontionally, otherwise, we preserve it if both K and J
have !noundef metadata been set.

This patch also makes !noundef metadata added in KnownIDs when doing
instruction combine for phi node or global value numbering for loads.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D142801
2023-02-02 14:25:13 +08:00
Guozhi Wei
43969af627 Revert "[GVN] Improve PRE on load instructions"
This reverts commit 5f1448fe1585b5677d5f0064e4eeac3b493d8a18.
2023-02-01 22:48:31 +00:00
Guozhi Wei
3a5777f630 Revert "[GVN] Don't count debug instructions when limit the number of checked instructions"
This reverts commit f494b366ff8a076a72a8e1b7a6f401686d6eb0e6.
2023-02-01 22:48:06 +00:00
Sergey Kachkov
fdeafafe49 [GVN] Add pre-commit tests for address translation through select (D142705)
Differential Revision: https://reviews.llvm.org/D142706
2023-02-01 16:25:46 +03:00
Guozhi Wei
f494b366ff [GVN] Don't count debug instructions when limit the number of checked instructions
Don't count debug instructions when limit the number of checked instructions.
Otherwise the debug information may impact optimization like the test case
shows.

Differential Revision: https://reviews.llvm.org/D142787
2023-01-31 21:04:03 +00:00
Guozhi Wei
5f1448fe15 [GVN] Improve PRE on load instructions
This patch implements the enhancement proposed by
https://github.com/llvm/llvm-project/issues/59312.

Suppose we have following code

   v0 = load %addr
   br %LoadBB

 LoadBB:
   v1 = load %addr
   ...

 PredBB:
   ...
   br %cond, label %LoadBB, label %SuccBB

 SuccBB:
   v2 = load %addr
   ...

Instruction v1 in LoadBB is partially redundant, edge (PredBB, LoadBB) is a
critical edge. SuccBB is another successor of PredBB, it contains another load
v2 which is identical to v1. Current GVN splits the critical edge
(PredBB, LoadBB) and inserts a new load in it. A better method is move the load
of v2 into PredBB, then v1 can be changed to a PHI instruction.

If there are two or more similar predecessors, like the test case in the bug
entry, current GVN simply gives up because otherwise it needs to split multiple
critical edges. But we can move all loads in successor blocks into predecessors.

Differential Revision: https://reviews.llvm.org/D141712
2023-01-25 19:45:01 +00:00
Sergey Kachkov
e1a702db2f [GVN] Refactor findDominatingLoad function
Improve findDominatingLoad implementation:
1. Result is saved into gvn::AvailableValue struct
2. Search is done in extended BB (while there is a single predecessor or
   limit is reached)

Differential Revision: https://reviews.llvm.org/D141680
2023-01-20 11:54:11 +03:00
Nikita Popov
9ed2f14c87 [AsmParser] Remove typed pointer auto-detection
IR is now always parsed in opaque pointer mode, unless
-opaque-pointers=0 is explicitly given. There is no automatic
detection of typed pointers anymore.

The -opaque-pointers=0 option is added to any remaining IR tests
that haven't been migrated yet.

Differential Revision: https://reviews.llvm.org/D141912
2023-01-18 09:58:32 +01:00
Sergey Kachkov
b06fd14359 [GVN][NFC] Add pre-commit tests for non-local load cases (D141680)
Add test cases when load is non-local for select dependency, but can be
found in extended BB (chain of blocks with single predecessor). Check
that type of found load is the same.
2023-01-18 11:50:44 +03:00
Sergey Kachkov
bfd2dd49ff [GVN] Refactor handling of pointer-select in GVN pass
This patch extends Def memory dependency with support of select
instructions to consistently handle pointer-select conversion.

Differential Revision: https://reviews.llvm.org/D141619
2023-01-17 11:32:06 +03:00
Sergey Kachkov
868abc471d Revert "[GVN] Refactor handling of pointer-select in GVN pass"
This reverts commit fc7cdaa373308ce3d72218b4d80101ae19850a6c.
2023-01-16 15:13:17 +03:00
Sergey Kachkov
fc7cdaa373 [GVN] Refactor handling of pointer-select in GVN pass
This patch introduces new type of memory dependency - Select to
consistently handle it like Def/Clobber dependency.

Differential Revision: https://reviews.llvm.org/D141619
2023-01-16 14:12:28 +03:00
Nikita Popov
54c1aa2966 [GVN] Convert tests to opaque pointers (NFC) 2023-01-11 14:19:34 +01:00
Johannes Doerfert
1041053469 [CallGraph][FIX] Ensure generic intrinsics are represented in the CG
Intrinsics have historically been excluded from the call graph with an
exception of 3 special ones added at some point. This meant that passes
depending on the call graph needed to handle intrinsics explicitly as
the underlying assumption, namely that intrinsics can't call or modify
things, doesn't hold. We are slowly moving away from special handling of
intrinsics, or at least towards explicitly checking what intrinsics we
want to handle differently.

This patch:
 - Includes most intrinsics in the call graph. Debug intrinsics are
   still excluded.
 - Removes the special handling of intrinsics in the GlobalsAA pass.
 - Removes the `IntrinsicInst::isLeaf` method.

Properly
Fixes: https://github.com/llvm/llvm-project/issues/52706

See also:
https://discourse.llvm.org/t/intrinsics-are-not-special-stop-pretending-i-mean-it/67545

Differential Revision: https://reviews.llvm.org/D14119
2023-01-10 11:38:58 -08:00
Guozhi Wei
9852941f01 Revert "[GVN] Improve PRE on load instructions"
This reverts commit 1f1d501843e5cf8741599035d6ef66a3eb5e1e9e.

This patch caused several sanitizer tests failed. Revert it to unblock
others.
2023-01-10 02:35:35 +00:00
Johannes Doerfert
c586d97310 [GVN][NFC] Precommit intrinsic bug test case, see D141190 2023-01-09 16:03:51 -08:00
Guozhi Wei
1f1d501843 [GVN] Improve PRE on load instructions
This patch implements the enhancement proposed by
https://github.com/llvm/llvm-project/issues/59312.

Suppose we have following code

   v0 = load %addr
   br %LoadBB

 LoadBB:
   v1 = load %addr
   ...

 PredBB:
   ...
   br %cond, label %LoadBB, label %SuccBB

 SuccBB:
   v2 = load %addr
   ...

Instruction v1 in LoadBB is partially redundant, edge (PredBB, LoadBB) is a
critical edge. SuccBB is another successor of PredBB, it contains another load
v2 which is identical to v1. Current GVN splits the critical edge
(PredBB, LoadBB) and inserts a new load in it. A better method is move the load
of v2 into PredBB, then v1 can be changed to a PHI instruction.

If there are two or more similar predecessors, like the test case in the bug
entry, current GVN simply gives up because otherwise it needs to split multiple
critical edges. But we can move all loads in successor blocks into predecessors.

Differential Revision: https://reviews.llvm.org/D139582
2023-01-09 23:08:41 +00:00
Nikita Popov
d18a2dc5c9 [GVN] Name instructions in test (NFC) 2023-01-06 17:28:18 +01:00
Nikita Popov
23abf93138 [GVN] Convert some tests to opaque pointers (NFC) 2022-12-23 10:00:59 +01:00
Guozhi Wei
4c13af22b4 [TEST] Pre-commit test for GVN PRE load
This is a test case for D139582.

In this test case, %v4 and %v5 can be moved to predecessors, %v3 can be changed to a PHI instruction.

Differential Revision: https://reviews.llvm.org/D140234
2022-12-20 18:43:31 +00:00
Joshua Cranmer
e6b02214c6 [IR] Add a target extension type to LLVM.
Target-extension types represent types that need to be preserved through
optimization, but otherwise are not introspectable by target-independent
optimizations. This patch doesn't add any uses of these types by an existing
backend, it only provides basic infrastructure such that these types would work
correctly.

Reviewed By: nikic, barannikov88

Differential Revision: https://reviews.llvm.org/D135202
2022-12-20 11:02:11 -05:00