241 Commits

Author SHA1 Message Date
Nikita Popov
625113402f [IR] Remove support for and/or constant expressions
As part of https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179,
this removes support for and and or constant expressions. Places
creating such expressions have been migrated in advance, so this
is mostly API removal and test updates.

Differential Revision: https://reviews.llvm.org/D155924
2023-08-22 09:29:54 +02:00
Nikita Popov
063b37e7b4 Reapply [IR] Mark and/or constant expressions as undesirable
Reapply after D156401, which stops PatternMatch from recognizing
binop constant expressions, which should avoid the infinite loops
and assertion failures this patch previously exposed.

-----

In preparation for removing support for and/or expressions, mark
them as undesirable. As such, we will no longer implicitly create
such expressions, but they still exist.
2023-07-31 09:54:24 +02:00
Nikita Popov
90d825be70 Reapply [ConstantFold] Avoid creation of undesirable binop
This was reverted together with another commit due to a test
conflict. Reapply without functional changes.

-----

When commuting the operands, don't create a constant expression
for undesirable binops. Only invoke the constant folding function
in that case.
2023-07-27 09:48:54 +02:00
Matthew Voss
9eb73f9c9d Revert "[ConstantFold] Avoid creation of undesirable binop"
This reverts commit 673a4671f3e8b7158d990f6456428175a6eac38c.

Depends on reverted commit 0cab8d20417c0e2ccc1ffc5505e080126f5de8e6.

That commit was reverted due to an LTO crash. I've put a reduced
test case here: https://github.com/llvm/llvm-project/issues/64114
2023-07-26 12:56:31 -07:00
Matthew Voss
380dbfd8ca Revert "Reapply [IR] Mark and/or constant expressions as undesirable"
This reverts commit 0cab8d20417c0e2ccc1ffc5505e080126f5de8e6.

Reverted due to an LTO crash. I've put a reduced test case here:
https://github.com/llvm/llvm-project/issues/64114
2023-07-26 12:54:07 -07:00
Nikita Popov
673a4671f3 [ConstantFold] Avoid creation of undesirable binop
When commuting the operands, don't create a constant expression
for undesirable binops. Only invoke the constant folding function
in that case.
2023-07-25 16:54:57 +02:00
Nikita Popov
0cab8d2041 Reapply [IR] Mark and/or constant expressions as undesirable
This reapplies the change for and, but also marks or as undesirable
at the same time. Only handling one of them can cause infinite
combine loops due to the asymmetric handling.

-----

In preparation for removing support for and/or expressions, mark
them as undesirable. As such, we will no longer implicitly create
such expressions, but they still exist.
2023-07-25 15:31:45 +02:00
Nathan Chancellor
17f4f262fc
Revert "Reapply [IR] Mark and constant expressions as undesirable"
This reverts commit 086ee99564afbb11449c08ea2e094f7f49fadde5.

This patch causes an infinite loop when building arch/mips/mm/c-r4k.c in
the Linux kernel. See the comment in Phabricator for a reduced
reproducer: https://reviews.llvm.org/rG086ee99564afbb11449c08ea2e094f7f49fadde5
2023-07-21 15:57:03 -07:00
Nikita Popov
086ee99564 Reapply [IR] Mark and constant expressions as undesirable
Reapply after fixing an issue in canonicalizeLogicFirst() exposed
by this change (218f97578b26f7a89f7f8ed0748c31ef0181f80a).

-----

In preparation for removing support for and expressions, mark them
as undesirable. As such, we will no longer implicitly create such
expressions, but they still exist.
2023-07-21 10:10:50 +02:00
Nikita Popov
9dc391e89c Revert "[IR] Mark add constant expressions as undesirable"
This reverts commit f8a36d8c3e264c4fccf8058e699201a452ea7bb7.

I believe this is causing an assertion failure on the
sanitizer-x86_64-linux buildbot:

