summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CodeGenPrepare.cpp
AgeCommit message (Collapse)Author
2022-03-10Cleanup codegen includesserge-sans-paille
after: 1061034926 before: 1063332844 Differential Revision: https://reviews.llvm.org/D121169
2022-02-23PGOInstrumentation, GCOVProfiling: Split indirectbr critical edges ↵Matthias Braun
regardless of PHIs The `SplitIndirectBrCriticalEdges` function was originally designed for `CodeGenPrepare` and skipped splitting of edges when the destination block didn't contain any `PHI` instructions. This only makes sense when reducing COPYs like `CodeGenPrepare`. In the case of `PGOInstrumentation` or `GCOVProfiling` it would result in missed counters and wrong result in functions with computed goto. Differential Revision: https://reviews.llvm.org/D120096
2022-02-03[CodeGenPrepare] Avoid out-of-bounds shiftBjorn Pettersson
AddressingModeMatcher::matchOperationAddr may attempt to shift a variable by the same amount of steps as found in the IR in a SHL instruction. This was done without considering that there could be undefined behavior in the IR, so the shift performed when compiling could end up having undefined behavior as well. This patch avoid UB in the codegenprepare by making sure that we limit the shift amount used, in a similar way as already being done in CodeGenPrepare::optimizeLoadExt. Differential Revision: https://reviews.llvm.org/D118602
2022-01-30[CodeGen] Use default member initialization (NFC)Kazu Hirata
Identified with modernize-use-default-member-init.
2022-01-23[CodeGenPrepare] Use dyn_cast result to check for null pointersSimon Pilgrim
Simplifies logic and helps the static analyzer correctly check for nullptr dereferences
2022-01-18Revert "[CodeGen][AArch64] Ensure isSExtCheaperThanZExt returns true for ↵David Sherwood
negative constants" This reverts commit 197f3c0deb76951315118ef13937b67ea9cbd5aa. Reverting after miscompilation errors discovered with ffmpeg.
2022-01-17[CodeGen][AArch64] Ensure isSExtCheaperThanZExt returns true for negative ↵David Sherwood
constants When we know the value we're extending is a negative constant then it makes sense to use SIGN_EXTEND because this may improve code quality in some cases, particularly when doing a constant splat of an unpacked vector type. For example, for SVE when splatting the value -1 into all elements of a vector of type <vscale x 2 x i32> the element type will get promoted from i32 -> i64. In this case we want the splat value to sign-extend from (i32 -1) -> (i64 -1), whereas currently it zero-extends from (i32 -1) -> (i64 0xFFFFFFFF). Sign-extending the constant means we can use a single mov immediate instruction. New tests added here: CodeGen/AArch64/sve-vector-splat.ll I believe we see some code quality improvements in these existing tests too: CodeGen/AArch64/reduce-and.ll CodeGen/AArch64/unfold-masked-merge-vector-variablemask.ll The apparent regressions in CodeGen/AArch64/fast-isel-cmp-vec.ll only occur because the test disables codegen prepare and branch folding. Differential Revision: https://reviews.llvm.org/D114357
2022-01-13Revert "[CodeGen][AArch64] Ensure isSExtCheaperThanZExt returns true for ↵David Sherwood
negative constants" This reverts commit 31009f0b5afb504fc1f30769c038e1b7be6ea45b. It seems to be causing SVE VLA buildbot failures and has introduced a genuine regression. Reverting for now.
2022-01-13[CodeGen][AArch64] Ensure isSExtCheaperThanZExt returns true for negative ↵David Sherwood
constants When we know the value we're extending is a negative constant then it makes sense to use SIGN_EXTEND because this may improve code quality in some cases, particularly when doing a constant splat of an unpacked vector type. For example, for SVE when splatting the value -1 into all elements of a vector of type <vscale x 2 x i32> the element type will get promoted from i32 -> i64. In this case we want the splat value to sign-extend from (i32 -1) -> (i64 -1), whereas currently it zero-extends from (i32 -1) -> (i64 0xFFFFFFFF). Sign-extending the constant means we can use a single mov immediate instruction. New tests added here: CodeGen/AArch64/sve-vector-splat.ll I believe we see some code quality improvements in these existing tests too: CodeGen/AArch64/dag-numsignbits.ll CodeGen/AArch64/reduce-and.ll CodeGen/AArch64/unfold-masked-merge-vector-variablemask.ll The apparent regressions in CodeGen/AArch64/fast-isel-cmp-vec.ll only occur because the test disables codegen prepare and branch folding. Differential Revision: https://reviews.llvm.org/D114357
2021-12-12[llvm] Use llvm::reverse (NFC)Kazu Hirata
2021-12-03[CodeGen] Use range-based for loops (NFC)Kazu Hirata
2021-10-25CodeGenPrep: remove all copies of GEP from list if there are duplicates.Tim Northover
Unfortunately ToT has changed enough from the revision where this actually caused problems that the test no longer triggers an assertion failure.
2021-10-20[CodeGenPrepare] Avoid a scalable-vector crash in ctlz/cttzFraser Cormack
This patch fixes a crash when despeculating ctlz/cttz intrinsics with scalable-vector types. It is not safe to speculatively get the size of the vector type in bits in case the vector type is not a fixed-length type. As it happens this isn't required as vector types are skipped anyway. Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D112141
2021-10-04[APInt] Stop using soft-deprecated constructors and methods in llvm. NFC.Jay Foad
Stop using APInt constructors and methods that were soft-deprecated in D109483. This fixes all the uses I found in llvm, except for the APInt unit tests which should still test the deprecated methods. Differential Revision: https://reviews.llvm.org/D110807
2021-09-30[llvm] Migrate from arg_operands to args (NFC)Kazu Hirata
Note that arg_operands is considered a legacy name. See llvm/include/llvm/IR/InstrTypes.h for details.
2021-09-21[RISCV] Teach RISCVTargetLowering::shouldSinkOperands to sink splats for ↵Craig Topper
and/or/xor. This requires a minor change to CodeGenPrepare to ensure that shouldSinkOperands will be called for And. Reviewed By: frasercrmck Differential Revision: https://reviews.llvm.org/D110106
2021-09-19[llvm] Use pop_back_val (NFC)Kazu Hirata
2021-09-18[CodeGen] Use make_early_inc_range (NFC)Kazu Hirata
2021-09-12[CGP] Support opaque pointers in address mode foldNikita Popov
Rather than inspecting the pointer element type, use the access type of the load/store/atomicrmw/cmpxchg. In the process of doing this, simplify the logic by storing the address + type in MemoryUses, rather than an Instruction + Operand pair (which was then used to fetch the address).
2021-08-26[CGP] Fix the crash for combining address mode when having cyclic dependencyAndrew Wei
In the combination of addressing modes, when replacing the matched phi nodes, sometimes the phi node to be replaced has been modified. For example, there’s matcher set [A, B] and [C, A], which will have cyclic dependency: A is replaced by B and C will be replaced by A. Because we tried to match new phi node to another new phi node, we should ignore new phi nodes when mapping new phi node to old one. Reviewed By: skatkov Differential Revision: https://reviews.llvm.org/D108635
2021-08-17[CodeGenPrepare] The instruction to be sunk should be inserted before its ↵Tiehu Zhang
user in a block In current implementation, the instruction to be sunk will be inserted before the target instruction without considering the def-use tree, which may case Instruction does not dominate all uses error. We need to choose a suitable location to insert according to the use chain Reviewed By: dmgreen Differential Revision: https://reviews.llvm.org/D107262
2021-07-24[CGP] despeculateCountZeros - Don't create is-zero branch if cttz/ctlz ↵Simon Pilgrim
source is known non-zero If value tracking can confirm that the cttz/ctlz source is known non-zero then we don't need to create a branch (which DAG will struggle to recover from). Differential Revision: https://reviews.llvm.org/D106685
2021-07-22[WebAssembly] Implementation of global.get/set for reftypes in LLVM IRPaulo Matos
Reland of 31859f896. This change implements new DAG notes GLOBAL_GET/GLOBAL_SET, and lowering methods for load and stores of reference types from IR globals. Once the lowering creates the new nodes, tablegen pattern matches those and converts them to Wasm global.get/set. Reviewed By: tlively Differential Revision: https://reviews.llvm.org/D104797
2021-07-05[DebugInfo] CGP+HWasan: Handle dbg.values with duplicate location opsStephen Tozer
This patch fixes an issue which occurred in CodeGenPrepare and HWAddressSanitizer, which both at some point create a map of Old->New instructions and update dbg.value uses of these. They did this by iterating over the dbg.value's location operands, and if an instance of the old instruction was found, replaceVariableLocationOp would be called on that dbg.value. This would cause an error if the same operand appeared multiple times as a location operand, as the first call to replaceVariableLocationOp would update all uses of the old instruction, invalidating the old iterator and eventually hitting an assertion. This has been fixed by no longer iterating over the dbg.value's location operands directly, but by first collecting them into a set and then iterating over that, ensuring that we never attempt to replace a duplicated operand multiple times. Differential Revision: https://reviews.llvm.org/D105129
2021-07-02Revert "[WebAssembly] Implementation of global.get/set for reftypes in LLVM IR"Roman Lebedev
This reverts commit 4facbf213c51e4add2e8c19b08d5e58ad71c72de. ``` ******************** FAIL: LLVM :: CodeGen/WebAssembly/funcref-call.ll (44466 of 44468) ******************** TEST 'LLVM :: CodeGen/WebAssembly/funcref-call.ll' FAILED ******************** Script: -- : 'RUN: at line 1'; /builddirs/llvm-project/build-Clang12/bin/llc < /repositories/llvm-project/llvm/test/CodeGen/WebAssembly/funcref-call.ll --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | /builddirs/llvm-project/build-Clang12/bin/FileCheck /repositories/llvm-project/llvm/test/CodeGen/WebAssembly/funcref-call.ll -- Exit Code: 2 Command Output (stderr): -- llc: /repositories/llvm-project/llvm/include/llvm/Support/LowLevelTypeImpl.h:44: static llvm::LLT llvm::LLT::scalar(unsigned int): Assertion `SizeInBits > 0 && "invalid scalar size"' failed. ```
2021-07-02[WebAssembly] Implementation of global.get/set for reftypes in LLVM IRPaulo Matos
Reland of 31859f896. This change implements new DAG notes GLOBAL_GET/GLOBAL_SET, and lowering methods for load and stores of reference types from IR globals. Once the lowering creates the new nodes, tablegen pattern matches those and converts them to Wasm global.get/set. Differential Revision: https://reviews.llvm.org/D104797
2021-06-23[CGP][RISCV] Teach CodeGenPrepare::optimizeSwitchInst to honor ↵Craig Topper
isSExtCheaperThanZExt. This optimization pre-promotes the input and constants for a switch instruction to a legal type so that all the generated compares share the same extend. Since RISCV prefers sext for i32 to i64 extends, we should honor that to use sext.w instead of a pair of shifts. Reviewed By: jrtc27 Differential Revision: https://reviews.llvm.org/D104612
2021-06-11[NFC][OpaquePtr] Explicitly pass GEP source type in optimizeGatherScatterInst()Arthur Eubanks
Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D103480
2021-06-10Revert "Implementation of global.get/set for reftypes in LLVM IR"David Spickett
This reverts commit 31859f896cf90d64904134ce7b31230f374c3fcc. Causing SVE and RISCV-V test failures on bots.
2021-06-10Implementation of global.get/set for reftypes in LLVM IRPaulo Matos
This change implements new DAG notes GLOBAL_GET/GLOBAL_SET, and lowering methods for load and stores of reference types from IR globals. Once the lowering creates the new nodes, tablegen pattern matches those and converts them to Wasm global.get/set. Reviewed By: tlively Differential Revision: https://reviews.llvm.org/D95425
2021-05-16[CPG][ARM] Optimize towards branch on zero in codegenprepareDavid Green
This adds a simple fold into codegenprepare that converts comparison of branches towards comparison with zero if possible. For example: %c = icmp ult %x, 8 br %c, bla, blb %tc = lshr %x, 3 becomes %tc = lshr %x, 3 %c = icmp eq %tc, 0 br %c, bla, blb As a first order approximation, this can reduce the number of instructions needed to perform the branch as the shift is (often) needed anyway. At the moment this does not effect very much, as llvm tends to prefer the opposite form. But it can protect against regressions from commits like rG9423f78240a2. Simple cases of Add and Sub are added along with Shift, equally as the comparison to zero can often be folded with cpsr flags. Differential Revision: https://reviews.llvm.org/D101778
2021-04-23[TTI] NFC: Change getIntImmCost[Inst|Intrin] to return InstructionCostSander de Smalen
This patch migrates the TTI cost interfaces to return an InstructionCost. See this patch for the introduction of the type: https://reviews.llvm.org/D91174 See this thread for context: http://lists.llvm.org/pipermail/llvm-dev/2020-November/146408.html Differential Revision: https://reviews.llvm.org/D100565
2021-04-19[DebugInfo] Move the findDbg* functions into DebugInfo.cppOCHyams
Move the findDbg* functions into lib/IR/DebugInfo.cpp from lib/Transforms/Utils/Local.cpp. D99169 adds a call to a function (findDbgUsers) that lives in lib/Transforms/Utils/Local.cpp (LLVMTransformUtils) from lib/IR/Value.cpp (LLVMCore). The Core lib doesn't include TransformUtils. The builtbots caught this here: https://lab.llvm.org/buildbot/#/builders/109/builds/12664. This patch moves the function, and the 3 similar ones for consistency, into DebugInfo.cpp which is part of LLVMCore. Reviewed By: dblaikie, rnk Differential Revision: https://reviews.llvm.org/D100632
2021-04-07[CSSPGO] Move pseudo probes to the beginning of a block to unblock ↵Hongtao Yu
SelectionDAG combine. Pseudo probes, when scattered in a block, can be chained dependencies of other regular DAG nodes and block DAG combine optimizations. To fix this, scattered probes in a block are grouped and placed at the beginning of the block. This shouldn't affect the profile quality. Test Plan: Reviewed By: wenlei, wmi Differential Revision: https://reviews.llvm.org/D100002
2021-04-06Use AssumeInst in a few more places [nfc]Philip Reames
Follow up to a6d2a8d6f5. These were found by simply grepping for "::assume", and are the subset of that result which looked cleaner to me using the isa/dyn_cast patterns.
2021-03-22[TargetTransformInfo] move branch probability query from TargetLoweringInfoSanjay Patel
This is no-functional-change intended (NFC), but needed to allow optimizer passes to use the API. See D98898 for a proposed usage by SimplifyCFG. I'm simplifying the code by removing the cl::opt. That was added back with the original commit in D19488, but I don't see any evidence in regression tests that it was used. Target-specific overrides can use the usual patterns to adjust as necessary. We could also restore that cl::opt, but it was not clear to me exactly how to do it in the convoluted TTI class structure.
2021-03-17Reapply "[DebugInfo] Handle multiple variable location operands in IR"Stephen Tozer
Fixed section of code that iterated through a SmallDenseMap and added instructions in each iteration, causing non-deterministic code; replaced SmallDenseMap with MapVector to prevent non-determinism. This reverts commit 01ac6d1587e8613ba4278786e8341f8b492ac941.
2021-03-17Revert "[DebugInfo] Handle multiple variable location operands in IR"Hans Wennborg
This caused non-deterministic compiler output; see comment on the code review. > This patch updates the various IR passes to correctly handle dbg.values with a > DIArgList location. This patch does not actually allow DIArgLists to be produced > by salvageDebugInfo, and it does not affect any pass after codegen-prepare. > Other than that, it should cover every IR pass. > > Most of the changes simply extend code that operated on a single debug value to > operate on the list of debug values in the style of any_of, all_of, for_each, > etc. Instances of setOperand(0, ...) have been replaced with with > replaceVariableLocationOp, which takes the value that is being replaced as an > additional argument. In places where this value isn't readily available, we have > to track the old value through to the point where it gets replaced. > > Differential Revision: https://reviews.llvm.org/D88232 This reverts commit df69c69427dea7f5b3b3a4d4564bc77b0926ec88.
2021-03-13Restore fixed version of "[CodeGenPrepare] Fix isIVIncrement (PR49466)"Philip Reames
Change was reverted in commit 8d20f2c2c66eb486ff23cc3d55a53bd840b36971 because it was causing an infinite loop. 9228f2f32 fixed the root issue in the code structure, this change just reapplies the original change w/adaptation to the new code structure.
2021-03-13[CGP] Consolidate logic for getIVIncrement and isIVIncrementPhilip Reames
This fixes the bug demonstrated by the test case in the commit message of 8d20f2c2 (which was a revert of cf82700). The root issue was that we have two transforms which are inverses of each other. We use one for simple induction variables (where we can use the post-inc form), and the other for everything else. The problem was that the two transforms could disagree about whether something was an induction variable. The reverted commit made a change to one of the matcher routines which was used for one of the two transforms without updating the other matcher. However, it's worth noting the existing code w/o the reverted change also has cases where the decision could differ between the two paths. The fix is simply to consolidate the code such that two paths must agree by construction, and to add an assert to catch any potential future re-divergence. Triggering the infinite loop requires side stepping the SunkAddrs cache. The SunkAddrs cache has the effect of suppressing the iteration in the common case, but there are codepaths through CGP which restart iteration and clear this cache. Unfortunately, I have not been able to construct a standalone IR test case for this. The original test case is a c++ program which when compiled by clang demonstrates the infinite loop, but all of my attempts at extracting an IR test case runnable through opt/llc have failed to reproduce. (Including capturing the IR at point of the transform itself!) I have no idea what weird state clang is creating here. I also tried creating a test case by hand, but gave up after about an hour of trying to find the right combination to dance through multiple transforms to create the end result needed to trip the bug.
2021-03-12Revert "[CodeGenPrepare] Fix isIVIncrement (PR49466)"Jordan Rupprecht
This reverts commit cf82700af8c658ae09b14c3d01bb1e73e48d3bd3 due to a compile timeout when building the following with `clang -O2`: ``` template <class, class = int> class a; struct b { using d = int *; }; struct e { using f = b::d; }; class g { public: e::f h; e::f i; }; template <class, class> class a : g { public: long j() const { return i - h; } long operator[](long) const noexcept; }; template <class c, class k> long a<c, k>::operator[](long l) const noexcept { return h[l]; } template <typename m, typename n> int fn1(m, n, const char *); int o, p; class D { void q(const a<long> &); long r; }; void D::q(const a<long> &l) { int s; if (l[0]) for (; l.j(); ++s) { if (l[s]) while (fn1(o, 0, "")) ; r = l[s] / p; } } ```
2021-03-12[OpaquePtrs] Remove some uses of type-less CreateGEP() (NFC)Nikita Popov
This removes some (but not all) uses of type-less CreateGEP() and CreateInBoundsGEP() APIs, which are incompatible with opaque pointers. There are a still a number of tricky uses left, as well as many more variation APIs for CreateGEP.
2021-03-09[cgp] improve robustness of uadd/usub transformsPhilip Reames
LSR prefers to schedule iv increments just before the latch. The recent 80511565 broadened this to moving increments in the original IR. This pointed out a robustness problem with the CGP transform. When we have a use of an induction increment outside of the loop (we canonicalize away from this form, but it happens e.g. unanalyzeable loops) we'd avoid performing the uadd/usub transform. Interestingly, all of these involve moving the increment closer to it's operands, so there's no concern about dominating all uses. We can handle that case cheaply, resulting in a more robust transform.
2021-03-09[cgp] group related code together [nfc]Philip Reames
2021-03-09[DebugInfo] Handle multiple variable location operands in IRgbtozers
This patch updates the various IR passes to correctly handle dbg.values with a DIArgList location. This patch does not actually allow DIArgLists to be produced by salvageDebugInfo, and it does not affect any pass after codegen-prepare. Other than that, it should cover every IR pass. Most of the changes simply extend code that operated on a single debug value to operate on the list of debug values in the style of any_of, all_of, for_each, etc. Instances of setOperand(0, ...) have been replaced with with replaceVariableLocationOp, which takes the value that is being replaced as an additional argument. In places where this value isn't readily available, we have to track the old value through to the point where it gets replaced. Differential Revision: https://reviews.llvm.org/D88232
2021-03-09[CodeGenPrepare] Fix isIVIncrement (PR49466)Ta-Wei Tu
In the NFC commit 8d835f42a57f15c0b9053bd7c41ea95821a40e5f, the check for `!L` is moved to a separate function `getIVIncrement` which, instead of using `BO->getParent()`, uses `PN->getParent()`. However, these two basic blocks are not necessarily the same. https://bugs.llvm.org/show_bug.cgi?id=49466 demonstrates a case where `PN` is contained in a loop while `BO` is not, causing the null-pointer dereference in `L->getLoopLatch()`. This patch checks whether both `BO` and `PN` belong to the same loop before entering `getIVIncrement`. Reviewed By: mkazantsev Differential Revision: https://reviews.llvm.org/D98144
2021-03-08[DebugInfo] Support DIArgList in DbgVariableIntrinsicgbtozers
This patch updates DbgVariableIntrinsics to support use of a DIArgList for the location operand, resulting in a significant change to its interface. This patch does not update all IR passes to support multiple location operands in a dbg.value; the only change is to update the DbgVariableIntrinsic interface and its uses. All code outside of the intrinsic classes assumes that an intrinsic will always have exactly one location operand; they will still support DIArgLists, but only if they contain exactly one Value. Among other changes, the setOperand and setArgOperand functions in DbgVariableIntrinsic have been made private. This is to prevent code from setting the operands of these intrinsics directly, which could easily result in incorrect/invalid operands being set. This does not prevent these functions from being called on a debug intrinsic at all, as they can still be called on any CallInst pointer; it is assumed that any code directly setting the operands on a generic call instruction is doing so safely. The intention for making these functions private is to prevent DIArgLists from being overwritten by code that's naively trying to replace one of the Values it points to, and also to fail fast if a DbgVariableIntrinsic is updated to use a DIArgList without a valid corresponding DIExpression.
2021-03-04[cgp] Defer lazy domtree usage to last possible pointPhilip Reames
This is a compile time optimization for d9e93e8e5. Not sure this matters or not, but why not do it just in case. This does involve querying TLI with a potentially invalid addressing mode for the using instruction, but since we don't actually pass the using instruction to the TLI callback, that should be fine.
2021-03-04[CGP] Lazily compute domtree only when needed during address matchingPhilip Reames
This is a compile time optimization for d9e93e8e5. As pointed out in post dommit review on the original review (D96399), there was a moderately large compile time regression with this patch and the eager computation of domtree on matcher construction is the first obvious candidate for why.
2021-03-04[CodeGenPrepare] Eliminate llvm.expect before removing empty blocksJann Horn
CodeGenPrepare currently first removes empty blocks, then in a loop performs other optimizations. One of those optimizations is the removal of call instructions that invoke @llvm.assume, which can create new empty blocks. This means that when a branch only contains a call to __builtin_assume(), the empty branch will survive into MIR, and will then only be half-removed by MIR-level optimizations (e.g. removing the branch but leaving the condition intact). Fix it by eliminating @llvm.expect builtin calls before removing empty blocks. Reviewed By: bkramer Differential Revision: https://reviews.llvm.org/D97848