summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
AgeCommit message (Collapse)Author
2025-11-17[SystemZ] TableGen-erate node descriptions (#168113)Sergei Barannikov
This allows SDNodes to be validated against their expected type profiles and reduces the number of changes required to add a new node. There is only one node that is missing a description -- `GET_CCMASK`, others were successfully imported. Part of #119709. Pull Request: https://github.com/llvm/llvm-project/pull/168113
2025-09-19[PowerPC] using milicode call for strlen instead of lib call (#153600)zhijian lin
AIX has "millicode" routines, which are functions loaded at boot time into fixed addresses in kernel memory. This allows them to be customized for the processor. The __strlen routine is a millicode implementation; we use millicode for the strlen function instead of a library call to improve performance.
2025-08-07[PowerPC][AIX] Using milicode for memcmp instead of libcall (#147093)zhijian lin
AIX has "millicode" routines, which are functions loaded at boot time into fixed addresses in kernel memory. This allows them to be customized for the processor. The __memcmp routine is a millicode implementation; we use millicode for the memcmp function instead of a library call to improve performance.
2024-12-21[SelectionDAG] Virtualize isTargetStrictFPOpcode / isTargetMemoryOpcode ↵Sergei Barannikov
(#119969) With this change, targets are no longer required to put memory / strict-fp opcodes after special `ISD::FIRST_TARGET_MEMORY_OPCODE`/`ISD::FIRST_TARGET_STRICTFP_OPCODE` markers. This will also allow autogenerating `isTargetMemoryOpcode`/`isTargetStrictFPOpcode (#119709). Pull Request: https://github.com/llvm/llvm-project/pull/119969
2024-11-25[SystemZ] Use getSignedConstant() where necessary (#117181)Nikita Popov
This will avoid assertion failures once we disable implicit truncation in getConstant(). Inside adjustSubwordCmp() I ended up suppressing the issue with an explicit cast, because this code deals with a mix of unsigned and signed immediates.
2023-01-24[SystemZ] Use llvm::bit_floor (NFC)Kazu Hirata
If x is known to be nonzero, findLastSet(x) returns the index of the highest set bit counting from the LSB, so 1 << findLastSet(x) is the same as llvm::bit_floor(x).
2023-01-24[NFC] Deprecate SelectionDag functions taking Alignment as unsignedGuillaume Chatelet
2023-01-22Use llvm::popcount instead of llvm::countPopulation(NFC)Kazu Hirata
2022-08-07[llvm] Fix comment typos (NFC)Kazu Hirata
2022-06-10[clang] Add support for __builtin_memset_inlineGuillaume Chatelet
In the same spirit as D73543 and in reply to https://reviews.llvm.org/D126768#3549920 this patch is adding support for `__builtin_memset_inline`. The idea is to get support from the compiler to easily write efficient memory function implementations. This patch could be split in two: - one for the LLVM part adding the `llvm.memset.inline.*` intrinsics. - and another one for the Clang part providing the instrinsic as a builtin. Differential Revision: https://reviews.llvm.org/D126903
2021-12-06[SystemZ] Improve codegen for memset.Jonas Paulsson
Memset with a constant length was implemented with a single store followed by a series of MVC:s. This patch changes this so that one store of the byte is emitted for each MVC, which avoids data dependencies between the MVCs. An MVI/STC + MVC(len-1) is done for each block. In addition, memset with a variable length is now also handled without a libcall. Since the byte is first stored and then MVC is used from that address, a length of two must now be subtracted instead of one for the loop and EXRL. This requires an extra check for the one-byte case, which is handled in a special block with just a single MVI/STC (like GCC). Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D112004
2021-10-14[SystemZ] Reapply memcmp and memcpy patches.Jonas Paulsson
This reverts 3562076 and includes some refactoring as well. Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D111733
2021-10-14[SystemZ] Bugfix and refactorization of mem-mem operationsJonas Paulsson
This patch fixes the bug that consisted of treating variable / immediate length mem operations (such as memcpy, memset, ...) differently. The variable length case needs to have the length minus 1 passed due to the use of EXRL target instructions. However, the DAGCombiner can convert a register length argument into a constant one, and whenever that happened one byte too little would end up being performed. This is also a refactorization by reducing the number of opcodes and variants involved. For any opcode (variable or constant length), only the length minus one is passed on to the ISD node. The rest of the logic is now instead handled during isel pseudo expansion. Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D111729
2021-10-06[SystemZ] Temporarily revert memcmp and memcpy patchesJonas Paulsson
Seem to cause test failures in compiler-rt. Revert "[SystemZ] Implement memcmp of variable length with CLC." This reverts commit 7a4e9a0c73667cb80e4572d41535a9e48f1ed9ef. Revert "[SystemZ] Implement memcpy of variable length with MVC." This reverts commit c6c13c58eebda605a9a05f1f13cac1e46407afc7.
2021-10-05[SystemZ] Implement memcmp of variable length with CLC.Jonas Paulsson
Following the same pattern of memset/memcpy, this patch implements a variable length memcmp with a CLC loop followed by an EXRL instruction. Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D107380
2021-10-05[SystemZ] Implement memcpy of variable length with MVC.Jonas Paulsson
Instead of making a memcpy libcall, emit an MVC loop and an EXRL instruction the same way as is already done for memset 0. Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D106874
2021-07-06[SystemZ] Generate XC loop for memset 0 of variable length.Jonas Paulsson
Benchmarking has shown that it is worthwhile to implement a variable length memset of 0 with XC (exclusive or) like gcc does, instead of using a libcall. This requires the use of the EXecute Relative Long (EXRL) instruction which can now be done in a framework that can also be used with other target instructions (not just XC). Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D103865
2020-09-14[SelectionDAG] Use Align/MaybeAlign in calls to ↵Craig Topper
getLoad/getStore/getExtLoad/getTruncStore. The versions that take 'unsigned' will be removed in the future. I tried to use getOriginalAlign instead of getAlign in some places. getAlign factors in the minimum alignment implied by the offset in the pointer info. Since we're also passing the pointer info we can use the original alignment. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D87592
2020-06-30[Alignment][NFC] Migrate SelectionDAGTargetInfo::EmitTargetCodeForMemcpy to ↵Guillaume Chatelet
Align This patch is part of a series to introduce an Alignment type. See this thread for context: http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html See this patch for the introduction of the type: https://reviews.llvm.org/D64790 Differential Revision: https://reviews.llvm.org/D82849
2020-06-30[Alignment][NFC] Migrate SelectionDAGTargetInfo::EmitTargetCodeForMemset to ↵Guillaume Chatelet
Align This patch is part of a series to introduce an Alignment type. See this thread for context: http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html See this patch for the introduction of the type: https://reviews.llvm.org/D64790 Differential Revision: https://reviews.llvm.org/D82851
2019-09-19Reapply r372285 "GlobalISel: Don't materialize immarg arguments to intrinsics"Matt Arsenault
This reverts r372314, reapplying r372285 and the commits which depend on it (r372286-r372293, and r372296-r372297) This was missing one switch to getTargetConstant in an untested case. llvm-svn: 372338
2019-09-19Revert r372285 "GlobalISel: Don't materialize immarg arguments to intrinsics"Hans Wennborg
This broke the Chromium build, causing it to fail with e.g. fatal error: error in backend: Cannot select: t362: v4i32 = X86ISD::VSHLI t392, Constant:i8<15> See llvm-commits thread of r372285 for details. This also reverts r372286, r372287, r372288, r372289, r372290, r372291, r372292, r372293, r372296, and r372297, which seemed to depend on the main commit. > Encode them directly as an imm argument to G_INTRINSIC*. > > Since now intrinsics can now define what parameters are required to be > immediates, avoid using registers for them. Intrinsics could > potentially want a constant that isn't a legal register type. Also, > since G_CONSTANT is subject to CSE and legalization, transforms could > potentially obscure the value (and create extra work for the > selector). The register bank of a G_CONSTANT is also meaningful, so > this could throw off future folding and legalization logic for AMDGPU. > > This will be much more convenient to work with than needing to call > getConstantVRegVal and checking if it may have failed for every > constant intrinsic parameter. AMDGPU has quite a lot of intrinsics wth > immarg operands, many of which need inspection during lowering. Having > to find the value in a register is going to add a lot of boilerplate > and waste compile time. > > SelectionDAG has always provided TargetConstant for constants which > should not be legalized or materialized in a register. The distinction > between Constant and TargetConstant was somewhat fuzzy, and there was > no automatic way to force usage of TargetConstant for certain > intrinsic parameters. They were both ultimately ConstantSDNode, and it > was inconsistently used. It was quite easy to mis-select an > instruction requiring an immediate. For SelectionDAG, start emitting > TargetConstant for these arguments, and using timm to match them. > > Most of the work here is to cleanup target handling of constants. Some > targets process intrinsics through intermediate custom nodes, which > need to preserve TargetConstant usage to match the intrinsic > expectation. Pattern inputs now need to distinguish whether a constant > is merely compatible with an operand or whether it is mandatory. > > The GlobalISelEmitter needs to treat timm as a special case of a leaf > node, simlar to MachineBasicBlock operands. This should also enable > handling of patterns for some G_* instructions with immediates, like > G_FENCE or G_EXTRACT. > > This does include a workaround for a crash in GlobalISelEmitter when > ARM tries to uses "imm" in an output with a "timm" pattern source. llvm-svn: 372314
2019-09-19GlobalISel: Don't materialize immarg arguments to intrinsicsMatt Arsenault
Encode them directly as an imm argument to G_INTRINSIC*. Since now intrinsics can now define what parameters are required to be immediates, avoid using registers for them. Intrinsics could potentially want a constant that isn't a legal register type. Also, since G_CONSTANT is subject to CSE and legalization, transforms could potentially obscure the value (and create extra work for the selector). The register bank of a G_CONSTANT is also meaningful, so this could throw off future folding and legalization logic for AMDGPU. This will be much more convenient to work with than needing to call getConstantVRegVal and checking if it may have failed for every constant intrinsic parameter. AMDGPU has quite a lot of intrinsics wth immarg operands, many of which need inspection during lowering. Having to find the value in a register is going to add a lot of boilerplate and waste compile time. SelectionDAG has always provided TargetConstant for constants which should not be legalized or materialized in a register. The distinction between Constant and TargetConstant was somewhat fuzzy, and there was no automatic way to force usage of TargetConstant for certain intrinsic parameters. They were both ultimately ConstantSDNode, and it was inconsistently used. It was quite easy to mis-select an instruction requiring an immediate. For SelectionDAG, start emitting TargetConstant for these arguments, and using timm to match them. Most of the work here is to cleanup target handling of constants. Some targets process intrinsics through intermediate custom nodes, which need to preserve TargetConstant usage to match the intrinsic expectation. Pattern inputs now need to distinguish whether a constant is merely compatible with an operand or whether it is mandatory. The GlobalISelEmitter needs to treat timm as a special case of a leaf node, simlar to MachineBasicBlock operands. This should also enable handling of patterns for some G_* instructions with immediates, like G_FENCE or G_EXTRACT. This does include a workaround for a crash in GlobalISelEmitter when ARM tries to uses "imm" in an output with a "timm" pattern source. llvm-svn: 372285
2019-02-06[SystemZ] Do not return INT_MIN from strcmp/memcmpUlrich Weigand
The IPM sequence currently generated to compute the strcmp/memcmp result will return INT_MIN for the "less than zero" case. While this is in compliance with the standard, strictly speaking, it turns out that common applications cannot handle this, e.g. because they negate a comparison result in order to implement reverse compares. This patch changes code to use a different sequence that will result in -2 for the "less than zero" case (same as GCC). However, this requires that the two source operands of the compare instructions are inverted, which breaks the optimization in removeIPMBasedCompare. Therefore, I've removed this (and all of optimizeCompareInstr), and replaced it with a mostly equivalent optimization in combineCCMask at the DAGcombine level. llvm-svn: 353304
2019-01-19Update the file headers across all of the LLVM projects in the monorepoChandler Carruth
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-04-30[SystemZ] Do not use glue to represent condition code dependenciesUlrich Weigand
Currently, an instruction setting the condition code is linked to the instruction using the condition code via a "glue" link in the SelectionDAG. This has a number of drawbacks; in particular, it means the same CC cannot be used by multiple users. It also makes it more difficult to efficiently implement SADDO et. al. This patch changes the back-end to represent CC dependencies as normal values during SelectionDAG matching, along the lines of how this is handled in the X86 back-end already. In addition to the core mechanics of updating all relevant patterns, this requires a number of additional changes: - We now need to be able to spill/restore a CC value into a GPR if necessary. This means providing a copyPhysReg implementation for moves involving CC, and defining getCrossCopyRegClass. - Since we still prefer to avoid such spills, we provide an override for IsProfitableToFold to avoid creating a merged LOAD / ICMP if this would result in multiple users of the CC. - combineCCMask no longer requires a single CC user, and no longer need to be careful about preventing invalid glue/chain cycles. - emitSelect needs to be more careful in marking CC live-in to the basic block it generates. Also, we can now optimize the case of multiple subsequent selects with the same condition just like X86 does. llvm-svn: 331202
2016-07-15[SelectionDAG] Get rid of bool parameters in SelectionDAG::getLoad, ↵Justin Lebar
getStore, and friends. Summary: Instead, we take a single flags arg (a bitset). Also add a default 0 alignment, and change the order of arguments so the alignment comes before the flags. This greatly simplifies many callsites, and fixes a bug in AMDGPUISelLowering, wherein the order of the args to getLoad was inverted. It also greatly simplifies the process of adding another flag to getLoad. Reviewers: chandlerc, tstellarAMD Subscribers: jholewinski, arsenm, jyknight, dsanders, nemanjai, llvm-commits Differential Revision: http://reviews.llvm.org/D22249 llvm-svn: 275592
2016-06-12Pass DebugLoc and SDLoc by const ref.Benjamin Kramer
This used to be free, copying and moving DebugLocs became expensive after the metadata rewrite. Passing by reference eliminates a ton of track/untrack operations. No functionality change intended. llvm-svn: 272512
2015-07-09Remove getDataLayout() from TargetSelectionDAGInfo (had no users)Mehdi Amini
Summary: Remove empty subclass in the process. This change is part of a series of commits dedicated to have a single DataLayout during compilation by using always the one owned by the module. Reviewers: echristo Subscribers: jholewinski, llvm-commits, rafael, yaron.keren, ted Differential Revision: http://reviews.llvm.org/D11045 From: Mehdi Amini <mehdi.amini@apple.com> llvm-svn: 241780
2015-04-28Reapply r235977 "[DebugInfo] Add debug locations to constant SD nodes"Sergey Dmitrouk
[DebugInfo] Add debug locations to constant SD nodes This adds debug location to constant nodes of Selection DAG and updates all places that create constants to pass debug locations (see PR13269). Can't guarantee that all locations are correct, but in a lot of cases choice is obvious, so most of them should be. At least all tests pass. Tests for these changes do not cover everything, instead just check it for SDNodes, ARM and AArch64 where it's easy to get incorrect locations on constants. This is not complete fix as FastISel contains workaround for wrong debug locations, which drops locations from instructions on processing constants, but there isn't currently a way to use debug locations from constants there as llvm::Constant doesn't cache it (yet). Although this is a bit different issue, not directly related to these changes. Differential Revision: http://reviews.llvm.org/D9084 llvm-svn: 235989
2015-04-28Revert "[DebugInfo] Add debug locations to constant SD nodes"Daniel Jasper
This breaks a test: http://bb.pgr.jp/builders/cmake-llvm-x86_64-linux/builds/23870 llvm-svn: 235987
2015-04-28[DebugInfo] Add debug locations to constant SD nodesSergey Dmitrouk
This adds debug location to constant nodes of Selection DAG and updates all places that create constants to pass debug locations (see PR13269). Can't guarantee that all locations are correct, but in a lot of cases choice is obvious, so most of them should be. At least all tests pass. Tests for these changes do not cover everything, instead just check it for SDNodes, ARM and AArch64 where it's easy to get incorrect locations on constants. This is not complete fix as FastISel contains workaround for wrong debug locations, which drops locations from instructions on processing constants, but there isn't currently a way to use debug locations from constants there as llvm::Constant doesn't cache it (yet). Although this is a bit different issue, not directly related to these changes. Differential Revision: http://reviews.llvm.org/D9084 llvm-svn: 235977
2015-02-19Demote vectors to arrays. No functionality change.Benjamin Kramer
llvm-svn: 229861
2015-02-12MathExtras: Bring Count(Trailing|Leading)Ones and CountPopulation in line ↵Benjamin Kramer
with countTrailingZeros Update all callers. llvm-svn: 228930
2014-06-27Have SystemZSelectionDAGInfo constructor take a DataLayout ratherEric Christopher
than a target machine since it doesn't need anything past the DataLayout. llvm-svn: 211870
2014-06-06Have TargetSelectionDAGInfo take a DataLayout initializer rather thanEric Christopher
a TargetMachine since the only thing it wants is DataLayout. llvm-svn: 210366
2014-04-26Convert SelectionDAG::getNode methods to use ArrayRef<SDValue>.Craig Topper
llvm-svn: 207327
2014-04-22[Modules] Fix potential ODR violations by sinking the DEBUG_TYPEChandler Carruth
definition below all of the header #include lines, lib/Target/... edition. llvm-svn: 206842
2014-03-06[SystemZ] Use "auto" for cast resultsRichard Sandiford
No functional change intended. llvm-svn: 203106
2013-10-16[SystemZ] Improve handling of SETCCRichard Sandiford
We previously used the default expansion to SELECT_CC, which in turn would expand to "LHI; BRC; LHI". In most cases it's better to use an IPM-based sequence instead. llvm-svn: 192784
2013-09-06[SystemZ] Use XC for a memset of 0Richard Sandiford
llvm-svn: 190130
2013-08-28[SystemZ] Extend memcmp support to all constant lengthsRichard Sandiford
This uses the infrastructure added for memcpy and memmove in r189331. llvm-svn: 189458
2013-08-27[SystemZ] Extend memcpy and memset support to all constant lengthsRichard Sandiford
Lengths up to a certain threshold (currently 6 * 256) use a series of MVCs. Lengths above that threshold use a loop to handle X*256 bytes followed by a single MVC to handle the excess (if any). This loop will also be needed in future when support for variable lengths is added. Because the same tablegen classes are used to define MVC and CLC, the patch also has the side-effect of defining a pseudo loop instruction for CLC. That instruction isn't used yet (and wouldn't be handled correctly if it were). I'm planning to use it soon though. llvm-svn: 189331
2013-08-20[SystemZ] Use SRST to optimize memchrRichard Sandiford
SystemZTargetLowering::emitStringWrapper() previously loaded the character into R0 before the loop and made R0 live on entry. I'd forgotten that allocatable registers weren't allowed to be live across blocks at this stage, and it confused LiveVariables enough to cause a miscompilation of f3 in memchr-02.ll. This patch instead loads R0 in the loop and leaves LICM to hoist it after RA. This is actually what I'd tried originally, but I went for the manual optimisation after noticing that R0 often wasn't being hoisted. This bug forced me to go back and look at why, now fixed as r188774. We should also try to optimize null checks so that they test the CC result of the SRST directly. The select between null and the SRST GPR result could then usually be deleted as dead. llvm-svn: 188779
2013-08-16[SystemZ] Use SRST to implement strlen and strnlenRichard Sandiford
It would also make sense to use it for memchr; I'm working on that now. llvm-svn: 188547
2013-08-16[SystemZ] Use MVST to implement strcpy and stpcpyRichard Sandiford
llvm-svn: 188546
2013-08-16[SystemZ] Use CLST to implement strcmpRichard Sandiford
llvm-svn: 188544
2013-08-16[SystemZ] Fix sign of integer memcmp resultRichard Sandiford
r188163 used CLC to implement memcmp. Code that compares the result directly against zero can test the CC value produced by CLC, but code that needs an integer result must use IPM. The sequence I'd used was: ipm <reg> sll <reg>, 2 sra <reg>, 30 but I'd forgotten that this inverts the order, so that CC==1 ("less") becomes an integer greater than zero, and CC==2 ("greater") becomes an integer less than zero. This sequence should only be used if the CLC arguments are reversed to compensate. The problem then is that the branch condition must also be reversed when testing the CLC result directly. Rather than do that, I went for a different sequence that works with the natural CLC order: ipm <reg> srl <reg>, 28 rll <reg>, <reg>, 31 One advantage of this is that it doesn't clobber CC. A disadvantage is that any sign extension to 64 bits must be done separately, rather than being folded into the shifts. llvm-svn: 188538
2013-08-12[SystemZ] Use CLC and IPM to implement memcmpRichard Sandiford
For now this is restricted to fixed-length comparisons with a length in the range [1, 256], as for memcpy() and MVC. llvm-svn: 188163
2013-07-09[SystemZ] Use "STC;MVC" for memsetRichard Sandiford
Use "STC;MVC" for memsets that are too big for two STCs or MV...Is yet small enough for a single MVC. As with memcpy, I'm leaving longer cases till later. The number of tests might seem excessive, but f33 & f34 from memset-04.ll failed the first cut because I'd not added the "?:" on the calculation of Size1. llvm-svn: 185918