aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
AgeCommit message (Collapse)AuthorFilesLines
2019-08-02[InstCombine] fold cmp+select using select operand equivalenceSanjay Patel1-0/+3
As discussed in PR42696: https://bugs.llvm.org/show_bug.cgi?id=42696 ...but won't help that case yet. We have an odd situation where a select operand equivalence fold was implemented in InstSimplify when it could have been done more generally in InstCombine if we allow dropping of {nsw,nuw,exact} from a binop operand. Here's an example: https://rise4fun.com/Alive/Xplr %cmp = icmp eq i32 %x, 2147483647 %add = add nsw i32 %x, 1 %sel = select i1 %cmp, i32 -2147483648, i32 %add => %sel = add i32 %x, 1 I've left the InstSimplify code in place for now, but my guess is that we'd prefer to remove that as a follow-up to save on code duplication and compile-time. Differential Revision: https://reviews.llvm.org/D65576 llvm-svn: 367695
2019-07-24[InstSimplify] Rename SimplifyFPUnOp and SimplifyFPBinOpJay Foad1-14/+12
Summary: SimplifyFPBinOp is a variant of SimplifyBinOp that lets you specify fast math flags, but the name is misleading because both functions can simplify both FP and non-FP ops. Instead, overload SimplifyBinOp so that you can optionally specify fast math flags. Likewise for SimplifyFPUnOp. Reviewers: spatel Reviewed By: spatel Subscribers: xbolva00, cameron.mcinally, eraman, hiraditya, haicheng, zzheng, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64902 llvm-svn: 366902
2019-07-16[InstructionSimplify] Apply sext/trunc after pointer strippingMichael Liao1-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
2019-07-11InstructionSimplify: Simplify InstructionSimplify. NFC.Tim Northover1-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
2019-07-11Replace three "strip & accumulate" implementations with a single oneJohannes Doerfert1-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
2019-06-20[InstSimplify] simplify power-of-2 (single bit set) sequencesSanjay Patel1-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
2019-06-16[InstSimplify] Fix addo/subo undef folds (PR42209)Roman Lebedev1-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
2019-06-09[InstSimplify] reduce code duplication for fcmp folds; NFCSanjay Patel1-10/+7
llvm-svn: 362904
2019-06-09[InstSimplify] enhance fcmp fold with never-nan operandSanjay Patel1-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
2019-06-08[InstSimplify] enhance fcmp fold with never-nan operandSanjay Patel1-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
2019-05-31[InstructionSimplify] Add missing implementation of llvm::SimplifyUnOp. NFCCraig Topper1-0/+4
There are no callers currently, but the function is declared so we should at least implement it. llvm-svn: 362205
2019-05-24[InstSimplify] fold insertelement-of-extractelementSanjay Patel1-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
2019-05-23[InstSimplify] insertelement V, undef, ? --> VSanjay Patel1-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
2019-05-20[InstSimplify] update stale comment; NFCSanjay Patel1-1/+1
Missed this diff with rL361118. llvm-svn: 361180
2019-05-20[InstSimplify] Teach fsub -0.0, (fneg X) ==> X about unary fnegCameron McInally1-1/+2
Differential Revision: https://reviews.llvm.org/D62077 llvm-svn: 361151
2019-05-19[InstSimplify] fold fcmp (maxnum, X, C1), C2Sanjay Patel1-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
2019-05-17[InstSimplify] Add unary fneg to `fsub 0.0, (fneg X) ==> X` transformCameron McInally1-1/+3
Differential Revision: https://reviews.llvm.org/D62013 llvm-svn: 361047
2019-05-16[InstSimplify] fold fcmp (minnum, X, C1), C2Sanjay Patel1-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
2019-05-15Teach InstSimplify -X + X --> 0.0 about unary FNegCameron McInally1-4/+10
Differential Revision: https://reviews.llvm.org/D61916 llvm-svn: 360777
2019-05-06Add FNeg support to InstructionSimplifyCameron McInally1-0/+65
Differential Revision: https://reviews.llvm.org/D61573 llvm-svn: 360053
2019-04-25Consolidate existing utilities for interpreting vector predicate maskes [NFC]Philip Reames1-16/+0
llvm-svn: 359163
2019-04-24Add "const" in GetUnderlyingObjects. NFCBjorn Pettersson1-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
2019-04-22[InstSimplify] Move masked.gather w/no active lanes handling to InstSimplify ↵Philip Reames1-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
2019-04-03InstSimplify: Fold round intrinsics from sitofp/uitofpMatt Arsenault1-0/+16
https://godbolt.org/z/gEMRZb llvm-svn: 357549
2019-03-19[InstSimplify] SimplifyICmpInst - icmp eq/ne %X, undef -> undefSimon Pilgrim1-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
2019-03-18[ValueTracking][InstSimplify] Move abs handling into computeConstantRange(); NFCNikita Popov1-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
2019-03-14[InstCombine] canonicalize funnel shift constant shift amount to be modulo ↵Sanjay Patel1-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
2019-03-09[ValueTracking] Move constant range computation into ValueTracking; NFCNikita Popov1-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
2019-02-26[InstSimplify] remove zero-shift-guard fold for general funnel shiftSanjay Patel1-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
2019-02-20[InstSimplify] use any-zero matcher for fcmp foldsSanjay Patel1-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
2019-02-20Revert "[InstSimplify] use any-zero matcher for fcmp folds"Sanjay Patel1-25/+22
This reverts commit 058bb8351351d56d2a4e8a772570231f9e5305e5. Forgot to update another test affected by this change. llvm-svn: 354408
2019-02-20[InstSimplify] use any-zero matcher for fcmp foldsSanjay Patel1-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
2019-02-11[CallSite removal] Port InstSimplify over to use `CallBase` both in itsChandler Carruth1-19/+17
interface and implementation. Port code with: `cast<CallBase>(CS.getInstruction())`. llvm-svn: 353662
2019-02-11[CallSite removal] Migrate ConstantFolding APIs and implementation toChandler Carruth1-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
2019-02-03[InstSimplify] Missed optimization in math expression: log10(pow(10.0,x)) == ↵Dmitry Venikov1-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
2019-01-19Update the file headers across all of the LLVM projects in the monorepoChandler Carruth1-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
2018-12-17[InstSimplify] Simplify saturating add/sub + icmpNikita Popov1-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
2018-12-02[ValueTracking] add helper function for testing implied condition; NFCISanjay Patel1-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
2018-11-29[InstSimplify] fold select with implied conditionSanjay Patel1-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
2018-11-20[InstSimplify] fold funnel shifts with undef operandsSanjay Patel1-1/+10
Splitting these off from the D54666. Patch by: nikic (Nikita Popov) llvm-svn: 347332
2018-11-20[InstructionSimplify] Add support for saturating add/subSanjay Patel1-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
2018-11-15[InstSimplify] delete shift-of-zero guard ops around funnel shiftsSanjay Patel1-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
2018-11-05[InstSimplify] fold select (fcmp X, Y), X, YSanjay Patel1-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
2018-11-01[InstSimplify] fold icmp based on range of abs/nabs (2nd try)Sanjay Patel1-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
2018-10-31revert rL345717 : [InstSimplify] fold icmp based on range of abs/nabsSanjay Patel1-42/+0
This can miscompile as shown in PR39510: https://bugs.llvm.org/show_bug.cgi?id=39510 llvm-svn: 345780
2018-10-31[InstSimplify] fold 'fcmp nnan ult X, 0.0' when X is not negativeSanjay Patel1-1/+4
This is the inverted case for the transform added with D53874 / rL345725. llvm-svn: 345728
2018-10-31[InstSimplify] fold 'fcmp nnan oge X, 0.0' when X is not negativeSanjay Patel1-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
2018-10-31[InstSimplify] fold icmp based on range of abs/nabsSanjay Patel1-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
2018-10-19[InstCombine] InstCombine and InstSimplify for minimum and maximumThomas Lively1-7/+18
Summary: Depends on D52765 Reviewers: aheejin, dschuff Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D52766 llvm-svn: 344799
2018-10-09[FPEnv] PatternMatcher support for checking FNEG ignoring signed zerosCameron McInally1-4/+2
https://reviews.llvm.org/D52934 llvm-svn: 344084