aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
AgeCommit message (Collapse)AuthorFilesLines
2022-08-08[llvm] LLVM_FALLTHROUGH => [[fallthrough]]. NFCFangrui Song1-3/+3
With C++17 there is no Clang pedantic warning or MSVC C5051.
2022-08-07[ConstFolding] fix overzealous assert when converting FP halfSanjay Patel1-1/+1
Fixes #56981
2022-08-05[ConstProp] Don't fallthorugh for poison constants on vctp and active_lane_mask.David Green1-2/+2
Given a poison constant as input, the dyn_cast to a ConstantInt would fail so we would fall through to the generic code that attempts to fold each element of the input vectors. The inputs to these intrinsics are not vectors though, leading to a compile time crash. Instead bail out properly for poison values by returning nullptr. This doesn't try to define what poison means for these intrinsics. Fixes #56945
2022-07-30ConstantFolding: fold OOB accesses to poison instead of undefNuno Lopes1-4/+4
2022-07-08[ConstantFolding] Guard against unfolded FP binopNikita Popov1-0/+2
Check that the operation actually folded before trying to flush denormals. A minor variation of the pr33453 test exposed this with the FP binops marked as undesirable.
2022-07-05[ConstExpr] Don't create div/rem expressionsNikita Popov1-1/+4
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-04[ConstantFolding] Check return value of ConstantFoldInstOperandsImpl()Nikita Popov1-2/+6
This operation is fallible, but ConstantFoldConstantImpl() is not. If we fail to fold, we should simply return the original expression. I don't think this can cause any issues right now, but it becomes a problem if once make ConstantFoldInstOperandsImpl() not create a constant expression for everything it possibly could.
2022-07-01[InstructionSimplify] handle denormal input for fcmpChen Zheng1-49/+55
Handle denormal constant input for fcmp instructions based on the denormal handling mode. Reviewed By: spatel, dcandler Differential Revision: https://reviews.llvm.org/D128647
2022-07-01[ConstExpr] Don't create insertvalue expressionsNikita Popov1-1/+1
In preparation for the removal in D128719, this stops creating insertvalue constant expressions (well, unless they are directly used in LLVM IR). Differential Revision: https://reviews.llvm.org/D128792
2022-06-30[ConstantFold] Support loads in ConstantFoldInstOperands()Nikita Popov1-6/+6
This allows all constant folding to happen through a single function, without requiring special handling for loads at each call-site. This may not be NFC because some callers currently don't do that special handling.
2022-06-30[ConstantFold] Supports compares in ConstantFoldInstOperands()Nikita Popov1-18/+12
Support compares in ConstantFoldInstOperands(), instead of forcing the use of ConstantFoldCompareInstOperands(). Also handle insertvalue (extractvalue was already handled). This removes a footgun, where many uses of ConstantFoldInstOperands() need a separate check for compares beforehand. It's particularly insidious if called on a constant expression, because it doesn't fail in that case, but will just not do DL-dependent folding.
2022-06-28[IR] Remove support for extractvalue constant expressionNikita Popov1-2/+2
This removes the extractvalue constant expression, as part of https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179. extractvalue is already not supported in bitcode, so we do not need to worry about bitcode auto-upgrade. Uses of ConstantExpr::getExtractValue() should be replaced with IRBuilder::CreateExtractValue() (if the fact that the result is constant is not important) or ConstantFoldExtractValueInstruction() (if it is). Though for this particular case, it is also possible and usually preferable to use getAggregateElement() instead. The C API function LLVMConstExtractValue() is removed, as the underlying constant expression no longer exists. Instead, LLVMBuildExtractValue() should be used (which will constant fold or create an instruction). Depending on the use-case, LLVMGetAggregateElement() may also be used instead. Differential Revision: https://reviews.llvm.org/D125795
2022-06-21[InstCombine] handle subobjects of constant aggregatesMartin Sebor1-2/+33
Remove the known limitation of the library function call folders to only work with top-level arrays of characters (as per the TODO comment in the code) and allows them to also fold calls involving subobjects of constant aggregates such as member arrays.
2022-06-20[llvm] Don't use Optional::getValue (NFC)Kazu Hirata1-1/+1
2022-06-20[ConstantFolding] Respect denormal handling mode attributes when folding ↵David Candler1-1/+74
instructions Depending on the environment, a floating point instruction should treat denormal inputs as zero, and/or flush a denormal output to zero. Denormals are not currently accounted for when an instruction gets folded to a constant, which can lead to differences in output between a folded and a unfolded instruction when running on the target. The denormal handling mode can be set by the function level attribute denormal-fp-math, which this patch uses to determine whether any denormal inputs to or outputs from folding should be zero, and that the sign is set appropriately. Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D116952
2022-05-19[APInt] Remove all uses of zextOrSelf, sextOrSelf and truncOrSelfJay Foad1-5/+5
Most clients only used these methods because they wanted to be able to extend or truncate to the same bit width (which is a no-op). Now that the standard zext, sext and trunc allow this, there is no reason to use the OrSelf versions. The OrSelf versions additionally have the strange behaviour of allowing extending to a *smaller* width, or truncating to a *larger* width, which are also treated as no-ops. A small amount of client code relied on this (ConstantRange::castOp and MicrosoftCXXNameMangler::mangleNumber) and needed rewriting. Differential Revision: https://reviews.llvm.org/D125557
2022-05-03[LV][SLP] Mark fptosi_sat as vectorizableDavid Green1-1/+1
This adds fptosi_sat and fptoui_sat to the list of trivially vectorizable functions, mainly so that the loop vectorizer can vectorize the instruction. Marking them as trivially vectorizable also allows them to be SLP vectorized, and Scalarized. The signature of a fptosi_sat requires two type overrides (@llvm.fptosi.sat.v2i32.v2f32), unlike other intrinsics that often only take a single. This patch alters hasVectorInstrinsicOverloadedScalarOpd to isVectorIntrinsicWithOverloadTypeAtArg, so that it can mark the first operand of the intrinsic as a overloaded (but not scalar) operand. Differential Revision: https://reviews.llvm.org/D124358
2022-05-02[ConstantFold] Don't convert getelementptr to ptrtoint+inttoptrNikita Popov1-15/+13
ConstantFolding currently converts "getelementptr i8, Ptr, (sub 0, V)" to "inttoptr (sub (ptrtoint Ptr), V)". This transform is, taken by itself, correct, but does came with two issues: 1. It unnecessarily broadens provenance by introducing an inttoptr. We generally prefer not to introduce inttoptr during optimization. 2. For the case where V == ptrtoint Ptr, this folds to inttoptr 0, which further folds to null. In that case provenance becomes incorrect. This has been observed as a real-world miscompile with rustc. We should probably address that incorrect inttoptr 0 fold at some point, but in either case we should also drop this inttoptr-introducing fold. Instead, replace it with a fold rooted at ptrtoint(getelementptr), which seems to cover the original motivation for this fold (test2 in the changed file). Differential Revision: https://reviews.llvm.org/D124677
2022-04-25[NFC] Rename Instrinsic to IntrinsicDavid Green1-1/+1
2022-03-11[ConstFold] Don't fold calls with mismatching function typeNikita Popov1-0/+2
With opaque pointers, this is no longer ensured through pointer type identity.
2022-03-01Cleanup includes: LLVMAnalysisserge-sans-paille1-1/+0
Number of lines output by preprocessor: before: 1065940348 after: 1065307662 Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup Differential Revision: https://reviews.llvm.org/D120659
2022-02-27[ConstantFolding] Fix folding of constrained compare intrinsicsSerge Pavlov1-5/+4
The change fixes treatment of constrained compare intrinsics if compared values are of vector type. Differential revision: https://reviews.llvm.org/D110322
2022-02-22Fix warning introduced by 47eff645d8e873ba531014751c1c06a716a367e9David Sherwood1-1/+1
2022-02-22[InstCombine] Bail out of load-store forwarding for scalable vector typesDavid Sherwood1-3/+6
This patch fixes an invalid TypeSize->uint64_t implicit conversion in FoldReinterpretLoadFromConst. If the size of the constant is scalable we bail out of the optimisation for now. Tests added here: Transforms/InstCombine/load-store-forward.ll Differential Revision: https://reviews.llvm.org/D120240
2022-02-15[Analysis] propagate poison through add/sub saturate intrinsicsSanjay Patel1-0/+10
A more general enhancement needs to add tests and make sure that intrinsics that return structs are correct. There are also target-specific intrinsics, and I'm not sure what behavior is expected for those.
2022-02-15[Analysis] propagate poison through integer min/max intrinsicsSanjay Patel1-0/+5
A more general enhancement needs to add tests and make sure that intrinsics that return structs are correct. There are also target-specific intrinsics, and I'm not sure what behavior is expected for those.
2022-02-03[ConstantFolding] Fold constrained compare intrinsicsSerge Pavlov1-4/+26
The change implements constant folding of ‘llvm.experimental.constrained.fcmp’ and ‘llvm.experimental.constrained.fcmps’ intrinsics. Differential Revision: https://reviews.llvm.org/D110322
2022-01-25[NFC] Remove uses of PointerType::getElementType()Nikita Popov1-1/+1
Instead use either Type::getPointerElementType() or Type::getNonOpaquePointerElementType(). This is part of D117885, in preparation for deprecating the API.
2022-01-23[IR] document and update ctlz/cttz intrinsics to optionally return poison ↵Sanjay Patel1-2/+2
rather than undef The behavior in Analysis (knownbits) implements poison semantics already, and we expect the transforms (for example, in instcombine) derived from those semantics, so this patch changes the LangRef and remaining code to be consistent. This is one more step in removing "undef" from LLVM. Without this, I think https://github.com/llvm/llvm-project/issues/53330 has a legitimate complaint because that report wants to allow subsequent code to mask off bits, and that is allowed with undef values. The clang builtins are not actually documented anywhere AFAICT, but we might want to add that to remove more uncertainty. Differential Revision: https://reviews.llvm.org/D117912
2022-01-21[ConstantFold] Allow all float types in reinterpret load foldingNikita Popov1-2/+2
Rather than hardcoding just half, float and double, allow all floating point types.
2022-01-21[ConstantFold] Support pointers in reinterpret load foldingNikita Popov1-1/+1
Peculiarly, the necessary code to handle pointers (including the check for non-integral address spaces) is already in place, because we were already allowing vectors of pointers here, just not plain pointers.
2022-01-21[ConstantFold] Simplify type check in reinterpret load folding (NFC)Nikita Popov1-13/+6
Keep a list of allowed types, but then always construct the map type the same way. We need an integer with the same width as the original type.
2022-01-17[ConstantFold] Don't fold load from non-byte-sized vectorNikita Popov1-0/+6
Following up on https://github.com/llvm/llvm-project/commit/1470f94d71c544327f76b85c55cb6f7cb43a6cbb#r63981173: The result here (probably) depends on endianness. Don't bother trying to handle this exotic case, just bail out.
2022-01-14[ConstantFold] Check for uniform value before reinterpret loadNikita Popov1-2/+11
The reinterpret load code will convert undef values into zero. Check the uniform value case before it to produce a better result for all-undef initializers. However, the uniform value handling will return the uniform value even if the access is out of bounds, while the reinterpret load code will return undef. Add an explicit check to retain the previous result in this case.
2022-01-13[ConstantFold] Check uniform value in ConstantFoldLoadFromConst()Nikita Popov1-2/+5
This case is automatically handled if ConstantFoldLoadFromConstPtr() is used. Make sure that ConstantFoldLoadFromConst() also handles it.
2022-01-10[ConstantFolding] Clean up Intrinsics::abs undef handlingSimon Pilgrim1-2/+4
Match cttz/ctlz handling by assuming C1 == 0 if C1 != 1 - I've added an assertion as well. Fixes static analyzer nullptr dereference warnings.
2022-01-07[NFCI][IR] MinMaxIntrinsic: add some more helper methods, and use themRoman Lebedev1-21/+6
2022-01-05[ConstantFold] Use ConstantFoldLoadFromUniformValue() in more placesNikita Popov1-15/+4
In particular, this also preserves undef when loading from padding, rather than converting it to zero through a different codepath. This is the remaining part of D115924.
2022-01-05[ConstantFolding] Unify handling of load from uniform valueNikita Popov1-7/+18
There are a number of places that specially handle loads from a uniform value where all the bits are the same (zero, one, undef, poison), because we a) don't care about the load offset in that case b) it bypasses casts that might not be legal generally but do work with uniform values. We had multiple implementations of this, with a different set of supported values each time. This replaces two usages with a more complete helper. Other usages will be replaced separately, because they have larger impact. This is part of D115924.
2022-01-04[ConstantFolding] Remove unused ConstantFoldLoadThroughGEPConstantExpr()Nikita Popov1-17/+0
This API is no longer used since bbeaf2aac678633749e7385466da10a1c0120b3b.
2022-01-03[ConstantFold] Make icmp of gep fold offset basedNikita Popov1-2/+23
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
2021-12-22[ConstantFolding] Do not remove side effect from constrained functionsSerge Pavlov1-8/+1
According to the discussion in https://reviews.llvm.org/D110322 the code that removes side effect from replaced function call is deleted. Differential Revision: https://reviews.llvm.org/D115870
2021-12-21[ConstantFold][GlobalOpt] Don't create x86_mmx null valueNikita Popov1-1/+2
This fixes the assertion failure reported at https://reviews.llvm.org/D114889#3198921 with a straightforward check, until the cleaner fix in D115924 can be reapplied.
2021-12-20[llvm] Construct SmallVector with iterator ranges (NFC)Kazu Hirata1-1/+1
2021-12-18Revert "[ConstantFolding] Unify handling of load from uniform value"Nikita Popov1-24/+25
This reverts commit 9fd4f80e33a4ae4567483819646650f5735286e2. This breaks SingleSource/Regression/C/gcc-c-torture/execute/pr19687.c in test-suite. Either the test is incorrect, or clang is generating incorrect union initialization code. I've submitted https://reviews.llvm.org/D115994 to fix the test, assuming my interpretation is correct. Reverting this in the meantime as it may take some time to resolve.
2021-12-17[ConstantFolding] Unify handling of load from uniform valueNikita Popov1-25/+24
There are a number of places that specially handle loads from a uniform value where all the bits are the same (zero, one, undef, poison), because we a) don't care about the load offset in that case and b) it bypasses casts that might not be legal generally but do work with uniform values. We had multiple implementations of this, with a different set of supported values each time, as well as incomplete type checks in some cases. In particular, this fixes the assertion reported in https://reviews.llvm.org/D114889#3198921, as well as a similar assertion that could be triggered via constant folding. Differential Revision: https://reviews.llvm.org/D115924
2021-12-10[ConstantFold] Handle same type in ConstantFoldLoadThroughBitcastNikita Popov1-0/+3
Usually the case where the types are the same ends up being handled fine because it's legal to do a trivial bitcast to the same type. However, this is not true for aggregate types. Short-circuit the whole code if the types match exactly to account for this.
2021-12-03[ARM] Use v2i1 for MVE and CDE intrinsicsDavid Green1-4/+0
This adjusts all the MVE and CDE intrinsics now that v2i1 is a legal type, to use a <2 x i1> as opposed to emulating the predicate with a <4 x i1>. The v4i1 workarounds have been removed leaving the natural v2i1 types, notably in vctp64 which now generates a v2i1 type. AutoUpgrade code has been added to upgrade old IR, which needs to convert the old v4i1 to a v2i1 be converting it back and forth to an integer with arm.mve.v2i and arm.mve.i2v intrinsics. These should be optimized away in the final assembly. Differential Revision: https://reviews.llvm.org/D114455
2021-10-28[InstCombine][ConstantFolding] Make ConstantFoldLoadThroughBitcast ↵Peter Waller1-3/+3
TypeSize-aware The newly added test previously caused the compiler to fail an assertion. It looks like a strightforward TypeSize upgrade. Reviewed By: paulwalker-arm Differential Revision: https://reviews.llvm.org/D112142
2021-10-23[ConstantFolding] Accept offset in ConstantFoldLoadFromConstPtr (NFCI)Nikita Popov1-1/+7
As this API is now internally offset-based, we can accept a starting offset and remove the need to create a temporary bitcast+gep sequence to perform an offset load. The API now mirrors the ConstantFoldLoadFromConst() API.