summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [InstSimplify] simplifyUnsignedRangeCheck(): handle few tautological cases ↵Roman Lebedev2019-09-141-16/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | (PR43251) Summary: This is split off from D67356, since these cases produce a constant, no real need to keep them in instcombine. Alive proofs: https://rise4fun.com/Alive/u7Fk https://rise4fun.com/Alive/4lV https://bugs.llvm.org/show_bug.cgi?id=43251 Reviewers: spatel, nikic, xbolva00 Reviewed By: spatel Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67498 llvm-svn: 371921
* [InstSimplify] simplifyUnsignedRangeCheck(): handle more cases (PR43251)Roman Lebedev2019-09-121-0/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: I don't have a direct motivational case for this, but it would be good to have this for completeness/symmetry. This pattern is basically the motivational pattern from https://bugs.llvm.org/show_bug.cgi?id=43251 but with different predicate that requires that the offset is non-zero. The completeness bit comes from the fact that a similar pattern (offset != zero) will be needed for https://bugs.llvm.org/show_bug.cgi?id=43259, so it'd seem to be good to not overlook very similar patterns.. Proofs: https://rise4fun.com/Alive/21b Also, there is something odd with `isKnownNonZero()`, if the non-zero knowledge was specified as an assumption, it didn't pick it up (PR43267) Reviewers: spatel, nikic, xbolva00 Reviewed By: spatel Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67411 llvm-svn: 371718
* [InstSimplify] Pass SimplifyQuery into simplifyUnsignedRangeCheck() and use ↵Roman Lebedev2019-09-111-17/+15
| | | | | | | | | | it for isKnownNonZero() This was actually the original intention in D67332, but i messed up and forgot about it. This patch was originally part of D67411, but precommitting this. llvm-svn: 371630
* [InstSimplify] simplifyUnsignedRangeCheck(): if we know that X != 0, handle ↵Roman Lebedev2019-09-081-9/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | more cases (PR43246) Summary: This is motivated by D67122 sanitizer check enhancement. That patch seemingly worsens `-fsanitize=pointer-overflow` overhead from 25% to 50%, which strongly implies missing folds. In this particular case, given ``` char* test(char& base, unsigned long offset) { return &base + offset; } ``` it will end up producing something like https://godbolt.org/z/LK5-iH which after optimizations reduces down to roughly ``` define i1 @t0(i8* nonnull %base, i64 %offset) { %base_int = ptrtoint i8* %base to i64 %adjusted = add i64 %base_int, %offset %non_null_after_adjustment = icmp ne i64 %adjusted, 0 %no_overflow_during_adjustment = icmp uge i64 %adjusted, %base_int %res = and i1 %non_null_after_adjustment, %no_overflow_during_adjustment ret i1 %res } ``` Without D67122 there was no `%non_null_after_adjustment`, and in this particular case we can get rid of the overhead: Here we add some offset to a non-null pointer, and check that the result does not overflow and is not a null pointer. But since the base pointer is already non-null, and we check for overflow, that overflow check will already catch the null pointer, so the separate null check is redundant and can be dropped. Alive proofs: https://rise4fun.com/Alive/WRzq There are more patterns of "unsigned-add-with-overflow", they are not handled here, but this is the main pattern, that we currently consider canonical, so it makes sense to handle it. https://bugs.llvm.org/show_bug.cgi?id=43246 Reviewers: spatel, nikic, vsk Reviewed By: spatel Subscribers: hiraditya, llvm-commits, reames Tags: #llvm Differential Revision: https://reviews.llvm.org/D67332 llvm-svn: 371349
* Change TargetLibraryInfo analysis passes to always require FunctionTeresa Johnson2019-09-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This is the first change to enable the TLI to be built per-function so that -fno-builtin* handling can be migrated to use function attributes. See discussion on D61634 for background. This is an enabler for fixing handling of these options for LTO, for example. This change should not affect behavior, as the provided function is not yet used to build a specifically per-function TLI, but rather enables that migration. Most of the changes were very mechanical, e.g. passing a Function to the legacy analysis pass's getTLI interface, or in Module level cases, adding a callback. This is similar to the way the per-function TTI analysis works. There was one place where we were looking for builtins but not in the context of a specific function. See FindCXAAtExit in lib/Transforms/IPO/GlobalOpt.cpp. I'm somewhat concerned my workaround could provide the wrong behavior in some corner cases. Suggestions welcome. Reviewers: chandlerc, hfinkel Subscribers: arsenm, dschuff, jvesely, nhaehnle, mehdi_amini, javed.absar, sbc100, jgravelle-google, eraman, aheejin, steven_wu, george.burgess.iv, dexonsmith, jfb, asbirlea, gchatelet, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66428 llvm-svn: 371284
* Allow replaceAndRecursivelySimplify to list unsimplified visitees.Joerg Sonnenberger2019-08-291-12/+18
| | | | | | | This is part of D65280 and split it to avoid ABI changes on the 9.0 release branch. llvm-svn: 370355
* [InstSimplify] Drop leftover "division-by-zero guard" around ↵Roman Lebedev2019-08-291-12/+59
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `@llvm.umul.with.overflow` inverted overflow bit Summary: Now that with D65143/D65144 we've produce `@llvm.umul.with.overflow`, and with D65147 we've flattened the CFG, we now can see that the guard may have been there to prevent division by zero is redundant. We can simply drop it: ``` ---------------------------------------- Name: no overflow or zero %iszero = icmp eq i4 %y, 0 %umul = smul_overflow i4 %x, %y %umul.ov = extractvalue {i4, i1} %umul, 1 %umul.ov.not = xor %umul.ov, -1 %retval.0 = or i1 %iszero, %umul.ov.not ret i1 %retval.0 => %iszero = icmp eq i4 %y, 0 %umul = smul_overflow i4 %x, %y %umul.ov = extractvalue {i4, i1} %umul, 1 %umul.ov.not = xor %umul.ov, -1 %retval.0 = or i1 %iszero, %umul.ov.not ret i1 %umul.ov.not Done: 1 Optimization is correct! ``` Note that this is inverted from what we have in a previous patch, here we are looking for the inverted overflow bit. And that inversion is kinda problematic - given this particular pattern we neither hoist that `not` closer to `ret` (then the pattern would have been identical to the one without inversion, and would have been handled by the previous patch), neither do the opposite transform. But regardless, we should handle this too. I've filled [[ https://bugs.llvm.org/show_bug.cgi?id=42720 | PR42720 ]]. Reviewers: nikic, spatel, xbolva00, RKSimon Reviewed By: spatel Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65151 llvm-svn: 370351
* [InstSimplify] Drop leftover "division-by-zero guard" around ↵Roman Lebedev2019-08-291-0/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `@llvm.umul.with.overflow` overflow bit Summary: Now that with D65143/D65144 we've produce `@llvm.umul.with.overflow`, and with D65147 we've flattened the CFG, we now can see that the guard may have been there to prevent division by zero is redundant. We can simply drop it: ``` ---------------------------------------- Name: no overflow and not zero %iszero = icmp ne i4 %y, 0 %umul = umul_overflow i4 %x, %y %umul.ov = extractvalue {i4, i1} %umul, 1 %retval.0 = and i1 %iszero, %umul.ov ret i1 %retval.0 => %iszero = icmp ne i4 %y, 0 %umul = umul_overflow i4 %x, %y %umul.ov = extractvalue {i4, i1} %umul, 1 %retval.0 = and i1 %iszero, %umul.ov ret %umul.ov Done: 1 Optimization is correct! ``` Reviewers: nikic, spatel, xbolva00 Reviewed By: spatel Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65150 llvm-svn: 370350
* [InstCombine] fold cmp+select using select operand equivalenceSanjay Patel2019-08-021-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
* [InstSimplify] Rename SimplifyFPUnOp and SimplifyFPBinOpJay Foad2019-07-241-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
* [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
OpenPOWER on IntegriCloud