aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/GlobalISel/Utils.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-06-27GlobalISel: Replace use of report_fatal_error (#145866)Matt Arsenault1-1/+1
2025-06-06[AArch64] Skip storing of stack arguments when lowering tail calls (#126735)Guy David1-0/+11
This issue starts in the selection DAG and causes the backend to emit the following for a trivial tail call: ``` ldr w8, [sp] str w8, [sp] b func ``` I'm not too sure that checking for immutability of a specific stack object is a good enough of a gurantee, because as soon a tail-call is done lowering,`setHasTailCall()` is called and in that case perhaps a pass is allowed to change the value of the object in-memory? This can be extended to the ARM backend as well. Removed the `tailcall` keyword from a few other test assets, I'm assuming their original intent was left intact.
2025-05-22[LLVM][CodeGen] Add convenience accessors for MachineFunctionProperties ↵users/pcc/spr/main.elf-add-branch-to-branch-optimizationRahul Joshi1-1/+1
(#140002) Add per-property has<Prop>/set<Prop>/reset<Prop> functions to MachineFunctionProperties.
2025-05-05[GlobalISel] Take the result size into account when const folding icmp (#134365)KRM71-17/+28
The current implementation always creates a 1 bit constant for the result of the `G_ICMP`, which will cause issues if the destination register size is larger than that. With asserts enabled, it will cause a crash in `buildConstant`: ``` llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp:322: virtual MachineInstrBuilder llvm::MachineIRBuilder::buildConstant(const DstOp &, const ConstantInt &): Assertion `EltTy.getScalarSizeInBits() == Val.getBitWidth() && "creating constant with the wrong size"' failed. ```
2025-04-24Reapply "[LLVM][ISel][AArch64 Remove AArch64ISD::FCM##z nodes. (#135817)"Paul Walker1-1/+2
This reverts commit 427b6448a3af009e57c0142d6d8af83318b45093. Original patch has been updated to include a fix to esnure AArch64InstructionSelector::emitConstantVector supports all the cases where isBuildVectorAllOnes returns true.
2025-04-24Revert "[LLVM][ISel][AArch64 Remove AArch64ISD::FCM##z nodes. (#135817)"Paul Walker1-2/+1
This reverts commit 15d8b3cae9debc2bd7d27ca92ff599ba9fb30da5.
2025-04-23[LLVM][ISel][AArch64 Remove AArch64ISD::FCM##z nodes. (#135817)Paul Walker1-1/+2
We can easily select compare-to-zero instructions without dedicated nodes. The test changes show opportunities that were previous missed because of the redundant complexity.
2025-03-29[GlobalISel][NFC] Rename GISelKnownBits to GISelValueTracking (#133466)Tim Gymnich1-5/+5
- rename `GISelKnownBits` to `GISelValueTracking` to analyze more than just `KnownBits` in the future
2025-01-02[GISel] Combine `(neg (min/max x, (neg x)))` into `(max/min x, (neg x))` ↵Min-Yih Hsu1-0/+15
(#120998) This is the GISel version of #120666. Also supports both unsigned and signed version of min & max.
2024-12-26[GlobalIsel] [Utility] [NFC] Added isConstantOrConstantSplatVectorFP to ↵Vikash Gupta1-0/+12
handle float constants. (#120935) Needed for #120104
2024-12-12[GlobalISel][NFC] Fix LLT Propagation (#119587)Tim Gymnich1-2/+1
Retain LLT type information by creating new LLTs from the original LLT instead of only using the original scalar size. This PR prepares for the [LLT FPInfo RFC](https://discourse.llvm.org/t/rfc-globalisel-adding-fp-type-information-to-llt/83349/24) where LLTs will carry additional floating point type information in addition to the scalar size.
2024-11-10[llvm] Migrate away from PointerUnion::{is,get,dyn_cast} (NFC) (#115626)Kazu Hirata1-2/+2
Note that PointerUnion::{is,get,dyn_cast} have been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T>
2024-10-30[GISel] Return const APInt & from getIConstantFromReg. NFC (#114320)Craig Topper1-1/+2
This matches what the call to ConstantInt::getValue() returns. Let the caller make a copy if needed.
2024-10-29Remove llvm::shouldOptForSize() from Utils.h (#112630)Ellis Hoag1-5/+0
Remove `llvm::shouldOptForSize()` from `Utils.h` since we can use `llvm::shouldOptimizeForSize()` from `SizeOpts.h` instead. Depends on https://github.com/llvm/llvm-project/pull/112626
2024-10-28Check hasOptSize() in shouldOptimizeForSize() (#112626)Ellis Hoag1-3/+1
2024-10-24[aarch64] atan2 intrinsic lowering (p5) (#112611)Tex Riddell1-0/+2
This change is part of this proposal: https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294 - `VecFuncs.def`: define intrinsic to sleef/armpl mapping - `LegalizerHelper.cpp`: add missing fewerElementsVector handling for the new atan2 intrinsic - `AArch64ISelLowering.cpp`: Add arch64 specializations for lowering like neon instructions - `AArch64LegalizerInfo.cpp`: Legalize atan2. Part 5 for Implement the atan2 HLSL Function #70096.
2024-09-17[GlobalIsel] Canonicalize G_FCMP (#108891)Thorsten Schütt1-0/+40
As a side-effect, we start constant folding fcmps.
2024-09-16[GlobalIsel] Canonicalize G_ICMP (#108755)Thorsten Schütt1-0/+40
As a side-effect, we start constant folding icmps. Split out from https://github.com/llvm/llvm-project/pull/105991.
2024-09-09[CodeGen] Refactor DeadMIElim isDead and GISel isTriviallyDead (#105956)Tobias Stadler1-23/+4
Merge GlobalISel's isTriviallyDead and DeadMachineInstructionElim's isDead code and remove all unnecessary checks from the hot path by looping over the operands before doing any other checks. See #105950 for why DeadMIElim needs to remove LIFETIME markers even though they probably shouldn't generally be considered dead. x86 CTMark O3: -0.1% AArch64 GlobalISel CTMark O0: -0.6%, O2: -0.2%
2024-08-29[ExtendLifetimes] Implement llvm.fake.use to extend variable lifetimes (#86149)Stephen Tozer1-0/+3
This patch is part of a set of patches that add an `-fextend-lifetimes` flag to clang, which extends the lifetimes of local variables and parameters for improved debuggability. In addition to that flag, the patch series adds a pragma to selectively disable `-fextend-lifetimes`, and an `-fextend-this-ptr` flag which functions as `-fextend-lifetimes` for this pointers only. All changes and tests in these patches were written by Wolfgang Pieb (@wolfy1961), while Stephen Tozer (@SLTozer) has handled review and merging. The extend lifetimes flag is intended to eventually be set on by `-Og`, as discussed in the RFC here: https://discourse.llvm.org/t/rfc-redefine-og-o1-and-add-a-new-level-of-og/72850 This patch implements a new intrinsic instruction in LLVM, `llvm.fake.use` in IR and `FAKE_USE` in MIR, that takes a single operand and has no effect other than "using" its operand, to ensure that its operand remains live until after the fake use. This patch does not emit fake uses anywhere; the next patch in this sequence causes them to be emitted from the clang frontend, such that for each variable (or this) a fake.use operand is inserted at the end of that variable's scope, using that variable's value. This patch covers everything post-frontend, which is largely just the basic plumbing for a new intrinsic/instruction, along with a few steps to preserve the fake uses through optimizations (such as moving them ahead of a tail call or translating them through SROA). Co-authored-by: Stephen Tozer <stephen.tozer@sony.com>
2024-08-09[GlobalIsel] Combine G_ADD and G_SUB with constants (#97771)Thorsten Schütt1-0/+7
2024-07-26[CodeGen] Remove AA parameter of isSafeToMove (#100691)Pengcheng Wang1-1/+1
This `AA` parameter is not used and for most uses they just pass a nullptr. The use of `AA` was removed since 8d0383e.
2024-07-12[GlobalIsel] Improve poison analysis (#93731)Thorsten Schütt1-1/+53
2024-07-11[X86][CodeGen] Add base trig intrinsic lowerings (#96222)Farzon Lotfi1-0/+12
This change is an implementation of https://github.com/llvm/llvm-project/issues/87367's investigation on supporting IEEE math operations as intrinsics. Which was discussed in this RFC: https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294 This change adds constraint intrinsics and some lowering cases for `acos`, `asin`, `atan`, `cosh`, `sinh`, and `tanh`. The only x86 specific change was for f80. https://github.com/llvm/llvm-project/issues/70079 https://github.com/llvm/llvm-project/issues/70080 https://github.com/llvm/llvm-project/issues/70081 https://github.com/llvm/llvm-project/issues/70083 https://github.com/llvm/llvm-project/issues/70084 https://github.com/llvm/llvm-project/issues/95966 The x86 lowering is going to be done in three pr changes with this being the first. A second PR will be put up for Loop Vectorizing and then SLPVectorizer. The constraint intrinsics is also going to be in multiple parts, but just 2. This part covers just the llvm specific changes, part2 will cover clang specifc changes and legalization for backends than have special legalization requirements like aarch64 and wasm.
2024-06-21Revert "Intrinsic: introduce minimumnum and maximumnum (#93841)"Nikita Popov1-9/+1
As far as I can tell, this pull request was not approved, and did not go through an RFC on discourse. This reverts commit 89881480030f48f83af668175b70a9798edca2fb. This reverts commit 225d8fc8eb24fb797154c1ef6dcbe5ba033142da.
2024-06-21Intrinsic: introduce minimumnum and maximumnum (#93841)YunQiang Su1-1/+9
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compare sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86: Returns NUM but not same with IEEE754-2019's minimumNumber as +0.0 is not always greater than -0.0. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: #93033
2024-06-15[GISel] Unify multiple instances of getTypeForLLT (NFC) (#95577)Christudasan Devadasan1-0/+7
Multiple static instances of this utility function have been found in different GlobalISel files. Unifying them by adding an instance in utils.cpp.
2024-06-05[x86] Add tan intrinsic part 4 (#90503)Farzon Lotfi1-0/+2
This change is an implementation of #87367's investigation on supporting IEEE math operations as intrinsics. Which was discussed in this RFC: https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294 Much of this change was following how G_FSIN and G_FCOS were used. Changes: - `llvm/docs/GlobalISel/GenericOpcode.rst` - Document the `G_FTAN` opcode - `llvm/docs/LangRef.rst` - Document the tan intrinsic - `llvm/include/llvm/Analysis/VecFuncs.def` - Associate the tan intrinsic as a vector function similar to the tanf libcall. - `llvm/include/llvm/CodeGen/BasicTTIImpl.h` - Map the tan intrinsic to `ISD::FTAN` - `llvm/include/llvm/CodeGen/ISDOpcodes.h` - Define ISD opcodes for `FTAN` and `STRICT_FTAN` - `llvm/include/llvm/IR/Intrinsics.td` - Create the tan intrinsic - `llvm/include/llvm/IR/RuntimeLibcalls.def` - Define tan libcall mappings - `llvm/include/llvm/Target/GenericOpcodes.td` - Define the `G_FTAN` Opcode - `llvm/include/llvm/Support/TargetOpcodes.def` - Create a `G_FTAN` Opcode handler - `llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td` - Map `G_FTAN` to `ftan` - `llvm/include/llvm/Target/TargetSelectionDAG.td` - Define `ftan`, `strict_ftan`, and `any_ftan` and map them to the ISD opcodes for `FTAN` and `STRICT_FTAN` - `llvm/lib/Analysis/VectorUtils.cpp` - Associate the tan intrinsic as a vector intrinsic - `llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp` Map the tan intrinsic to `G_FTAN` Opcode - `llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp` - Add `G_FTAN` to the list of floating point math operations also associate `G_FTAN` with the `TAN_F` runtime lib. - `llvm/lib/CodeGen/GlobalISel/Utils.cpp` - More floating point math operation common behaviors. - llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp - List the function expansion operations for `FTAN` and `STRICT_FTAN`. Also define both opcodes in `PromoteNode`. - `llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp` - More `FTAN` and `STRICT_FTAN` handling in the legalizer - `llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h` - Define `SoftenFloatRes_FTAN` and `ExpandFloatRes_FTAN`. - `llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp` - Define `FTAN` as a legal vector operation. - `llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp` - Define `FTAN` as a legal vector operation. - `llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp` - define tan as an intrinsic that doesn't return NaN. - `llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp` Map `LibFunc_tan`, `LibFunc_tanf`, and `LibFunc_tanl` to `ISD::FTAN`. Map `Intrinsic::tan` to `ISD::FTAN` and add selection dag handling for `Intrinsic::tan`. - `llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp` - Define `ftan` and `strict_ftan` names for the equivalent ISD opcodes. - `llvm/lib/CodeGen/TargetLoweringBase.cpp` -Define a Tan128 libcall and ISD::FTAN as a target lowering action. - `llvm/lib/Target/X86/X86ISelLowering.cpp` - Add x86_64 lowering for tan intrinsic resolves https://github.com/llvm/llvm-project/issues/70082
2024-05-29[GlobalIsel] Combine freeze (#93239)Thorsten Schütt1-10/+92
2024-05-23[GISel][CombinerHelper] Push freeze through non-poison-producing operands ↵Dhruv Chawla1-3/+21
(#90618) This combine matches the existing fold in InstCombine, i.e. InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating. It tries to push freeze through an operand if the operand has only one maybe-poison operand and all other operands are guaranteed non-poison, and if the operation itself cannot generate poison (eg. add with nsw can generate poison, even with non-poison operands). This is beneficial because it can potentially enable other optimizations to occur that would otherwise be blocked because of the freeze.
2024-05-14[GlobalISel] Micro-optimize getConstantVRegValWithLookThrough (#91969)Pierre van Houtryve1-32/+44
I was benchmarking the MatchTable when I found that `getConstantVRegValWithLookThrough` took a non-negligible amount of time, about 7.5% of all of `AArch64PreLegalizerCombinerImpl::tryCombineAll`. I decided to take a closer look to see if I could squeeze some performance out of it, and I landed on a few changes that: - Avoid copying APint unnecessarily, especially returning std::optional<APInt> can be expensive when a out parameter also works. - Avoid indirect call by using templated function pointers instead of function_ref/std::function Both of those changes seem to speedup this function by about 50%, but my benchmarking (`perf record`) seems inconsistent (so take measurements with a grain of salt), I saw as high as 4.5% and as low as 2% for this function on the exact same input after the changes, but it never got close again to 7% in a few runs so this looks like a stable improvement.
2024-04-27[GlobalIsel] combine insert vector element (#89363)Thorsten Schütt1-0/+83
preliminary steps poison symbols
2024-04-16[X86][GISel] Add DU chain lookups for LOAD & STORE (#87453)Malay Sanghi1-0/+44
For G_LOAD and G_STORE we want this information during regbankselect. Today we treat load dest as integer and insert converts. --------- Co-authored-by: Evgenii Kudriashov <evgenii.kudriashov@intel.com>
2024-03-29[GlobalISel] Fold G_ICMP if possible (#86357)Shilei Tian1-0/+68
This patch tries to fold `G_ICMP` if possible.
2024-03-25[GlobalISel] Fold G_CTTZ if possible (#86224)Shilei Tian1-2/+3
This patch tries to fold `G_CTTZ` if possible.
2024-03-08[GISel] Simplify getConstantVRegValWithLookThrough. NFC.Jay Foad1-6/+5
2024-02-22[GlobalISel] Constant-fold G_PTR_ADD with different type sizes (#81473)Pierre van Houtryve1-1/+4
All other opcodes in the list are constrained to have the same type on both operands, but not G_PTR_ADD. Fixes #81464
2024-02-07[GISel] Add support for scalable vectors in getGCDType (#80307)Michael Maitland1-29/+40
This function can be called from buildCopyToRegs where at least one of the types is a scalable vector type. This function crashed because it did not know how to handle scalable vector types. This patch extends the functionality of getGCDType to handle when at least one of the types is a scalable vector. getGCDType between a fixed and scalable vector is not implemented since the docstring of the function explains that getGCDType is used to build MERGE/UNMERGE instructions and we will never build a MERGE/UNMERGE between fixed and scalable vectors. --------- Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2024-02-06[GISel] Add support for scalable vectors in getLCMType (#80306)Michael Maitland1-32/+53
This function can be called from buildCopyToRegs where at least one of the types is a scalable vector type. This function crashed because it did not know how to handle scalable vector types. This patch extends the functionality of getLCMType to handle when at least one of the types is a scalable vector. getLCMType between a fixed and scalable vector is not implemented since the docstring of the function explains that getLCMType is used to build MERGE/UNMERGE instructions and we will never build a MERGE/UNMERGE between fixed and scalable vectors.
2024-02-02[GISEL] More accounting for scalable vectors when operating on LLTs (#80372)Michael Maitland1-2/+8
This is stacked on by #80377 and #80378
2024-01-15[GlobalISel] Refactor extractParts() (#75223)chuongg31-0/+147
Moved extractParts() and extractVectorParts() from LegalizerHelper to Utils to be able to use it in different passes. extractParts() will also try to use unmerge when doing irregular splits where possible, falling back to extract elements when not.
2023-11-14GlobalISel: Guard return in llvm::getIConstantSplatVal (#71989)Changpeng Fang1-3/+3
getIConstantVRegValWithLookThrough could return NULL.
2023-11-04Revert "[GISel] Add LookThroughInstrs for getIConstantVRegVal and ↵Craig Topper1-7/+5
getIConstan… (#68327)" This reverts commit 28ae42e6625154dfd164803850b15d8a0c296b94. The assert in getIConstantVRegVal was not updated for this change. The ValAndVReg->VReg == VReg check fails if any look through happens. RISC-V was the only target using the lookthrough functionality, but I'm not sure it was needed so I'm removing that too.
2023-10-20[GISel] Add LookThroughInstrs for getIConstantVRegVal and getIConstan… ↵Michael Maitland1-5/+7
(#68327) …tVRegSExtVal The implementation of these methods uses getIConstantVRegValWithLookThrough with LookThroughInstrs argument set to false. By adding the optional argument to getIConstantVRegVal and getIConstantVRegSExtVal we can take advantage of the already built look through functionality.
2023-09-22Use llvm::drop_begin and llvm::drop_end (NFC)Kazu Hirata1-1/+1
2023-08-24GlobalISel: Add constant fold combine for zext/sext/anyextMatt Arsenault1-0/+23
Could use more work for vectors. https://reviews.llvm.org/D156534
2023-08-16[AArch64][GISel] Fix selection of G_CONSTANT_FOLD_BARRIERDavid Green1-2/+9
As far as I understand - When lowering a G_CONSTANT_FOLD_BARRIER we replace the DstReg with SrcReg, and need to check that the register class is equivalent when doing so for the replacement to be legal. During lowering we could end up visiting nodes in an odd order, leaving a G_CONSTANT_FOLD_BARRIER with a known regclass for the src, but only a regbank for the dst. Providing the Regbank contains the regclass, the replacement should still be safe. This fixes an assert seen in the llvm-test-suite when lowering hoisted constants, relaxing canReplaceReg to account for the case when the regbank covers the regclass, so it is better able to handle differences in visiting order. Differential Revision: https://reviews.llvm.org/D157202
2023-06-01[CodeGen] Make use of MachineInstr::all_defs and all_uses. NFCI.Jay Foad1-4/+1
Differential Revision: https://reviews.llvm.org/D151424
2023-04-17[nfc][llvm] Replace pointer cast functions in PointerUnion by llvm casting ↵Shraiysh Vaishay1-2/+2
functions. This patch replaces the uses of PointerUnion.is function by llvm::isa, PointerUnion.get function by llvm::cast, and PointerUnion.dyn_cast by llvm::dyn_cast_if_present. This is according to the FIXME in the definition of the class PointerUnion. This patch does not remove them as they are being used in other subprojects. Reviewed By: mehdi_amini Differential Revision: https://reviews.llvm.org/D148449
2023-02-19Use APInt::count{l,r}_{zero,one} (NFC)Kazu Hirata1-1/+1