aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
AgeCommit message (Collapse)AuthorFilesLines
2022-05-16[ValueTracking] Handle and/or on RHS of isImpliedCondition()Nikita Popov1-2/+29
isImpliedCondition() currently handles and/or on the LHS, but not on the RHS, resulting in asymmetric behavior. This patch adds two new implication rules: * LHS ==> (RHS1 || RHS2) if LHS ==> RHS1 or LHS ==> RHS2 * LHS ==> !(RHS1 && RHS2) if LHS ==> !RHS1 or LHS ==> !RHS2 Differential Revision: https://reviews.llvm.org/D125551
2022-05-13[ValueTracking] recognize sub X, (X % Y) as not overflowingSanjay Patel1-0/+16
I fixed some poison-safety violations on related patterns in InstCombine and noticed that we missed adding nsw/nuw on them, so this adds clauses to the underlying analysis for that. We need the undef input restriction to make this safe according to Alive2: https://alive2.llvm.org/ce/z/48g9K8 Differential Revision: https://reviews.llvm.org/D125500
2022-05-03[ValueTracking] A and (B & ~A) have no common bits setNikita Popov1-0/+14
This extends haveNoCommonBitsSet() to two additional cases, allowing the following folds: * `A + (B & ~A)` --> `A | (B & ~A)` (https://alive2.llvm.org/ce/z/crxxhN) * `A + ((A & B) ^ B)` --> `A | ((A & B) ^ B)` (https://alive2.llvm.org/ce/z/A_wsH_) These should further fold to just `A | B`, though this currently only works in the first case. The reason why the second fold is necessary is that we consider this to be the canonical form if B is a constant. (I did check whether we can change that, but it looks like a number of folds depend on the current canonicalization, so I ended up adding both patterns here.) Differential Revision: https://reviews.llvm.org/D124763
2022-04-13Revert "[ValueTracking] Make getStringLenth aware of strdup"serge-sans-paille1-24/+6
This reverts commit e810d558093cff40caaa1aff24d289c76c59916d. The commit was not taken into account the fact that strduped string could be modified. Checking if such modification happens would make the function very costly, without a test case in mind it's not worth the effort.
2022-04-12[ValueTracking] Make getStringLenth aware of strdupserge-sans-paille1-6/+24
During strlen compile-time evaluation, make it possible to track size of strduped strings. Differential Revision: https://reviews.llvm.org/D123497
2022-04-05[ValueTracking] Handle non-pow2 align assume bundle (PR53693)Nikita Popov1-1/+2
https://reviews.llvm.org/D119414 clarified that this is legal IR, so handle it gracefully. (We could aggressively use the fact that the pointer must be a null pointer in that case, but I'm not bothering with that.) Fixes https://github.com/llvm/llvm-project/issues/53693.
2022-03-21Add missing dependencies to mayHaveNonDefUseDependencyPhilip Reames1-1/+13
Two interesting ommissions: * When reordering in either direction, reordering two calls which both contain inf-loops is illegal. This one is possibly a change in behavior for certain callers (e.g. fixes a latent bug.) * When moving down, control dependence must be respected by checking the inverse of isSafeToSpeculativeExecute. Current callers all seem to handle this case - though admitted, I did not do an exhaustive audit. Most seem to be only interested in moving upwards within a block. This is mostly a case of future proofing an API so that it implements what the comments says, not just what current callers need. Noticed via inspection. I don't have a test case.
2022-03-21Rename mayBeMemoryDependent to mayHaveNonDefUseDependency [nfc]Philip Reames1-1/+1
2022-03-18[FPEnv][InstSimplify] Teach CannotBeNegativeZero() about constrained intrinsics.Kevin P. Neal1-3/+12
Currently some optimizations are disabled because llvm::CannotBeNegativeZero() does not know how to deal with the constrained intrinsics. This patch fixes that by extending the existing implementation. Differential Revision: https://reviews.llvm.org/D121483
2022-03-14[ValueTracking] Simplify llvm::isPointerOffset()Arthur Eubanks1-52/+11
We still need the code after stripAndAccumulateConstantOffsets() since it doesn't handle GEPs of scalable types and non-constant but identical indexes. Differential Revision: https://reviews.llvm.org/D120523
2022-03-09[Analysis] remove bogus smin/smax pattern detectionSanjay Patel1-14/+0
This is a revert of cfcc42bdc. The analysis is wrong as shown by the minimal tests for instcombine: https://alive2.llvm.org/ce/z/y9Dp8A There may be a way to salvage some of the other tests, but that can be done as follow-ups. This avoids a miscompile and fixes #54311.
2022-03-01Cleanup includes: LLVMAnalysisserge-sans-paille1-2/+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-23[ValueTracking] Support signed intrinsic clampNikita Popov1-0/+24
This is the same special logic we apply for SPF signed clamps when computing the number of sign bits, just for intrinsics. This just uses the same logic as the select case, but there's multiple directions this could be improved in: We could also use the num sign bits from the clamped value, we could do this during constant range calculation, and there's probably unsigned analogues for the constant range case at least.
2022-02-16[ValueTracking] Checking haveNoCommonBitsSet for (x & y) and ~(x | y)Chuanqi Xu1-7/+19
This one tries to fix: https://github.com/llvm/llvm-project/issues/53357. Simply, this one would check (x & y) and ~(x | y) in haveNoCommonBitsSet. Since they shouldn't have common bits (we could traverse the case by enumerating), and we could convert this one to (x & y) | ~(x | y) . Then the compiler could handle it in InstCombineAndOrXor. Further more, since ((x & y) + (~x & ~y)) would be converted to ((x & y) + ~(x | y)), this patch would fix it too. https://alive2.llvm.org/ce/z/qsKzRS Reviewed By: spatel, xbolva00, RKSimon, lebedev.ri Differential Revision: https://reviews.llvm.org/D118094
2022-02-13[OpaquePtr][ValueTracking] Check GEP source element type in isPointerOffset()Arthur Eubanks1-1/+2
Fixes a MemCpyOpt miscompile with opaque pointers. This function can be further cleaned up, but let's just fix the miscompile first. Reviewed By: #opaque-pointers, nikic Differential Revision: https://reviews.llvm.org/D119652
2022-02-08[ValueTracking] Only check for non-undef/poison if already known to be a ↵Roman Lebedev1-2/+3
self-multiply https://godbolt.org/z/js9fTTG9h ^ we don't care what `isGuaranteedNotToBeUndefOrPoison()` says unless we already knew that the operands were equal.
2022-02-08[ValueTracking] Add support for X*X self-multiplicationSimon Pilgrim1-1/+5
D108992 added KnownBits handling for 'Quadratic Reciprocity' self-multiplication patterns (bit[1] == 0), which can be used for non-undef values (poison is OK). This patch adds noundef selfmultiply handling to value tracking so demanded bits patterns can make use of it. Differential Revision: https://reviews.llvm.org/D117995
2022-02-08[ValueTracking] Replace dyn_cast with dyn_cast_or_null to account for ↵Simon Pilgrim1-2/+2
getTerminator returning null Noticed while running checks on D117995 - a hexagon regression test was managing to return a block without a terminator
2022-01-28[Loads] Require Align in isDereferenceableAndAlignedPointer() (NFC)Nikita Popov1-2/+2
Now that loads always have an alignment, we should not perform an ABI alignment fallback here.
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-17[ValueTracking] Remove ComputeMultiple() functionNikita Popov1-119/+0
This function is no longer used since 499f1ca79f232faae09b1793a994d1a22ba403cd.
2022-01-04[Analysis] fix swapped operands to computeConstantRangeSanjay Patel1-2/+2
This was noted in post-commit review for D116322 / 0edf99950e6 . I am not seeing how to expose the bug in a test though because we don't pass an assumption cache into this analysis from there.
2022-01-03[ValueTracking][SelectionDAG] Rename ↵Craig Topper1-4/+4
ComputeMinSignedBits->ComputeMaxSignificantBits. NFC This function returns an upper bound on the number of bits needed to represent the signed value. Use "Max" to match similar functions in KnownBits like countMaxActiveBits. Rename APInt::getMinSignedBits->getSignificantBits. Keeping the old name around to keep this patch size down. Will do a bulk rename as follow up. Rename KnownBits::countMaxSignedBits->countMaxSignificantBits. Reviewed By: lebedev.ri, RKSimon, spatel Differential Revision: https://reviews.llvm.org/D116522
2021-12-28[Analysis] allow caller to choose signed/unsigned when computing constant rangeSanjay Patel1-7/+17
We should not lose analysis precision if an 'add' has both no-wrap flags (nsw and nuw) compared to just one or the other. This patch is modeled on a similar construct that was added with D59386. I don't think it is possible to expose a problem with an unsigned compare because of the way this was coded (nuw is handled first). InstCombine has an assert that fires with the example from: https://github.com/llvm/llvm-project/issues/52884 ...because it was expecting InstSimplify to handle this kind of pattern with an smax. Fixes #52884 Differential Revision: https://reviews.llvm.org/D116322
2021-12-27[Analysis] remove unneeded casts; NFCSanjay Patel1-2/+4
The callee does the casting too; this matches a plain call later in the same function for 'shl'.
2021-12-20[Analysis] fix cast in ValueTracking to allow constant expressionSanjay Patel1-1/+1
The test would crash because a non-instruction negate op made it in here. Fixes #51506
2021-12-15[NFC] Remove more calls to getAlignment()Arthur Eubanks1-2/+2
These are deprecated and should be replaced with getAlign(). Some of these asserts don't do anything because Load/Store/AllocaInst never have a 0 align value.
2021-12-14Add FMF to hasPoisonGeneratingFlags/dropPoisonGeneratingFlagsPhilip Reames1-8/+0
These flags are documented as generating poison values for particular input values. As such, we should really be consistent about their handling with how we handle nsw/nuw/exact/inbounds. Differential Revision: https://reviews.llvm.org/D115460
2021-12-07[IR] Split vscale_range interfaceCullen Rhodes1-8/+10
Interface is split from: std::pair<unsigned, unsigned> getVScaleRangeArgs() into separate functions for min/max: unsigned getVScaleRangeMin(); Optional<unsigned> getVScaleRangeMax(); Reviewed By: sdesmalen, paulwalker-arm Differential Revision: https://reviews.llvm.org/D114075
2021-11-14[llvm] Use isa instead of dyn_cast (NFC)Kazu Hirata1-1/+1
2021-11-05[ValueTracking][InstCombine] Introduce and use ComputeMinSignedBitsDavid Green1-0/+8
This introduces a new ComputeMinSignedBits method for ValueTracking that returns the BitWidth - SignBits + 1 from ComputeSignBits, and represents the minimum bit size for the value as a signed integer. Similar to the existing APInt::getMinSignedBits method, this can make some of the reasoning around ComputeSignBits more natural. See https://reviews.llvm.org/D112298
2021-10-30[ValueTracking] Teach computeConstantRange that the maximum value of a half ↵David Green1-0/+19
is 65504 The maximal value of a half is 0x7bff, which is 65504 when converted to an integer. This patch teaches that to computeConstantRange to compute a constant range with the correct maximum value. https://alive2.llvm.org/ce/z/BV_Spb https://alive2.llvm.org/ce/z/Nwuqvb The maximum value for a float converted in the same way is 3.4e38, which requires 129bits of data. I have not added that here as integer types so larger are rare, compared to integers types larger than 17 bits require for half floats. The MVE tests change because instsimplify happens to be run as a part of the backend, where it doesn't tend to for other backends. Differential Revision: https://reviews.llvm.org/D112694
2021-10-27[Operator] Add hasPoisonGeneratingFlags [mostly NFC]Philip Reames1-13/+3
This method parallels the dropPoisonGeneratingFlags on Instruction, but is hoisted to operator to handle constant expressions as well. This is mostly code movement, but I did go ahead and add the inrange constexpr gep case. This had been discussed previously, but apparently never followed up o.
2021-10-24Treat branch on poison as immediate UB (under an off by default flag)Philip Reames1-1/+21
The LangRef clearly states that branching on a undef or poison value is immediate undefined behavior, but historically, we have not been consistent about implementing that interpretation in the optimizer. Historically, we used (in some cases) a more relaxed model which essentially looked for provable UB along both paths which was control dependent on the condition. However, we've never been 100% consistent here. For instance SCEV uses the strong model for increments which form AddRecs (and only addrecs). At the moment, the last big blocker for finally making this switch is enabling the fix landed in D106041. Loop unswitching (in it's classic form) is incorrect as it creates many "branch on poisons" when unswitching conditions originally unreachable within the loop. This change adds a flag to value tracking which allows to easily test the optimization potential of treating branch on poison as immediate UB. It's intended to help ease work on getting us finally through this transition and avoid multiple independent rediscovers of the same issues. Differential Revision: https://reviews.llvm.org/D112026
2021-10-21[CodeMetrics] Don't require speculatability for ephemeral valuesNikita Popov1-1/+3
As discussed in D112016, our current requirement of speculatability for ephemeral is overly strict: What we really care about is that the instruction will be DCEd once the assume is dropped. For that it is sufficient that the instruction is side-effect free and not a terminator. In particular, this allows non-dereferenceable loads to be ephemeral values. Differential Revision: https://reviews.llvm.org/D112179
2021-10-14[ValueTracking] Simplify getKnowledgeValidInContext() call (NFC)Nikita Popov1-2/+1
This accepts an ArrayRef, there's no need to create a SmallVector.
2021-10-13Make various assume bundle data structures use uint64_tArthur Eubanks1-1/+1
Following D110451, we need to make sure to support 64 bit values.
2021-10-13[instcombine] propagate single use freeze(gep inbounds X)Philip Reames1-4/+7
This is a follow on for D111675 which implements the gep case. I'd originally left it out because I was hoping to actually implement the inrange todo, but after a bit of staring at the code, decided to leave it as is since it doesn't effect this use case (i.e. instcombine requires the op to freeze to be an instruction). Differential Revision: https://reviews.llvm.org/D111691
2021-10-12Fix bug introduced with 6f34839 (poison flags on floating point ops)Philip Reames1-5/+8
The newly introduced API for checking whether poison comes solely from flags which can be dropped was out of sync. This was noticed by a reviewer post commit. For the moment, disable the floating point flags. In a follow up change, I plan to add support in dropPoisonGeneratingFlags, but that deserves to be a change of it's own.
2021-10-12[instcombine] propagate freeze through single use poison producing flag ↵Philip Reames1-17/+20
instruction If we have an instruction which produces poison only when flags are specified on the instruction, then we know that freezing the operands and dropping flags is equivalent to freezing the result. If we know those flags don't result in any undefined behavior being executed, then there's no point in preserving the flags as we gain no knowledge by having them. This patch extends the existing propagation logic which sinks freeze to single potential non-poison operands to allow dropping of flags when we know the freeze is the sole use of the instruction with poison flags. The main value is that we tend to sink freezes towards the phi in IV cycles where the incoming value to the phi is the freeze of an IV increment. This will in turn (in a future patch), let us fold the freeze through the phi into the loop preheader. Motivated by eliminating need for CanonicalizeFreezeInLoops for the clearly profitable cases from onephi.ll test case in the test directory. Differential Revision: https://reviews.llvm.org/D111675
2021-10-08Add iterator range variants of isGuaranteedToTransferExecutionToSuccessor ↵Philip Reames1-4/+24
[mostly-nfc] This factors out utilities for scanning a bounded block of instructions since we have this code repeated in a bunch of places. The change to InlineFunction isn't strictly NFC as the limit mechanism there didn't handle debug instructions correctly.
2021-10-06Returning poison from a function w/ noundef return attribute is UBPhilip Reames1-1/+4
This does for readability of returns within said function as what we do for the caller side when reasoning about what might be poison. Differential Revision: https://reviews.llvm.org/D111180
2021-10-04[APInt] Stop using soft-deprecated constructors and methods in llvm. NFC.Jay Foad1-19/+16
Stop using APInt constructors and methods that were soft-deprecated in D109483. This fixes all the uses I found in llvm, except for the APInt unit tests which should still test the deprecated methods. Differential Revision: https://reviews.llvm.org/D110807
2021-09-30[llvm] Migrate from arg_operands to args (NFC)Kazu Hirata1-1/+1
Note that arg_operands is considered a legacy name. See llvm/include/llvm/IR/InstrTypes.h for details.
2021-09-24[Analysis] Fix another issue when querying vscale attributes on functionsDavid Sherwood1-1/+1
There are several places in the code that are currently broken where we assume an Instruction is always a member of a BasicBlock that lives in a Function. This is a problem specifically when attempting to get the vscale_range attribute. This patch adds checks that an Instruction's parent also has a parent! I've added a test for a function-less @llvm.vscale intrinsic call here: unittests/Analysis/ValueTrackingTest.cpp
2021-09-24[Analysis] Fix issues when querying vscale attributes on functionsDavid Sherwood1-1/+2
There are several places in the code that are currently broken as they assume an Instruction always has a parent Function when attempting to get the vscale_range attribute. This patch adds checks that an Instruction has a parent. I've added a test for a parentless @llvm.vscale intrinsic call here: unittests/Analysis/ValueTrackingTest.cpp Differential Revision: https://reviews.llvm.org/D110158
2021-09-22[ValueTracking] fix isOnlyUsedInZeroEqualityComparison with no usersSanjay Patel1-2/+1
This is another problem exposed by: https://bugs.llvm.org/PR50836
2021-09-22[Analysis] reduce code for isOnlyUsedInZeroEqualityComparison; NFCSanjay Patel1-10/+6
There's a bug here noted by the FIXME and visible in variations of PR50836.
2021-09-21[ValueTracking,VectorCombine] Allow passing DT to computeConstantRange.Florian Hahn1-2/+3
isValidAssumeForContext can provide better results with access to the dominator tree in some cases. This patch adjusts computeConstantRange to allow passing through a dominator tree. The use VectorCombine is updated to pass through the DT to enable additional scalarization. Note that similar APIs like computeKnownBits already accept optional dominator tree arguments. Reviewed By: lebedev.ri Differential Revision: https://reviews.llvm.org/D110175
2021-09-20[Analysis] Add support for vscale in computeKnownBitsFromOperatorDavid Sherwood1-0/+26
In ValueTracking.cpp we use a function called computeKnownBitsFromOperator to determine the known bits of a value. For the vscale intrinsic if the function contains the vscale_range attribute we can use the maximum and minimum values of vscale to determine some known zero and one bits. This should help to improve code quality by allowing certain optimisations to take place. Tests added here: Transforms/InstCombine/icmp-vscale.ll Differential Revision: https://reviews.llvm.org/D109883