clang++: /b/sanitizer-x86_64-linux/build/llvm-project/llvm/include/llvm/Support/Casting.h:578: decltype(auto) llvm::cast(From *) [To = llvm::BinaryOperator, From = llvm::Value]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

  #10 0x000055bdd7e82408 canonicalizeLogicFirst(llvm::BinaryOperator&, llvm::IRBuilder<llvm::TargetFolder, llvm::IRBuilderCallbackInserter>&) /b/sanitizer-x86_64-linux/build/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2131:5
  #11 0x000055bdd7e80183 llvm::InstCombinerImpl::visitAnd(llvm::BinaryOperator&) /b/sanitizer-x86_64-linux/build/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:2661:20

Likely the code is encountering a constant expression in a case it
didn't before.
2023-07-20 18:09:17 +02:00
Nikita Popov
f8a36d8c3e [IR] Mark add constant expressions as undesirable
In preparation for removing support for add expressions, mark them
as undesirable. As such, we will no longer implicitly create such
expressions, but they still exist.
2023-07-20 15:24:19 +02:00
Nikita Popov
b13f280538 [IR] Remove typed pointer handling from getGEPReturnType() (NFC) 2023-07-18 12:28:53 +02:00
Nikita Popov
061bb65f74 [ConstantFold] Remove typed pointer specific folds (NFC) 2023-07-12 15:20:29 +02:00
ManuelJBrito
22f5dc7501 [IR] Update to use new shufflevector semantics
Update to use new shufflevector semantics for undefined values in the mask

Differential Revision: https://reviews.llvm.org/D149548
2023-06-13 17:12:04 +01:00
ManuelJBrito
d22edb9794 [IR][NFC] Change UndefMaskElem to PoisonMaskElem
Following the change in shufflevector semantics,
poison will be used to represent undefined elements in shufflevector masks.

Differential Revision: https://reviews.llvm.org/D149256
2023-04-27 18:01:54 +01:00
Nikita Popov
bbfb13a5ff [ConstExpr] Remove select constant expression
This removes the select constant expression, as part of
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
Uses of this expressions have already been removed in advance,
so this just removes related infrastructure and updates tests.

Differential Revision: https://reviews.llvm.org/D145382
2023-03-16 10:32:08 +01:00
Kazu Hirata
a28b252d85 Use APInt::getSignificantBits instead of APInt::getMinSignedBits (NFC)
Note that getMinSignedBits has been soft-deprecated in favor of
getSignificantBits.
2023-02-19 23:56:52 -08:00
Guillaume Chatelet
cb1093b771 [NFC] Remove dead code 2023-02-03 16:06:11 +00:00
Guillaume Chatelet
3c80d24a4b [NFC] Simplify logic in ConstantFold
Differential Revision: https://reviews.llvm.org/D143271
2023-02-03 15:40:55 +00:00
Nikita Popov
78f88082de [ConstantFold] Fix incorrect inbounds inference for [0 x T] GEPs
Previously all indices into [0 x T] arrays were considered in
range, which resulted in us incorrectly inferring inbounds for
all GEPs of that form. We should not consider them in range here,
and instead bail out of the rewriting logic (which would divide
by zero).

Do continue to consider 0 always in range, to avoid changing
behavior for zero-index GEPs.
2023-02-01 15:14:11 +01:00
Nikita Popov
5f01a626dd [ConstantFold] Fix inbounds inference on mismatching source element type
When inferring that a GEP of a global variable is inbounds because
there is no notional overindexing, we need to check that the
global value type and the GEP source element type match.

This was not necessary with typed pointers (because we would have
a bitcast in between), but is necessary with opaque pointers.

We should be able to recover some of the safe cases by performing
an offset based inbounds inference in DL-aware ConstantFolding.
2023-01-31 11:33:00 +01:00
Nikita Popov
f09d32d121 [ConstantFold] Don't drop zero index gep with inrange attribute
This may cause GlobalSplit to fail if opaque pointers are used.

