194 Commits

Author SHA1 Message Date
Juan Manuel Martinez Caamaño
04c56505f8
[NFC][LLVM] Make constrainSelectedInstRegOperands return void (#179501)
`constrainSelectedInstRegOperands` always returns `true`; so it can be
safely transformed to return `void` instead.

A follow-up patch should update `MachineInstrBuilder::constrainAllUses`.
2026-02-04 08:59:16 +01:00
Stefan Weigl-Bosker
828261ebb8
[GISel] Add G_CTLS Opcode and combines, lower to cls(w) (#175069)
Fixes https://github.com/llvm/llvm-project/issues/174369

- Added a G_CTLS opcode and some pattern matching. This is the
GlobalISel equivalent to
https://github.com/llvm/llvm-project/pull/173417
- Add legalization for aarch64 and riscv

```
// Folds (ctlz (xor x, (sra x, bitwidth-1))) -> (add (ctls x), 1). 
// Folds (ctlz (or (shl (xor x, (sra x, bitwidth-1)), 1), 1) -> (ctls x) (clang aarch64)
```
2026-01-16 13:22:18 -08:00
Joel Fuentes
42dc78f945
[GlobalISel] Fix FCMP constant folding in presence trunc/zext/sext chain (#171878)
The instruction combine ``canonicalize_fcmp`` tries to fold constant
values in fcmp, however, it fails when the source defs have different FP
types. This occurs because it uses
``getFConstantVRegValWithLookThrough`` to get the constants value def,
even through trunc, zext, or sext.

Related to #171856
2025-12-19 19:12:18 +00:00
Petar Avramovic
25b6a15dfd
GlobalISel: Stop using TPC to check if GlobalISelAbort is enabled (#169917)
New pass manager does not use TargetPassConfig.
GlobalISel requires TargetPassConfig to reportGISelFailure,
and it only actual use is to check if GlobalISelAbort is enabled.
TargetPassConfig uses TargetMachine to check if GlobalISelAbort is
enabled, but TargetMachine is also available from MachineFunction.
2025-12-02 17:12:10 +01:00
Lewis Crawford
ea3fdc5972
Avoid maxnum(sNaN, x) optimizations / folds (#170181)
The behaviour of constant-folding `maxnum(sNaN, x)` and `minnum(sNaN,
x)` has become controversial, and there are ongoing discussions about
which behaviour we want to specify in the LLVM IR LangRef.

See:
  - https://github.com/llvm/llvm-project/issues/170082
  - https://github.com/llvm/llvm-project/pull/168838
  - https://github.com/llvm/llvm-project/pull/138451
  - https://github.com/llvm/llvm-project/pull/170067
-
https://discourse.llvm.org/t/rfc-a-consistent-set-of-semantics-for-the-floating-point-minimum-and-maximum-operations/89006

This patch removes optimizations and constant-folding support for
`maxnum(sNaN, x)` but keeps it folded/optimized for `qNaN`. This should
allow for some more flexibility so the implementation can conform to
either the old or new version of the semantics specified without any
changes.

As far as I am aware, optimizations involving constant `sNaN` should
generally be edge-cases that rarely occur, so here should hopefully be
very little real-world performance impact from disabling these
optimizations.
2025-12-02 12:43:03 +00:00
Matt Arsenault
55422e804b
CodeGen: Remove TRI argument from getRegClass (#158225)
TargetInstrInfo now directly holds a reference to TargetRegisterInfo
and does not need TRI passed in anywhere.
2025-11-10 15:43:55 -08:00
David Green
215aca4432
[GlobalISel] SBFX/UBFX does not create poison (#165675)
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-31 09:18:07 +00:00
paperchalice
f98b955f7c
[GlobalIsel] Remove NoNaNsFPMath uses (#163484)
Users should use `nnan` instead.
This is the GlobalIsel part.
2025-10-16 09:58:44 +08:00
Matt Arsenault
7289f2cd0c
CodeGen: Remove MachineFunction argument from getRegClass (#158188)
This is a low level utility to parse the MCInstrInfo and should
not depend on the state of the function.
2025-09-12 19:22:02 +09:00
Abhishek Kaushik
1278ac71d3
[NFC][GlobalISel] Pass APInt by const reference (#157827)
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 11:11:14 +05:30
Shaoce SUN
41d7ae84e5
[RISCV][GlobalIsel] Lower G_FMINIMUMNUM, G_FMAXIMUMNUM (#157295)
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-09-11 10:16:42 +08:00
Victor Mustya
6a5cb5afdc
[GISel] Fix crash in GlobalISel utils method (#153334)
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-25 12:59:01 -07:00
AZero13
f94290cbff
[ValueTracking][GlobalISel] UCMP and SCMP cannot create undef or poison (#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-20 08:41:27 +09:00
jyli0116
961a4aabf8
[GlobalISel] Add constant matcher for APInt (#151357)
Changed m_SpecificICst, m_SpecificICstSplat and m_SpecificICstorSplat to
match against APInt as well.
2025-08-04 09:47:21 +01:00
Matt Arsenault
7e2e030121
GlobalISel: Replace use of report_fatal_error (#145866) 2025-06-27 21:16:23 +09:00
Guy David
4d4b7cc69e
[AArch64] Skip storing of stack arguments when lowering tail calls (#126735)
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-06-06 11:26:24 +03:00
Rahul Joshi
1fdf02ad5a
[LLVM][CodeGen] Add convenience accessors for MachineFunctionProperties (#140002)
Add per-property has<Prop>/set<Prop>/reset<Prop> functions to
MachineFunctionProperties.
2025-05-22 08:07:52 -07:00
KRM7
0926d94453
[GlobalISel] Take the result size into account when const folding icmp (#134365)
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-05-05 19:01:53 +02:00
Paul Walker
d7f3c31293 Reapply "[LLVM][ISel][AArch64 Remove AArch64ISD::FCM##z nodes. (#135817)"
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-24 12:44:41 +00:00
Paul Walker
427b6448a3 Revert "[LLVM][ISel][AArch64 Remove AArch64ISD::FCM##z nodes. (#135817)"
This reverts commit 15d8b3cae9debc2bd7d27ca92ff599ba9fb30da5.
2025-04-24 09:48:54 +00:00
Paul Walker
15d8b3cae9
[LLVM][ISel][AArch64 Remove AArch64ISD::FCM##z nodes. (#135817)
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-04-23 11:29:42 +01:00
Tim Gymnich
1d0005a69a
[GlobalISel][NFC] Rename GISelKnownBits to GISelValueTracking (#133466)
- rename `GISelKnownBits` to `GISelValueTracking` to analyze more than
just `KnownBits` in the future
2025-03-29 11:51:29 +01:00
Min-Yih Hsu
3cac26f541
[GISel] Combine (neg (min/max x, (neg x))) into (max/min x, (neg x)) (#120998)
This is the GISel version of #120666. Also supports both unsigned and
signed version of min & max.
2025-01-02 16:29:34 -08:00
Vikash Gupta
c21a3776c9
[GlobalIsel] [Utility] [NFC] Added isConstantOrConstantSplatVectorFP to handle float constants. (#120935)
Needed for #120104
2024-12-26 18:57:19 +05:30
Tim Gymnich
2db2dc8ab9
[GlobalISel][NFC] Fix LLT Propagation (#119587)
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-12-12 09:47:46 -08:00
Kazu Hirata
5b19ed8bb4
[llvm] Migrate away from PointerUnion::{is,get,dyn_cast} (NFC) (#115626)
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-11-10 07:24:06 -08:00
Craig Topper
f0bae562dc
[GISel] Return const APInt & from getIConstantFromReg. NFC (#114320)
This matches what the call to ConstantInt::getValue() returns. Let the
caller make a copy if needed.
2024-10-30 19:15:51 -07:00
Ellis Hoag
9cc5a4bf66
Remove llvm::shouldOptForSize() from Utils.h (#112630)
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-29 14:23:47 -05:00
Ellis Hoag
6ab26eab4f
Check hasOptSize() in shouldOptimizeForSize() (#112626) 2024-10-28 09:45:03 -07:00
Tex Riddell
c03d09ce3e
[aarch64] atan2 intrinsic lowering (p5) (#112611)
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-10-24 17:53:12 -07:00
Thorsten Schütt
acfa294b5e
[GlobalIsel] Canonicalize G_FCMP (#108891)
As a side-effect, we start constant folding fcmps.
2024-09-17 09:42:04 +02:00
Thorsten Schütt
5c348f692a
[GlobalIsel] Canonicalize G_ICMP (#108755)
As a side-effect, we start constant folding icmps.

Split out from https://github.com/llvm/llvm-project/pull/105991.
2024-09-16 19:25:34 +02:00
Tobias Stadler
2d338bed00
[CodeGen] Refactor DeadMIElim isDead and GISel isTriviallyDead (#105956)
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-09-09 16:30:44 +02:00
Stephen Tozer
3d08ade7bd
[ExtendLifetimes] Implement llvm.fake.use to extend variable lifetimes (#86149)
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-29 17:53:32 +01:00
Thorsten Schütt
6b77531123
[GlobalIsel] Combine G_ADD and G_SUB with constants (#97771) 2024-08-09 20:14:32 +02:00
Pengcheng Wang
ed4e75d5e5
[CodeGen] Remove AA parameter of isSafeToMove (#100691)
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-26 15:47:47 +08:00
Thorsten Schütt
e8734e49e4
[GlobalIsel] Improve poison analysis (#93731) 2024-07-12 19:39:50 +02:00
Farzon Lotfi
0b58f34c98
[X86][CodeGen] Add base trig intrinsic lowerings (#96222)
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-07-11 15:58:43 -04:00
Nikita Popov
f2f18459d4 Revert "Intrinsic: introduce minimumnum and maximumnum (#93841)"
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-21 08:34:04 +02:00
YunQiang Su
8988148003
Intrinsic: introduce minimumnum and maximumnum (#93841)
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-21 11:53:08 +08:00
Christudasan Devadasan
27bebc1161
[GISel] Unify multiple instances of getTypeForLLT (NFC) (#95577)
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-15 18:11:32 +05:30
Farzon Lotfi
1d87433593
[x86] Add tan intrinsic part 4 (#90503)
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-06-05 15:01:33 -04:00
Thorsten Schütt
6d90ac1e06
[GlobalIsel] Combine freeze (#93239) 2024-05-29 18:05:33 +02:00
Dhruv Chawla
4c48b3cb5c
[GISel][CombinerHelper] Push freeze through non-poison-producing operands (#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-23 13:45:52 +05:30
Pierre van Houtryve
922fafaff8
[GlobalISel] Micro-optimize getConstantVRegValWithLookThrough (#91969)
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-05-14 08:26:00 +02:00
Thorsten Schütt
bc349cea7a
[GlobalIsel] combine insert vector element (#89363)
preliminary steps
poison symbols
2024-04-27 08:39:35 +02:00
Malay Sanghi
92e96c7bba
[X86][GISel] Add DU chain lookups for LOAD & STORE (#87453)
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-04-16 13:06:17 +02:00
Shilei Tian
3a106e5b2c
[GlobalISel] Fold G_ICMP if possible (#86357)
This patch tries to fold `G_ICMP` if possible.
2024-03-29 15:59:50 -04:00
Shilei Tian
0a4299403e
[GlobalISel] Fold G_CTTZ if possible (#86224)
This patch tries to fold `G_CTTZ` if possible.
2024-03-25 16:55:37 -04:00
Jay Foad
430de48a61 [GISel] Simplify getConstantVRegValWithLookThrough. NFC. 2024-03-08 12:26:43 +00:00