summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/GlobalISel/Utils.cpp
AgeCommit message (Collapse)Author
2025-11-10CodeGen: Remove TRI argument from getRegClass (#158225)Matt Arsenault
TargetInstrInfo now directly holds a reference to TargetRegisterInfo and does not need TRI passed in anywhere.
2025-10-31[GlobalISel] SBFX/UBFX does not create poison (#165675)David Green
This adds G_SBFX/G_UBFX to the list of instructions that do not generate poison, to allowing freeze to be hoisted above one.
2025-10-16[GlobalIsel] Remove NoNaNsFPMath uses (#163484)paperchalice
Users should use `nnan` instead. This is the GlobalIsel part.
2025-09-12CodeGen: Remove MachineFunction argument from getRegClass (#158188)Matt Arsenault
This is a low level utility to parse the MCInstrInfo and should not depend on the state of the function.
2025-09-11[NFC][GlobalISel] Pass `APInt` by const reference (#157827)Abhishek Kaushik
Change `SpecificConstantMatch` constructor and `isBuildVectorConstantSplat` overloads to take `const APInt&` instead of by value to avoid unnecessary copies, especially for wide integers.
2025-09-11[RISCV][GlobalIsel] Lower G_FMINIMUMNUM, G_FMAXIMUMNUM (#157295)Shaoce SUN
Similar to the implementation in https://github.com/llvm/llvm-project/pull/104411 , the `fmin.s`/`fmax.s` instructions follow IEEE 754-2019 semantics, and `G_FMINIMUMNUM`/`G_FMAXIMUMNUM` are legal.
2025-08-25[GISel] Fix crash in GlobalISel utils method (#153334)Victor Mustya
The `getDefSrcRegIgnoringCopies` method in GlobalISel Utils crashed when the first operand of the input instruction was not a register, e.g., the `INLINEASM` instruction has a non-register first operand. --------- Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-08-20[ValueTracking][GlobalISel] UCMP and SCMP cannot create undef or poison ↵AZero13
(#154404) They cannot make poison or undef, same for IR. They can only make -1, 0, or 1 Alive 2: https://alive2.llvm.org/ce/z/--Jd78
2025-08-04[GlobalISel] Add constant matcher for APInt (#151357)jyli0116
Changed m_SpecificICst, m_SpecificICstSplat and m_SpecificICstorSplat to match against APInt as well.
2025-06-27GlobalISel: Replace use of report_fatal_error (#145866)Matt Arsenault
2025-06-06[AArch64] Skip storing of stack arguments when lowering tail calls (#126735)Guy David
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 Joshi
(#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)KRM7
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 Walker
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 Walker
This reverts commit 15d8b3cae9debc2bd7d27ca92ff599ba9fb30da5.
2025-04-23[LLVM][ISel][AArch64 Remove AArch64ISD::FCM##z nodes. (#135817)Paul Walker
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 Gymnich
- 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 Hsu
(#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 Gupta
handle float constants. (#120935) Needed for #120104
2024-12-12[GlobalISel][NFC] Fix LLT Propagation (#119587)Tim Gymnich
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 Hirata
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 Topper
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 Hoag
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 Hoag
2024-10-24[aarch64] atan2 intrinsic lowering (p5) (#112611)Tex Riddell
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ütt
As a side-effect, we start constant folding fcmps.
2024-09-16[GlobalIsel] Canonicalize G_ICMP (#108755)Thorsten Schütt
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 Stadler
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 Tozer
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ütt
2024-07-26[CodeGen] Remove AA parameter of isSafeToMove (#100691)Pengcheng Wang
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ütt
2024-07-11[X86][CodeGen] Add base trig intrinsic lowerings (#96222)Farzon Lotfi
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 Popov
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 Su
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 Devadasan
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 Lotfi
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ütt
2024-05-23[GISel][CombinerHelper] Push freeze through non-poison-producing operands ↵Dhruv Chawla
(#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 Houtryve
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ütt
preliminary steps poison symbols
2024-04-16[X86][GISel] Add DU chain lookups for LOAD & STORE (#87453)Malay Sanghi
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 Tian
This patch tries to fold `G_ICMP` if possible.
2024-03-25[GlobalISel] Fold G_CTTZ if possible (#86224)Shilei Tian
This patch tries to fold `G_CTTZ` if possible.
2024-03-08[GISel] Simplify getConstantVRegValWithLookThrough. NFC.Jay Foad
2024-02-22[GlobalISel] Constant-fold G_PTR_ADD with different type sizes (#81473)Pierre van Houtryve
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 Maitland
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 Maitland
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 Maitland
This is stacked on by #80377 and #80378
2024-01-15[GlobalISel] Refactor extractParts() (#75223)chuongg3
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.