summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [InstructionSimplify] Apply sext/trunc after pointer strippingMichael Liao2019-07-161-0/+4
| | | | | | | | | | | | | | | | | Summary: - As the pointer stripping could trace through `addrspacecast` now, need to sext/trunc the offset to ensure it has the same width as the pointer after stripping. Reviewers: jdoerfert Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64768 llvm-svn: 366162
* InstructionSimplify: Simplify InstructionSimplify. NFC.Tim Northover2019-07-111-42/+24
| | | | | | | | | | | The interface predates CallBase, so both it and implementation were significantly more complicated than they needed to be. There was even some redundancy that could be eliminated. Should also help with OpaquePointers by not trying to derive a function's type from it's PointerType. llvm-svn: 365767
* Replace three "strip & accumulate" implementations with a single oneJohannes Doerfert2019-07-111-26/+1
| | | | | | | | | | | This patch replaces the three almost identical "strip & accumulate" implementations for constant pointer offsets with a single one, combining the respective functionalities. The old interfaces are kept for now. Differential Revision: https://reviews.llvm.org/D64468 llvm-svn: 365723
* [InstSimplify] simplify power-of-2 (single bit set) sequencesSanjay Patel2019-06-201-0/+10
| | | | | | | | | | | | | | | | | | | | As discussed in PR42314: https://bugs.llvm.org/show_bug.cgi?id=42314 Improving the canonicalization for these patterns: rL363956 ...means we should adjust/enhance the related simplification. https://rise4fun.com/Alive/w1cp Name: isPow2 or zero %x = and i32 %xx, 2048 %a = add i32 %x, -1 %r = and i32 %a, %x => %r = i32 0 llvm-svn: 363997
* [InstSimplify] Fix addo/subo undef folds (PR42209)Roman Lebedev2019-06-161-8/+11
| | | | | | | | | | | | | | | | Fix folds of addo and subo with an undef operand to be: `@llvm.{u,s}{add,sub}.with.overflow` all fold to `{ undef, false }`, as per LLVM undef rules. Same for commuted variants. Based on the original version of the patch by @nikic. Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=42209 | PR42209 ]] Differential Revision: https://reviews.llvm.org/D63065 llvm-svn: 363522
* [InstSimplify] reduce code duplication for fcmp folds; NFCSanjay Patel2019-06-091-10/+7
| | | | llvm-svn: 362904
* [InstSimplify] enhance fcmp fold with never-nan operandSanjay Patel2019-06-091-2/+2
| | | | | | | | | | | | | | | | This is another step towards correcting our usage of fast-math-flags when applied on an fcmp. In this case, we are checking for 'nnan' on the fcmp itself rather than the operand of the fcmp. But I'm leaving that clause in until we're more confident that we can stop relying on fcmp's FMF. By using the more general "isKnownNeverNaN()", we gain a simplification shown on the tests with 'uitofp' regardless of the FMF on the fcmp (uitofp never produces a NaN). On the tests with 'fabs', we are now relying on the FMF for the call fabs instruction in addition to the FMF on the fcmp. This is a continuation of D62979 / rL362879. llvm-svn: 362903
* [InstSimplify] enhance fcmp fold with never-nan operandSanjay Patel2019-06-081-1/+3
| | | | | | | | | | | | | | | | | | This is 1 step towards correcting our usage of fast-math-flags when applied on an fcmp. In this case, we are checking for 'nnan' on the fcmp itself rather than the operand of the fcmp. But I'm leaving that clause in until we're more confident that we can stop relying on fcmp's FMF. By using the more general "isKnownNeverNaN()", we gain a simplification shown on the tests with 'uitofp' regardless of the FMF on the fcmp (uitofp never produces a NaN). On the tests with 'fabs', we are now relying on the FMF for the call fabs instruction in addition to the FMF on the fcmp. I'll update the 'ult' case below here as a follow-up assuming no problems here. Differential Revision: https://reviews.llvm.org/D62979 llvm-svn: 362879
* [InstructionSimplify] Add missing implementation of llvm::SimplifyUnOp. NFCCraig Topper2019-05-311-0/+4
| | | | | | | There are no callers currently, but the function is declared so we should at least implement it. llvm-svn: 362205
* [InstSimplify] fold insertelement-of-extractelementSanjay Patel2019-05-241-0/+6
| | | | | | | | This was partly handled in InstCombine (only the constant index case), so delete that and zap it more generally in InstSimplify. llvm-svn: 361576
* [InstSimplify] insertelement V, undef, ? --> VSanjay Patel2019-05-231-0/+5
| | | | | | | | This was part of InstCombine, but it's better placed in InstSimplify. InstCombine also had an unreachable but weaker fold for insertelement with undef index, so that is deleted. llvm-svn: 361559
* [InstSimplify] update stale comment; NFCSanjay Patel2019-05-201-1/+1
| | | | | | Missed this diff with rL361118. llvm-svn: 361180
* [InstSimplify] Teach fsub -0.0, (fneg X) ==> X about unary fnegCameron McInally2019-05-201-1/+2
| | | | | | Differential Revision: https://reviews.llvm.org/D62077 llvm-svn: 361151
* [InstSimplify] fold fcmp (maxnum, X, C1), C2Sanjay Patel2019-05-191-16/+26
| | | | | | | | | | | | | This is the sibling transform for rL360899 (D61691): maxnum(X, GreaterC) == C --> false maxnum(X, GreaterC) <= C --> false maxnum(X, GreaterC) < C --> false maxnum(X, GreaterC) >= C --> true maxnum(X, GreaterC) > C --> true maxnum(X, GreaterC) != C --> true llvm-svn: 361118
* [InstSimplify] Add unary fneg to `fsub 0.0, (fneg X) ==> X` transformCameron McInally2019-05-171-1/+3
| | | | | | Differential Revision: https://reviews.llvm.org/D62013 llvm-svn: 361047
* [InstSimplify] fold fcmp (minnum, X, C1), C2Sanjay Patel2019-05-161-0/+30
| | | | | | | | | | | | | | | | | | | | | minnum(X, LesserC) == C --> false minnum(X, LesserC) >= C --> false minnum(X, LesserC) > C --> false minnum(X, LesserC) != C --> true minnum(X, LesserC) <= C --> true minnum(X, LesserC) < C --> true maxnum siblings will follow if there are no problems here. We should be able to perform some other combines when the constants are equal or greater-than too, but that would go in instcombine. We might also generalize this by creating an FP ConstantRange (similar to what we do for integers). Differential Revision: https://reviews.llvm.org/D61691 llvm-svn: 360899
* Teach InstSimplify -X + X --> 0.0 about unary FNegCameron McInally2019-05-151-4/+10
| | | | | | Differential Revision: https://reviews.llvm.org/D61916 llvm-svn: 360777
* Add FNeg support to InstructionSimplifyCameron McInally2019-05-061-0/+65
| | | | | | Differential Revision: https://reviews.llvm.org/D61573 llvm-svn: 360053
* Consolidate existing utilities for interpreting vector predicate maskes [NFC]Philip Reames2019-04-251-16/+0
| | | | llvm-svn: 359163
* Add "const" in GetUnderlyingObjects. NFCBjorn Pettersson2019-04-241-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Both the input Value pointer and the returned Value pointers in GetUnderlyingObjects are now declared as const. It turned out that all current (in-tree) uses of GetUnderlyingObjects were trivial to update, being satisfied with have those Value pointers declared as const. Actually, in the past several of the users had to use const_cast, just because of ValueTracking not providing a version of GetUnderlyingObjects with "const" Value pointers. With this patch we get rid of those const casts. Reviewers: hfinkel, materi, jkorous Reviewed By: jkorous Subscribers: dexonsmith, jkorous, jholewinski, sdardis, eraman, hiraditya, jrtc27, atanasyan, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D61038 llvm-svn: 359072
* [InstSimplify] Move masked.gather w/no active lanes handling to InstSimplify ↵Philip Reames2019-04-221-1/+2
| | | | | | | | from InstCombine In the process, use the existing masked.load combine which is slightly stronger, and handles a mix of zero and undef elements in the mask. llvm-svn: 358913
* InstSimplify: Fold round intrinsics from sitofp/uitofpMatt Arsenault2019-04-031-0/+16
| | | | | | https://godbolt.org/z/gEMRZb llvm-svn: 357549
* [InstSimplify] SimplifyICmpInst - icmp eq/ne %X, undef -> undefSimon Pilgrim2019-03-191-0/+7
| | | | | | | | | | | | | | | As discussed on PR41125 and D59363, we have a mismatch between icmp eq/ne cases with an undef operand: When the other operand is constant we fold to undef (handled in ConstantFoldCompareInstruction) When the other operand is non-constant we fold to a bool constant based on isTrueWhenEqual (handled in SimplifyICmpInst). Neither is really wrong, but this patch changes the logic in SimplifyICmpInst to consistently fold to undef. The NewGVN test change is annoying (as with most heavily reduced tests) but AFAICT I have kept the purpose of the test based on rL291968. Differential Revision: https://reviews.llvm.org/D59541 llvm-svn: 356456
* [ValueTracking][InstSimplify] Move abs handling into computeConstantRange(); NFCNikita Popov2019-03-181-41/+0
| | | | | | | | | | | This is preparation for D59506. The InstructionSimplify abs handling is moved into computeConstantRange(), which is the general place for such calculations. This is NFC and doesn't affect the existing tests in test/Transforms/InstSimplify/icmp-abs-nabs.ll. Differential Revision: https://reviews.llvm.org/D59511 llvm-svn: 356409
* [InstCombine] canonicalize funnel shift constant shift amount to be modulo ↵Sanjay Patel2019-03-141-1/+0
| | | | | | | | | | | | | | | bitwidth The shift argument is defined to be modulo the bitwidth, so if that argument is a constant, we can always reduce the constant to its minimal form to allow better CSE and other follow-on transforms. We need to be careful to ignore constant expressions here, or we will likely infinite loop. I'm adding a general vector constant query for that case. Differential Revision: https://reviews.llvm.org/D59374 llvm-svn: 356192
* [ValueTracking] Move constant range computation into ValueTracking; NFCNikita Popov2019-03-091-238/+1
| | | | | | | | | | | | | | | | InstructionSimplify currently has some code to determine the constant range of integer instructions for some simple cases. It is used to simplify icmps. This change moves the relevant code into ValueTracking as llvm::computeConstantRange(), so it can also be reused for other purposes. In particular this is with the optimization of overflow checks in mind (ref D59071), where constant ranges cover some cases that known bits don't. llvm-svn: 355781
* [InstSimplify] remove zero-shift-guard fold for general funnel shiftSanjay Patel2019-02-261-12/+29
| | | | | | | | | | | | | | | | | | | | | | As discussed on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2019-February/130491.html We can't remove the compare+select in the general case because we are treating funnel shift like a standard instruction (as opposed to a special instruction like select/phi). That means that if one of the operands of the funnel shift is poison, the result is poison regardless of whether we know that the operand is actually unused based on the instruction's particular semantics. The motivating case for this transform is the more specific rotate op (rather than funnel shift), and we are preserving the fold for that case because there is no chance of introducing extra poison when there is no anonymous extra operand to the funnel shift. llvm-svn: 354905
* [InstSimplify] use any-zero matcher for fcmp foldsSanjay Patel2019-02-201-22/+25
| | | | | | | | | | | | | The m_APFloat matcher does not work with anything but strict splat vector constants, so we could miss these folds and then trigger an assertion in instcombine: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13201 The previous attempt at this in rL354406 had a logic bug that actually triggered a regression test failure, but I failed to notice it the first time. llvm-svn: 354467
* Revert "[InstSimplify] use any-zero matcher for fcmp folds"Sanjay Patel2019-02-201-25/+22
| | | | | | | This reverts commit 058bb8351351d56d2a4e8a772570231f9e5305e5. Forgot to update another test affected by this change. llvm-svn: 354408
* [InstSimplify] use any-zero matcher for fcmp foldsSanjay Patel2019-02-201-22/+25
| | | | | | | | | The m_APFloat matcher does not work with anything but strict splat vector constants, so we could miss these folds and then trigger an assertion in instcombine: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13201 llvm-svn: 354406
* [CallSite removal] Port InstSimplify over to use `CallBase` both in itsChandler Carruth2019-02-111-19/+17
| | | | | | | | interface and implementation. Port code with: `cast<CallBase>(CS.getInstruction())`. llvm-svn: 353662
* [CallSite removal] Migrate ConstantFolding APIs and implementation toChandler Carruth2019-02-111-2/+3
| | | | | | | | | `CallBase`. Users have been updated. You can see how to update any out-of-tree usages: pass `cast<CallBase>(CS.getInstruction())`. llvm-svn: 353661
* [InstSimplify] Missed optimization in math expression: log10(pow(10.0,x)) == ↵Dmitry Venikov2019-02-031-1/+9
| | | | | | | | | | | | | | | | x, log2(pow(2.0,x)) == x Summary: This patch enables folding following instructions under -ffast-math flag: log10(pow(10.0,x)) -> x, log2(pow(2.0,x)) -> x Reviewers: hfinkel, spatel, efriedma, craig.topper, zvi, majnemer, lebedev.ri Reviewed By: spatel, lebedev.ri Subscribers: lebedev.ri, llvm-commits Differential Revision: https://reviews.llvm.org/D41940 llvm-svn: 352981
* Update the file headers across all of the LLVM projects in the monorepoChandler Carruth2019-01-191-4/+3
| | | | | | | | | | | | | | | | | to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
* [InstSimplify] Simplify saturating add/sub + icmpNikita Popov2018-12-171-0/+66
| | | | | | | | | | | | | If a saturating add/sub has one constant operand, then we can determine the possible range of outputs it can produce, and simplify an icmp comparison based on that. The implementation is based on a similar existing mechanism for simplifying binary operator + icmps. Differential Revision: https://reviews.llvm.org/D55735 llvm-svn: 349369
* [ValueTracking] add helper function for testing implied condition; NFCISanjay Patel2018-12-021-38/+3
| | | | | | | | We were duplicating code around the existing isImpliedCondition() that checks for a predecessor block/dominating condition, so make that a wrapper call. llvm-svn: 348088
* [InstSimplify] fold select with implied conditionSanjay Patel2018-11-291-0/+39
| | | | | | | | | | | | | | | | | | | | | | | This is an almost direct move of the functionality from InstCombine to InstSimplify. There's no reason not to do this in InstSimplify because we never create a new value with this transform. (There's a question of whether any dominance-based transform belongs in either of these passes, but that's a separate issue.) I've changed 1 of the conditions for the fold (1 of the blocks for the branch must be the block we started with) into an assert because I'm not sure how that could ever be false. We need 1 extra check to make sure that the instruction itself is in a basic block because passes other than InstCombine may be using InstSimplify as an analysis on values that are not wired up yet. The 3-way compare changes show that InstCombine has some kind of phase-ordering hole. Otherwise, we would have already gotten the intended final result that we now show here. llvm-svn: 347896
* [InstSimplify] fold funnel shifts with undef operandsSanjay Patel2018-11-201-1/+10
| | | | | | | | Splitting these off from the D54666. Patch by: nikic (Nikita Popov) llvm-svn: 347332
* [InstructionSimplify] Add support for saturating add/subSanjay Patel2018-11-201-0/+34
| | | | | | | | | | | | | | | | | | | | | | Add support for saturating add/sub in InstructionSimplify. In particular, the following simplifications are supported: sat(X + 0) -> X sat(X + undef) -> -1 sat(X uadd MAX) -> MAX (and commutative variants) sat(X - 0) -> X sat(X - X) -> 0 sat(X - undef) -> 0 sat(undef - X) -> 0 sat(0 usub X) -> 0 sat(X usub MAX) -> 0 Patch by: @nikic (Nikita Popov) Differential Revision: https://reviews.llvm.org/D54532 llvm-svn: 347330
* [InstSimplify] delete shift-of-zero guard ops around funnel shiftsSanjay Patel2018-11-151-0/+22
| | | | | | | | | | | | | | | | | | | | | | | | This is a problem seen in common rotate idioms as noted in: https://bugs.llvm.org/show_bug.cgi?id=34924 Note that we are not canonicalizing standard IR (shifts and logic) to the intrinsics yet. (Although I've written this before...) I think this is the last step before we enable that transform. Ie, we could regress code by doing that transform without this simplification in place. In PR34924, I questioned whether this is a valid transform for target-independent IR, but I convinced myself this is ok. If we're speculating a funnel shift by turning cmp+br into select, then SimplifyCFG has already determined that the transform is justified. It's possible that SimplifyCFG is not taking into account profile or other metadata, but if that's true, then it's a bug independent of funnel shifts. Also, we do have CGP code to restore a guard like this around an intrinsic if it can't be lowered cheaply. But that isn't necessary for funnel shift because the default expansion in SelectionDAGBuilder includes this same cmp+select. Differential Revision: https://reviews.llvm.org/D54552 llvm-svn: 346960
* [InstSimplify] fold select (fcmp X, Y), X, YSanjay Patel2018-11-051-0/+31
| | | | | | | | | This is NFCI for InstCombine because it calls InstSimplify, so I left the tests for this transform there. As noted in the code comment, we can allow this fold more often by using FMF and/or value tracking. llvm-svn: 346169
* [InstSimplify] fold icmp based on range of abs/nabs (2nd try)Sanjay Patel2018-11-011-0/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is retrying the fold from rL345717 (reverted at rL347780) ...with a fix for the miscompile demonstrated by PR39510: https://bugs.llvm.org/show_bug.cgi?id=39510 Original commit message: This is a fix for PR39475: https://bugs.llvm.org/show_bug.cgi?id=39475 We managed to get some of these patterns using computeKnownBits in https://reviews.llvm.org/D47041, but that can't be used for nabs(). Instead, put in some range-based logic, so we can fold both abs/nabs with icmp with a constant value. Alive proofs: https://rise4fun.com/Alive/21r Name: abs_nsw_is_positive %cmp = icmp slt i32 %x, 0 %negx = sub nsw i32 0, %x %abs = select i1 %cmp, i32 %negx, i32 %x %r = icmp sgt i32 %abs, -1 => %r = i1 true Name: abs_nsw_is_not_negative %cmp = icmp slt i32 %x, 0 %negx = sub nsw i32 0, %x %abs = select i1 %cmp, i32 %negx, i32 %x %r = icmp slt i32 %abs, 0 => %r = i1 false Name: nabs_is_negative_or_0 %cmp = icmp slt i32 %x, 0 %negx = sub i32 0, %x %nabs = select i1 %cmp, i32 %x, i32 %negx %r = icmp slt i32 %nabs, 1 => %r = i1 true Name: nabs_is_not_over_0 %cmp = icmp slt i32 %x, 0 %negx = sub i32 0, %x %nabs = select i1 %cmp, i32 %x, i32 %negx %r = icmp sgt i32 %nabs, 0 => %r = i1 false Differential Revision: https://reviews.llvm.org/D53844 llvm-svn: 345832
* revert rL345717 : [InstSimplify] fold icmp based on range of abs/nabsSanjay Patel2018-10-311-42/+0
| | | | | | | This can miscompile as shown in PR39510: https://bugs.llvm.org/show_bug.cgi?id=39510 llvm-svn: 345780
* [InstSimplify] fold 'fcmp nnan ult X, 0.0' when X is not negativeSanjay Patel2018-10-311-1/+4
| | | | | | This is the inverted case for the transform added with D53874 / rL345725. llvm-svn: 345728
* [InstSimplify] fold 'fcmp nnan oge X, 0.0' when X is not negativeSanjay Patel2018-10-311-0/+4
| | | | | | | | | | | | | | This re-raises some of the open questions about how to apply and use fast-math-flags in IR from PR38086: https://bugs.llvm.org/show_bug.cgi?id=38086 ...but given the current implementation (no FMF on casts), this is likely the only way to predicate the transform. This is part of solving PR39475: https://bugs.llvm.org/show_bug.cgi?id=39475 Differential Revision: https://reviews.llvm.org/D53874 llvm-svn: 345725
* [InstSimplify] fold icmp based on range of abs/nabsSanjay Patel2018-10-311-0/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a fix for PR39475: https://bugs.llvm.org/show_bug.cgi?id=39475 We managed to get some of these patterns using computeKnownBits in D47041, but that can't be used for nabs(). Instead, put in some range-based logic, so we can fold both abs/nabs with icmp with a constant value. Alive proofs: https://rise4fun.com/Alive/21r Name: abs_nsw_is_positive %cmp = icmp slt i32 %x, 0 %negx = sub nsw i32 0, %x %abs = select i1 %cmp, i32 %negx, i32 %x %r = icmp sgt i32 %abs, -1 => %r = i1 true Name: abs_nsw_is_not_negative %cmp = icmp slt i32 %x, 0 %negx = sub nsw i32 0, %x %abs = select i1 %cmp, i32 %negx, i32 %x %r = icmp slt i32 %abs, 0 => %r = i1 false Name: nabs_is_negative_or_0 %cmp = icmp slt i32 %x, 0 %negx = sub i32 0, %x %nabs = select i1 %cmp, i32 %x, i32 %negx %r = icmp slt i32 %nabs, 1 => %r = i1 true Name: nabs_is_not_over_0 %cmp = icmp slt i32 %x, 0 %negx = sub i32 0, %x %nabs = select i1 %cmp, i32 %x, i32 %negx %r = icmp sgt i32 %nabs, 0 => %r = i1 false Differential Revision: https://reviews.llvm.org/D53844 llvm-svn: 345717
* [InstCombine] InstCombine and InstSimplify for minimum and maximumThomas Lively2018-10-191-7/+18
| | | | | | | | | | | | Summary: Depends on D52765 Reviewers: aheejin, dschuff Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D52766 llvm-svn: 344799
* [FPEnv] PatternMatcher support for checking FNEG ignoring signed zerosCameron McInally2018-10-091-4/+2
| | | | | | https://reviews.llvm.org/D52934 llvm-svn: 344084
* [IR] Replace `isa<TerminatorInst>` with `isTerminator()`.Chandler Carruth2018-08-261-2/+2
| | | | | | | | | | | | This is a bit awkward in a handful of places where we didn't even have an instruction and now we have to see if we can build one. But on the whole, this seems like a win and at worst a reasonable cost for removing `TerminatorInst`. All of this is part of the removal of `TerminatorInst` from the `Instruction` type hierarchy. llvm-svn: 340701
* [InstSimplify] use isKnownNeverNaN to fold more fcmp ord/unoSanjay Patel2018-08-211-7/+5
| | | | | | | | | | | Remove duplicate tests from InstCombine that were added with D50582. I left negative tests there to verify that nothing in InstCombine tries to go overboard. If isKnownNeverNaN is improved to handle the FP binops or other cases, we should have coverage under InstSimplify, so we could remove more duplicate tests from InstCombine at that time. llvm-svn: 340279
OpenPOWER on IntegriCloud