inrange really needs a new representation, but for now restore the
pre-opaque pointers status.
2023-01-06 12:06:42 +01:00
serge-sans-paille
38818b60c5
Move from llvm::makeArrayRef to ArrayRef deduction guides - llvm/ part
Use deduction guides instead of helper functions.

The only non-automatic changes have been:

1. ArrayRef(some_uint8_pointer, 0) needs to be changed into ArrayRef(some_uint8_pointer, (size_t)0) to avoid an ambiguous call with ArrayRef((uint8_t*), (uint8_t*))
2. CVSymbol sym(makeArrayRef(symStorage)); needed to be rewritten as CVSymbol sym{ArrayRef(symStorage)}; otherwise the compiler is confused and thinks we have a (bad) function prototype. There was a few similar situation across the codebase.
3. ADL doesn't seem to work the same for deduction-guides and functions, so at some point the llvm namespace must be explicitly stated.
4. The "reference mode" of makeArrayRef(ArrayRef<T> &) that acts as no-op is not supported (a constructor cannot achieve that).

Per reviewers' comment, some useless makeArrayRef have been removed in the process.

This is a follow-up to https://reviews.llvm.org/D140896 that introduced
the deduction guides.

Differential Revision: https://reviews.llvm.org/D140955
2023-01-05 14:11:08 +01:00
Fangrui Song
89fae41ef1 [IR] llvm::Optional => std::optional
Many llvm/IR/* files have been migrated by other contributors.
This migrates most remaining files.
2022-12-05 04:13:11 +00:00
Kazu Hirata
e842c06c2d [IR] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-02 20:05:20 -08:00
Matt Arsenault
f85ce1b236 ConstantFold: Reduce code duplication for checking commuted compare 2022-10-26 10:59:58 -07:00
Nikita Popov
e047a4ab55 [ConstantFold] Avoid unary ConstantExpr::get()
Call ConstantFoldUnaryInstruction() instead, to only produce a
result if it folds.
2022-09-07 12:00:26 +02:00
Fangrui Song
de9d80c1c5 [llvm] LLVM_FALLTHROUGH => [[fallthrough]]. NFC
With C++17 there is no Clang pedantic warning or MSVC C5051.
2022-08-08 11:24:15 -07:00
Nikita Popov
935570b2ad [ConstExpr] Don't create div/rem expressions
This removes creation of udiv/sdiv/urem/srem constant expressions,
in preparation for their removal. I've added a
ConstantExpr::isDesirableBinOp() predicate to determine whether
an expression should be created for a certain operator.

With this patch, div/rem expressions can still be created through
explicit IR/bitcode, forbidding them entirely will be the next step.

Differential Revision: https://reviews.llvm.org/D128820
2022-07-05 15:54:53 +02:00
Nikita Popov
20b5f0c641 [IR] Export ConstantFold.h header (NFC)
This is in preparation for https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
As part of that change, we'll want to invoke some of these constant
folding APIs explicitly, as it won't happen as part of
ConstantExpr::getXYZ() anymore.

Ideally, we'd merge these with the DL-aware constant folding APIs
and only call those, but this is not easily possible for some
current usages (most important IRBuilder, which uses DL-independent
constant folding by default, and some major layering changes would
be needed to change that).

This is basically a reboot of D115035 with different motivation.

Differential Revision: https://reviews.llvm.org/D128213
2022-06-23 11:32:14 +02:00
Kazu Hirata
0916d96d12 Don't use Optional::hasValue (NFC) 2022-06-20 20:17:57 -07:00
Benjamin Kramer
08b20f20d2 [ConstantFold] Use getFltSemantics instead of manually checking the type
Simplifies the code and makes fpext/fptrunc constant folding not crash
when the result is bf16.
2022-05-05 15:52:19 +02:00
Craig Topper
ac8c720d48 [IR] Allow constant folding (insertelement <vscale x 2 x i32> zeroinitializer, i32 0, i32 i32 0.
Most of insertelement constant folding is blocked if the vector type
is scalable. I believe we can make an exception for inserting null
into an all zeros vector.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D123413
2022-04-15 17:44:32 -07:00
Nikita Popov
3c9f3f76f1 [ConstantFold] Fold zero-index GEPs with opaque pointers
With opaque pointers, we can eliminate zero-index GEPs even if
they have multiple indices, as this no longer impacts the result
type of the GEP.

This optimization is already done for instructions in InstSimplify,
but we were missing the corresponding constant expression handling.

The constexpr transform is a bit more powerful, because it can
produce a vector splat constant and also handles undef values --
it is an extension of an existing single-index transform.
2022-04-04 13:04:27 +02:00
Nikita Popov
7781f61efa [ConstantFold] Fix scalable shufflevector fold with all-undef mask
If the input is scalable, we should not be returning a fixed-width
vector as a result.
2022-03-11 14:30:02 +01:00
serge-sans-paille
e188aae406 Cleanup header dependencies in LLVMCore
Based on the output of include-what-you-use.

This is a big chunk of changes. It is very likely to break downstream code
unless they took a lot of care in avoiding hidden ehader dependencies, something
the LLVM codebase doesn't do that well :-/

I've tried to summarize the biggest change below:

- llvm/include/llvm-c/Core.h: no longer includes llvm-c/ErrorHandling.h
- llvm/IR/DIBuilder.h no longer includes llvm/IR/DebugInfo.h
- llvm/IR/IRBuilder.h no longer includes llvm/IR/IntrinsicInst.h
- llvm/IR/LLVMRemarkStreamer.h no longer includes llvm/Support/ToolOutputFile.h
- llvm/IR/LegacyPassManager.h no longer include llvm/Pass.h
- llvm/IR/Type.h no longer includes llvm/ADT/SmallPtrSet.h
- llvm/IR/PassManager.h no longer includes llvm/Pass.h nor llvm/Support/Debug.h

And the usual count of preprocessed lines:
$ clang++ -E  -Iinclude -I../llvm/include ../llvm/lib/IR/*.cpp -std=c++14 -fno-rtti -fno-exceptions | wc -l
before: 6400831
after:  6189948

200k lines less to process is no that bad ;-)

Discourse thread on the topic: https://llvm.discourse.group/t/include-what-you-use-include-cleanup

Differential Revision: https://reviews.llvm.org/D118652
2022-02-02 06:54:20 +01:00
Nikita Popov
0f0e699776 [ConstantFold] Disable gep of array bitcast fold with opaque pointers
Once again, this fold is meaningless with opaque pointers, as there
is no pointer element type to canonicalize. At some point, we may
want to do GEP type canonicalizations.
2022-01-27 11:52:52 +01:00
Nikita Popov
aa97bc116d [NFC] Remove uses of PointerType::getElementType()
Instead use either Type::getPointerElementType() or
Type::getNonOpaquePointerElementType().

This is part of D117885, in preparation for deprecating the API.
2022-01-25 09:44:52 +01:00
Nikita Popov
c41aa41957 [ConstFold] Add missing check for inbounds gep
If the gep is not inbounds, then the gep might compute a null
value even if the base pointer is non-null.
2022-01-06 09:59:40 +01:00
Nikita Popov
6c031780aa [ConstantFold] Remove another incorrect icmp of gep fold
This folded (null + X) == g to false, but of course this is
incorrect if X == g.

Possibly this got confused with the null == g case, which is
already handled elsewhere.
2022-01-04 16:08:09 +01:00
Nikita Popov
d74212987b [ConstantFold] Remove unnecessary bounded index restriction
The fold for merging a GEP of GEP into a single GEP currently bails
if doing so would result in notional overindexing. The justification
given in the comment above this check is dangerously incorrect: GEPs
with notional overindexing are perfectly fine, and if some code
treats them incorrectly, then that code is broken, not the GEP.
Such a GEP might legally appear in source IR, so only preventing
its creation cannot be sufficient. (The constant folder also ends
up canonicalizing the GEP to remove the notional overindexing, but
that's neither here nor there.)

This check dates back to
bd4fef4a89,
and as far as I can tell the original issue this was trying to
patch around has since been resolved.

Differential Revision: https://reviews.llvm.org/D116587
2022-01-04 15:23:09 +01:00
Nikita Popov
1379eb5776 [ConstFold] Slightly clean up icmp of two geps fold (NFC)
As we're only dealing with one type of constant expression here,
try to directly cast to GEPOperator.
2022-01-04 12:33:38 +01:00
Nikita Popov
75db002725 [ConstantFold] Remove another incorrect icmp of GEP fold
This fold is not correct, because indices might evaluate to zero
even if they are not a literal zero integer. Additionally, this
fold would be wrong (in the general case) for non-i8 types as well,
due to index overflow.

Drop this fold and instead let the target-dependent constant
folder compute the actual offset and fold the comparison based
on that.
2022-01-04 12:27:40 +01:00
Nikita Popov
127d955441 [ConstantFold] Drop unused function (NFC)
isMaybeZeroSizeType() is no longer used after
5afbfe33e7d6ce40af0ad6d99421b443c45b351b.
2022-01-03 10:14:52 +01:00
Nikita Popov
5afbfe33e7 [ConstantFold] Make icmp of gep fold offset based
We can fold an equality or unsigned icmp between base+offset1 and
base+offset2 with inbounds offsets by comparing the offsets directly.

This replaces a pair of specialized folds that tried to reason
based on the GEP structure instead. One of those folds was plain
wrong (because it does not account for negative offsets), while
the other is unnecessarily complicated and limited (e.g. it will
fail with bitcasts involved).

The disadvantage of this change is that it requires data layout,
so the fold is no longer performed by datalayout-independent
constant folding. I don't think this is a loss in practice, but
it does regress the ConstantExprFold.ll test, which checks folding
without running any passes.

Differential Revision: https://reviews.llvm.org/D116332
2022-01-03 09:41:37 +01:00
Serge Pavlov
ecfd9196d5 [ConstantFolding] Use ICmpInst::Predicate instead of plain integer
The function `ConstantFoldCompareInstruction` uses `unsigned short` to
represent compare predicate, although all usesrs of the respective
include file use definition of CmpInst also. This change replaces
predicate argument type in this function to `ICmpInst::Predicate`,
which allows to make code a bit clearer and simpler.

No functional changes.

Differential Revision: https://reviews.llvm.org/D116379
2021-12-30 14:31:44 +07:00
Nikita Popov
23de66d163 [ConstFold] Don't fold signed comparison of gep of global
An inbounds GEP may still cross the sign boundary, so signed icmps
cannot be folded (https://alive2.llvm.org/ce/z/XSgi4D). This was
previously fixed for other folds in this function, but this one
was missed.
2021-12-28 14:13:33 +01:00
Serge Pavlov
d86e2cc2e3 [NFC] Method for evaluation of FCmpInst for constant operands
New method `FCmpInst::compare` is added, which evaluates the given
compare predicate for constant operands. Interface is made similar to
`ICmpInst::compare`.

Differential Revision: https://reviews.llvm.org/D116168
2021-12-25 17:37:38 +07:00
Kazu Hirata
c23ebf1714 [llvm] Use range-based for loops (NFC) 2021-12-08 20:35:39 -08:00
David Sherwood
2a48b6993a [IR] In ConstantFoldShuffleVectorInstruction use zeroinitializer for splats of 0
When creating a splat of 0 for scalable vectors we tend to create them
with using a combination of shufflevector and insertelement, i.e.

shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> poison, i32 0, i32 0),
               <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer)

However, for the case of a zero splat we can actually just replace the
above with zeroinitializer instead. This makes the IR a lot simpler and
easier to read. I have changed ConstantFoldShuffleVectorInstruction to
use zeroinitializer when creating a splat of integer 0 or FP +0.0 values.

Differential Revision: https://reviews.llvm.org/D113394
2021-11-10 09:42:58 +00:00