summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [InstCombine] Z / (1.0 / Y) => (Y * Z)@raghesh (Raghesh Aloor)2020-01-091-0/+8
| | | | | | | | | This is a special case of Z / (X / Y) => (Y * Z) / X, with X = 1.0. The m_OneUse check is avoided because even in the case of the multiple uses for 1.0/Y, the number of instructions remain the same and a division is replaced by a multiplication. Differential Revision: https://reviews.llvm.org/D72319
* [InstCombine] fix undef propagation for vector urem transform (PR44186)Sanjay Patel2019-12-021-2/+4
| | | | | | | | | As described here: https://bugs.llvm.org/show_bug.cgi?id=44186 The match() code safely allows undef values, but we can't safely propagate a vector constant that contains an undef to the new compare instruction.
* [InstCombine] fold fneg disguised as select+fmul (PR43497)Sanjay Patel2019-10-061-18/+49
| | | | | | | Extends rL373230 and solves the motivating bug (although in a narrow way): https://bugs.llvm.org/show_bug.cgi?id=43497 llvm-svn: 373851
* [InstCombine] fold negate disguised as select+mulSanjay Patel2019-09-301-0/+19
| | | | | | | | | | | | | | | | | | | | Name: negate if true %sel = select i1 %cond, i32 -1, i32 1 %r = mul i32 %sel, %x => %m = sub i32 0, %x %r = select i1 %cond, i32 %m, i32 %x Name: negate if false %sel = select i1 %cond, i32 1, i32 -1 %r = mul i32 %sel, %x => %m = sub i32 0, %x %r = select i1 %cond, i32 %x, i32 %m https://rise4fun.com/Alive/Nlh llvm-svn: 373230
* [InstCombine] x /c fabs(x) -> copysign(1.0, x)David Bolvansky2019-08-121-0/+11
| | | | | | | | | | | | | | | | | | Summary: x / fabs(x) -> copysign(1.0, x) fabs(x) / x -> copysign(1.0, x) Reviewers: spatel, foad, RKSimon, efriedma Reviewed By: spatel Subscribers: lebedev.ri, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65898 llvm-svn: 368570
* [Transforms] Rename hasUnaryFloatFn() and getUnaryFloatFn() (NFC)Evandro Menezes2019-08-091-2/+2
| | | | | | Rename `hasUnaryFloatFn()` to `hasFloatFn()` and `getUnaryFloatFn()` to `getFloatFnName()`. llvm-svn: 368449
* [InstCombine] canonicalize fneg before fmul/fdivSanjay Patel2019-07-311-20/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Reverse the canonicalization of fneg relative to fmul/fdiv. That makes it easier to implement the transforms (and possibly other fneg transforms) in 1 place because we can always start the pattern match from fneg (either the legacy binop or the new unop). There's a secondary practical benefit seen in PR21914 and PR42681: https://bugs.llvm.org/show_bug.cgi?id=21914 https://bugs.llvm.org/show_bug.cgi?id=42681 ...hoisting fneg rather than sinking seems to play nicer with LICM in IR (although this change may expose analysis holes in the other direction). 1. The instcombine test changes show the expected neutral IR diffs from reversing the order. 2. The reassociation tests show that we were missing an optimization opportunity to fold away fneg-of-fneg. My reading of IEEE-754 says that all of these transforms are allowed (regardless of binop/unop fneg version) because: "For all other operations [besides copy/abs/negate/copysign], this standard does not specify the sign bit of a NaN result." In all of these transforms, we always have some other binop (fadd/fsub/fmul/fdiv), so we are free to flip the sign bit of a potential intermediate NaN operand. (If that interpretation is wrong, then we must already have a bug in the existing transforms?) 3. The clang tests shouldn't exist as-is, but that's effectively a revert of rL367149 (the test broke with an extension of the pre-existing fneg canonicalization in rL367146). Differential Revision: https://reviews.llvm.org/D65399 llvm-svn: 367447
* [InstCombine] Fold "x ?% y ==/!= 0" to "x & (y-1) ==/!= 0" iff y is ↵Roman Lebedev2019-07-301-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | power-of-two Summary: I have stumbled into this by accident while preparing to extend backend `x s% C ==/!= 0` handling. While we did happen to handle this fold in most of the cases, the folding is indirect - we fold `x u% y` to `x & (y-1)` (iff `y` is power-of-two), or first turn `x s% -y` to `x u% y`; that does handle most of the cases. But we can't turn `x s% INT_MIN` to `x u% -INT_MIN`, and thus we end up being stuck with `(x s% INT_MIN) == 0`. There is no such restriction for the more general fold: https://rise4fun.com/Alive/IIeS To be noted, the fold does not enforce that `y` is a constant, so it may indeed increase instruction count. This is consistent with what `x u% y`->`x & (y-1)` already does. I think it makes sense, it's at most one (simple) extra instruction, while `rem`ainder is really much more un-simple (and likely **very** costly). Reviewers: spatel, RKSimon, nikic, xbolva00, craig.topper Reviewed By: RKSimon Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65046 llvm-svn: 367322
* [InstCombine] canonicalize negated operand of fdivSanjay Patel2019-07-261-0/+10
| | | | | | | This is a transform that we use with fmul, so use it for fdiv too for consistency. llvm-svn: 367146
* Fix parameter name comments using clang-tidy. NFC.Rui Ueyama2019-07-161-4/+4
| | | | | | | | | | | | | | | | | | | | | This patch applies clang-tidy's bugprone-argument-comment tool to LLVM, clang and lld source trees. Here is how I created this patch: $ git clone https://github.com/llvm/llvm-project.git $ cd llvm-project $ mkdir build $ cd build $ cmake -GNinja -DCMAKE_BUILD_TYPE=Debug \ -DLLVM_ENABLE_PROJECTS='clang;lld;clang-tools-extra' \ -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DLLVM_ENABLE_LLD=On \ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ../llvm $ ninja $ parallel clang-tidy -checks='-*,bugprone-argument-comment' \ -config='{CheckOptions: [{key: StrictMode, value: 1}]}' -fix \ ::: ../llvm/lib/**/*.{cpp,h} ../clang/lib/**/*.{cpp,h} ../lld/**/*.{cpp,h} llvm-svn: 366177
* [InstCombine] don't move FP negation out of a constant expressionSanjay Patel2019-07-111-2/+4
| | | | | | | -(X * ConstExpr) becomes X * (-ConstExpr), so don't reverse that and infinite loop. llvm-svn: 365774
* [InstCombine] canonicalize fdiv after fmul if reassociation is allowedSanjay Patel2019-04-151-0/+8
| | | | | | | | (X / Y) * Z --> (X * Z) / Y This can allow other optimizations/reassociations as shown in the test diffs. llvm-svn: 358404
* [InstCombine] Canonicalize (-X srem Y) to -(X srem Y).Chen Zheng2019-04-131-0/+5
| | | | | | Differential Revision: https://reviews.llvm.org/D60647 llvm-svn: 358328
* [InstCombine] Canonicalize (-X s/ Y) to -(X s/ Y).Chen Zheng2019-04-101-0/+6
| | | | | | Differential Revision: https://reviews.llvm.org/D60395 llvm-svn: 358050
* Revert "[InstCombine] [InstCombine] Canonicalize (-X s/ Y) to -(X s/ Y)."Nikita Popov2019-04-091-6/+0
| | | | | | | | | | | This reverts commit 1383a9168948aabfd827220c9445ce0ce5765800. sdiv-canonicalize.ll fails after this revision. The fold needs to be moved outside the branch handling constant operands. However when this is done there are further test changes, so I'm reverting this in the meantime. llvm-svn: 358026
* [InstCombine] [InstCombine] Canonicalize (-X s/ Y) to -(X s/ Y).Chen Zheng2019-04-091-0/+6
| | | | | | Differential Revision: https://reviews.llvm.org/D60395 llvm-svn: 358017
* [InstCombine] prevent possible miscompile with sdiv+negate of vector opSanjay Patel2019-04-091-10/+11
| | | | | | | | | | | Similar to: rL358005 Forego folding arbitrary vector constants to fix a possible miscompile bug. We can enhance the transform if we do want to handle the more complicated vector case. llvm-svn: 358013
* [InstCombine] peek through fdiv to find a squared sqrtSanjay Patel2019-04-081-0/+19
| | | | | | | | | | | | A more general canonicalization between fdiv and fmul would not handle this case because that would have to be limited by uses to prevent 2 values from becoming 3 values: (x/y) * (x/y) --> (x*x) / (y*y) (But we probably should still have that limited -- but more general -- canonicalization independently of this change.) llvm-svn: 357943
* [CallSite removal] Remove CallSite uses from InstCombine.Craig Topper2019-01-311-1/+2
| | | | | | | | | | | | Reviewers: chandlerc Reviewed By: chandlerc Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D57494 llvm-svn: 352771
* [InstCombine] Missed optimization in math expression: simplify calls exp ↵Dmitry Venikov2019-01-311-0/+20
| | | | | | | | | | | | | | | | functions Summary: This patch enables folding following expressions under -ffast-math flag: exp(X) * exp(Y) -> exp(X + Y), exp2(X) * exp2(Y) -> exp2(X + Y). Motivation: https://bugs.llvm.org/show_bug.cgi?id=35594 Reviewers: hfinkel, spatel, efriedma, lebedev.ri Reviewed By: spatel, lebedev.ri Subscribers: lebedev.ri, llvm-commits Differential Revision: https://reviews.llvm.org/D41342 llvm-svn: 352730
* 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
* [InstCombine] canonicalize MUL with NEG operandChen Zheng2019-01-011-0/+5
| | | | | | | | | -X * Y --> -(X * Y) X * -Y --> -(X * Y) Differential Revision: https://reviews.llvm.org/D55961 llvm-svn: 350185
* Add a emitUnaryFloatFnCall version that fetches the function name from TLIMikael Holmen2018-10-181-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: In several places in the code we use the following pattern: if (hasUnaryFloatFn(&TLI, Ty, LibFunc_tan, LibFunc_tanf, LibFunc_tanl)) { [...] Value *Res = emitUnaryFloatFnCall(X, TLI.getName(LibFunc_tan), B, Attrs); [...] } In short, we check if there is a lib-function for a certain type, and then we _always_ fetch the name of the "double" version of the lib function and construct a call to the appropriate function, that we just checked exists, using that "double" name as a basis. This is of course a problem in cases where the target doesn't support the "double" version, but e.g. only the "float" version. In that case TLI.getName(LibFunc_tan) returns "", and emitUnaryFloatFnCall happily appends an "f" to "", and we erroneously end up with a call to a function called "f". To solve this, the above pattern is changed to if (hasUnaryFloatFn(&TLI, Ty, LibFunc_tan, LibFunc_tanf, LibFunc_tanl)) { [...] Value *Res = emitUnaryFloatFnCall(X, &TLI, LibFunc_tan, LibFunc_tanf, LibFunc_tanl, B, Attrs); [...] } I.e instead of first fetching the name of the "double" version and then letting emitUnaryFloatFnCall() add the final "f" or "l", we let emitUnaryFloatFnCall() fetch the right name from TLI. Reviewers: eli.friedman, efriedma Reviewed By: efriedma Subscribers: efriedma, bjope, llvm-commits Differential Revision: https://reviews.llvm.org/D53370 llvm-svn: 344725
* [IRBuilder] Fixup CreateIntrinsic to allow specifying Types to Mangle.Neil Henning2018-10-081-1/+1
| | | | | | | | | | | | | | | | | | | | The IRBuilder CreateIntrinsic method wouldn't allow you to specify the types that you wanted the intrinsic to be mangled with. To fix this I've: - Added an ArrayRef<Type *> member to both CreateIntrinsic overloads. - Used that array to pass into the Intrinsic::getDeclaration call. - Added a CreateUnaryIntrinsic to replace the most common use of CreateIntrinsic where the type was auto-deduced from operand 0. - Added a bunch more unit tests to test Create*Intrinsic calls that weren't being tested (including the FMF flag that wasn't checked). This was suggested as part of the AMDGPU specific atomic optimizer review (https://reviews.llvm.org/D51969). Differential Revision: https://reviews.llvm.org/D52087 llvm-svn: 343962
* [InstCombine] name change: foldShuffledBinop -> foldVectorBinop; NFCSanjay Patel2018-10-031-8/+8
| | | | | | | This function will deal with more than shuffles with D50992, and I have another potential per-element fold that could live here. llvm-svn: 343692
* [InstCombine] refactor mul narrowing folds; NFCISanjay Patel2018-09-141-71/+2
| | | | | | | | | | | | | Similar to rL342278: The test diffs are all cosmetic due to the change in value naming, but I'm including that to show that the new code does perform these folds rather than something else in instcombine. D52075 should be able to use this code too rather than duplicating all of the logic. llvm-svn: 342292
* [InstCombine] Fix incorrect usage of getPrimitiveSizeInBits when we should ↵Craig Topper2018-09-111-2/+1
| | | | | | | | | | be using the element size for vectors For vectors, getPrimitiveSizeInBits returns the full vector width. This code should using the element size for vectors. This could be fixed by calling getScalarSizeInBits, but its even easier to just get it from the APInt we're checking. Differential Revision: https://reviews.llvm.org/D51938 llvm-svn: 341971
* [InstCombine] Support (mul (sext x), cst) --> (sext (mul x, cst')) and (mul ↵Craig Topper2018-09-111-2/+2
| | | | | | | | | | (zext x), cst) --> (zext (mul x, cst')) for vectors constants. Similar to D51236, but for mul instead of add. Differential Revision: https://reviews.llvm.org/D51900 llvm-svn: 341961
* [InstCombine] fold udiv with common factor from muls with nuwSanjay Patel2018-07-261-0/+15
| | | | | | | | | Unfortunately, sdiv isn't as simple because of UB due to overflow. This fold is mentioned in PR38239: https://bugs.llvm.org/show_bug.cgi?id=38239 llvm-svn: 338059
* [InstCombine] Corrections in comments for division transformation (NFC)Sanjay Patel2018-07-151-3/+3
| | | | | | | | | | The actual code seems to be correct, but the comments were misleading. Patch by Aaron Puchert! Differential Revision: https://reviews.llvm.org/D49276 llvm-svn: 337131
* [InstCombine] return when SimplifyAssociativeOrCommutative makes a changeSanjay Patel2018-07-131-3/+8
| | | | | | | | | | | | | This bug was created by rL335258 because we used to always call instsimplify after trying the associative folds. After that change it became possible for subsequent folds to encounter unsimplified code (and potentially assert because of it). Instead of carrying changed state through instcombine, we can just return immediately. This allows instsimplify to run, so we can continue assuming that easy folds have already occurred. llvm-svn: 336965
* [InstCombine] simplify code for urem fold; NFCISanjay Patel2018-06-261-5/+2
| | | | llvm-svn: 335623
* [InstCombine] fold urem with sext bool divisorSanjay Patel2018-06-261-2/+13
| | | | | | | | | | | | | | | | | | | | | | Similar to other patches in this series: https://reviews.llvm.org/rL335512 https://reviews.llvm.org/rL335527 https://reviews.llvm.org/rL335597 https://reviews.llvm.org/rL335616 ...this is filling a gap in analysis that is exposed by an unrelated select-of-constants transform. I didn't see a way to unify the sext cases because each div/rem opcode results in a different fold. Note that in this case, the backend might want to convert the select into math: Name: sext urem %e = sext i1 %x to i32 %r = urem i32 %y, %e => %c = icmp eq i32 %y, -1 %z = zext i1 %c to i32 %r = add i32 %z, %y llvm-svn: 335622
* [InstCombine] fold udiv with sext bool divisorSanjay Patel2018-06-261-1/+7
| | | | | | | | | | Note: I didn't add a hasOneUse() check because the existing, related fold doesn't have that check. I suspect that the improved analysis and codegen make these some of the rare canonicalization cases where we allow an increase in instructions. llvm-svn: 335597
* [InstCombine] cleanup udiv folds; NFCISanjay Patel2018-06-251-30/+20
| | | | | | | | | This removes a "UDivFoldAction" in favor of a simple constant matcher. In theory, the existing code could do more matching, but I don't see any evidence or need for it. I've left a TODO about using ValueTracking in case we see any regressions. llvm-svn: 335545
* [InstCombine] fold sdiv with sext bool divisorSanjay Patel2018-06-251-4/+7
| | | | llvm-svn: 335527
* [InstCombine] simplify binops before trying other foldsSanjay Patel2018-06-211-18/+25
| | | | | | | | | | This is outwardly NFC from what I can tell, but it should be more efficient to simplify first (despite the name, SimplifyAssociativeOrCommutative does not actually simplify as InstSimplify does - it creates/morphs instructions). This should make it easier to refactor duplicated code that runs for all binops. llvm-svn: 335258
* [InstCombine] Fix div handlingSerguei Katkov2018-06-041-2/+2
| | | | | | | | | | | | | When we optimize select basing on fact that div by 0 is undef we should not traverse the instruction which are not guaranteed to transfer execution to next instruction. Guard intrinsic is an example. Reviewers: spatel, craig.topper Reviewed By: spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D47576 llvm-svn: 333864
* [InstCombine] call simplify before trying vector foldsSanjay Patel2018-06-021-32/+24
| | | | | | | | | | | | | | | | | | | | As noted in the review thread for rL333782, we could have made a bug harder to hit if we were simplifying instructions before trying other folds. The shuffle transform in question isn't ever a simplification; it's just a canonicalization. So I've renamed that to make that clearer. This is NFCI at this point, but I've regenerated the test file to show the cosmetic value naming difference of using instcombine's RAUW vs. the builder. Possible follow-ups: 1. Move reassociation folds after simplifies too. 2. Refactor common code; we shouldn't have so much repetition. llvm-svn: 333820
* [InstCombine] Moving overflow computation logic from InstCombine to ↵Omer Paparo Bivas2018-05-101-41/+0
| | | | | | | | | ValueTracking; NFC Differential Revision: https://reviews.llvm.org/D46704 Change-Id: Ifabcbe431a2169743b3cc310f2a34fd706f13f02 llvm-svn: 332026
* Remove @brief commands from doxygen comments, too.Adrian Prantl2018-05-011-2/+2
| | | | | | | | | | | | | | | | | This is a follow-up to r331272. We've been running doxygen with the autobrief option for a couple of years now. This makes the \brief markers into our comments redundant. Since they are a visual distraction and we don't want to encourage more \brief markers in new code either, this patch removes them all. Patch produced by for i in $(git grep -l '\@brief'); do perl -pi -e 's/\@brief //g' $i & done https://reviews.llvm.org/D46290 llvm-svn: 331275
* Remove \brief commands from doxygen comments.Adrian Prantl2018-05-011-4/+4
| | | | | | | | | | | | | | | | We've been running doxygen with the autobrief option for a couple of years now. This makes the \brief markers into our comments redundant. Since they are a visual distraction and we don't want to encourage more \brief markers in new code either, this patch removes them all. Patch produced by for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done Differential Revision: https://reviews.llvm.org/D46290 llvm-svn: 331272
* [InstCombine] allow more fmul folds with 'reassoc'Sanjay Patel2018-04-031-64/+64
| | | | | | | | The tests marked with 'FIXME' require loosening the check in SimplifyAssociativeOrCommutative() to optimize completely; that's still checking isFast() in Instruction::isAssociative(). llvm-svn: 329121
* [InstCombine] improve code comment; NFCSanjay Patel2018-03-261-2/+2
| | | | llvm-svn: 328560
* [InstCombine] distribute fmul over fadd/fsubSanjay Patel2018-03-261-98/+15
| | | | | | | | | | This replaces a large chunk of code that was looking for compound patterns that include these sub-patterns. Existing tests ensure that all of the previous examples are still folded as expected. We still need to loosen the FMF check. llvm-svn: 328502
* [InstCombine] check uses before creating instructions for fmul distributionSanjay Patel2018-03-261-1/+1
| | | | | | As the tests show, we could create extra instructions without any obvious benefit. llvm-svn: 328498
* [InstCombine] add nnan requirement for sqrt(x) * sqrt(y) -> sqrt(x*y)Sanjay Patel2018-03-181-1/+3
| | | | | | This is similar to D43765. llvm-svn: 327797
* [InstCombine] fix fmul reassociation to avoid creating an extra fdivSanjay Patel2018-03-131-6/+20
| | | | | | | | | | | | | This was supposed to be an NFC refactoring that will eventually allow eliminating the isFast() predicate, but there's a rare possibility that we would pessimize the code as shown in the test case because we failed to check 'hasOneUse()' properly. This version also removes an inefficiency of the old code; we would look for: (X * C) * C1 --> X * (C * C1) ...but that pattern is always handled by SimplifyAssociativeOrCommutative(). llvm-svn: 327404
* [InstCombine] rearrange visitFMul; NFCISanjay Patel2018-03-021-73/+69
| | | | | | | Put the simplest non-FMF folds first, so it's easier to see what's left to fix/group/add with the FMF folds. llvm-svn: 326632
* [InstCombine] partly fix FMF for fmul+log2 foldSanjay Patel2018-03-021-52/+17
| | | | | | | | | | The code was checking that all of the instructions in the sequence are 'fast', but that's not necessary. The final multiply is all that we need to check (tests adjusted). The fmul doesn't need to be fully 'fast' either, but that can be another patch. llvm-svn: 326608
OpenPOWER on IntegriCloud