2721 Commits

Author SHA1 Message Date
Simon Pilgrim
e74520fae6
[DAG] canCreateUndefOrPoison - add handling for ISD::ABS nodes (#148791)
Unlike the abs intrinsic, the ISD::ABS node defines ABS(INT_MIN) -> INT_MIN, so no undef/poison is created by the node itself
2025-07-15 09:31:26 +01:00
woruyu
b22b103c3d
[DAG] SelectionDAG::canCreateUndefOrPoison - add ISD::FCOPYSIGN (#148617)
### Summary
This PR resolves https://github.com/llvm/llvm-project/issues/147694
2025-07-14 15:28:52 +01:00
David Green
0736f330b0
[DAG] Handle truncated splat in isBoolConstant (#145473)
This allows truncated splat / buildvector in isBoolConstant, to allow
certain not instructions to be recognized post-legalization, and allow
vselect to optimize.

An override for x86 avx512 predicated vectors is required to avoid an
infinite recursion from the code that detects zero vectors. From:
```
  // Check if the first operand is all zeros and Cond type is vXi1.
  // If this an avx512 target we can improve the use of zero masking by
  // swapping the operands and inverting the condition.
```
2025-07-10 20:59:34 +01:00
Boyao Wang
697beb3f17
[TargetLowering] Change getOptimalMemOpType and findOptimalMemOpLowering to take LLVM Context (#147664)
Add LLVM Context to getOptimalMemOpType and findOptimalMemOpLowering. So
that we can use EVT::getVectorVT to generate EVT type in
getOptimalMemOpType.

Related to [#146673](https://github.com/llvm/llvm-project/pull/146673).
2025-07-10 11:11:09 +08:00
alex-t
9293b65a61
[AMDGPU] SelectionDAG divergence tracking should take into account Target divergency. (#147560)
This is the next attempt to upstream this:
https://github.com/llvm/llvm-project/pull/144947
The las one caused build errors in AArch64.
Issue was resolved.
2025-07-09 00:06:58 +02:00
woruyu
c80fa2364b
[DAG] SDPatternMatch m_Zero/m_One/m_AllOnes have inconsistent undef h… (#147044)
### Summary
This PR resolves https://github.com/llvm/llvm-project/issues/146871 
This PR resolves https://github.com/llvm/llvm-project/issues/140745

Refactor m_Zero/m_One/m_AllOnes all use struct template function to
match and AllowUndefs=false as default.
2025-07-07 15:04:54 +01:00
Benjamin Maxwell
3277f62344
[SDAG] Remove invalid check (NFC) (#146899)
It does not make sense to do !LC. LC is an RTLIB::Libcall enum, and zero
is a valid value.
2025-07-07 14:42:30 +01:00
Simon Pilgrim
52383956f8
[DAG] Replace DAGCombiner::ConstantFoldBITCASTofBUILD_VECTOR with SelectionDAG::FoldConstantBuildVector (#147037)
DAGCombiner can already constant fold build vectors of constants/undefs
to a new vector type, but it has to be incredibly careful after
legalization to not affect a target's canonicalized constants.

This patch proposes we move the implementation inside SelectionDAG to
make it easier for targets to manually use the constant folding whenever
it deems it safe to do so.

I've also altered the method to take the BuildVectorSDNode input
directly and consistently use the same SDLoc.
2025-07-07 10:44:03 +01:00
Austin
a550fef906
[llvm] Use llvm::fill instead of std::fill(NFC) (#146911)
Use llvm::fill instead of std::fill
2025-07-04 14:10:28 +08:00
Florian Hahn
bfd457588a
Revert "[AMDGPU] SelectionDAG divergence tracking should take into account Target divergency. (#144947)"
This reverts commit 8ac7210b7f0ad49ae7809bf6a9faf2f7433384b0.

This breaks the building the AArch64 backend, e.g. see
https://github.com/llvm/llvm-project/pull/144947

Revert to unbreak the build.

Also reverts follow-up commits 1e76f012db3ccfaa05e238812e572b5b6d12c17e.
2025-07-03 19:25:01 +01:00
alex-t
8ac7210b7f
[AMDGPU] SelectionDAG divergence tracking should take into account Target divergency. (#144947)
If a kernel is known to be executing only a single lane, IR
UniformityAnalysis will take note of that (via
GCNTTIImpl::hasBranchDivergence) and report that all values are uniform.
SelectionDAG's built-in divergence tracking should do the same.
2025-07-03 18:37:37 +02:00
Simon Pilgrim
72f87d2d69
[DAG] canCreateUndefOrPoison - remove isGuaranteedNotToBeUndefOrPoison check for insert/extract vector element indices (#146514)
No longer necessary now that #146490 has landed
2025-07-01 14:01:54 +01:00
Simon Pilgrim
89fe429262
[DAG] canCreateUndefOrPoison - remove isGuaranteedNotToBeUndefOrPoison check for shift nodes (#146502)
No longer necessary now that #146490 has landed - we still have the test coverage from #94145 that covers this.
2025-07-01 12:44:59 +01:00
Simon Pilgrim
56841565db
[DAG] canCreateUndefOrPoison - add handling for CTTZ/CTLZ_ZERO_UNDEF nodes (#146501)
CTTZ/CTLZ_ZERO_UNDEF nodes can only create poison if the source value is zero - so check with isKnownNeverZero

Pulled out of #146361 and reapplied now that #146490 has landed.
2025-07-01 12:44:45 +01:00
Simon Pilgrim
a97826a13b
[DAG] canCreateUndefOrPoison - explicitly state the AssertSext/Zext/Align/NoFPClass can create poison. NFC. (#146493)
This keeps getting forgotten (e.g. #66603) - so make a point of adding
it here to make it clear instead of relying on the implicit default of
returning true.
2025-07-01 11:31:47 +01:00
Simon Pilgrim
529508c187
[DAG] canCreateUndefOrPoison - add handling for CTTZ/CTLZ nodes (#146361)
ISD::CTTZ/CTLZ nodes handle all input values and do not create undef/poison.

The *_ZERO_UNDEF variants will be handled in a future patch.
2025-06-30 17:48:05 +01:00
Simon Pilgrim
b9e4679976
[DAG] canCreateUndefOrPoison - add handling for ADD/SUB/MUL overflow nodes (#146322)
Neither the arithmetic value or overflow result can create undef/poison from regular operands values.

We have complete test coverage for all ADDO/SUBO nodes, 32-bit codegen handles the _CARRY variants but until #145939 lands AND DAGCombiner::visitFREEZE handles multiple results we can't see any codegen change.

Pulled out of #145939
2025-06-30 13:26:57 +01:00
Craig Topper
9df1c81fee
[SelectionDAG] Combine range metadata when loads are CSEd. (#146026)
When CSEing a load with an existing load with different range
metadata, clear the range metadata on the existing
load.

This is conservative, alternatively we could calculate new range
metadata using MDNode::getMostGenericRange. Without a test case I wasn't
sure it was worth it.

MDnode::getMostGenericRange takes a non-const MDNode*, but all of
SelectionDAG
uses const MDNode*. A const_cast will need to be used somewhere or
we need to make the codebase consistent about whether MDNode pointers
should be const or not.

I'm sure this isn't the only place that needs to be updated to handle
the CSE.
    
Fixes #145363.
2025-06-27 08:58:06 -07:00
Simon Pilgrim
7dde6027a0
[DAG] canCreateUndefOrPoison - add handling for ISD::SELECT (#146046)
Followup to #143760 which handled ISD::VSELECT

I've moved ISD::SELECT/VSELECT under the "No poison except from flags
(which is handled above)" subgroup to try to remind people that these
can have poison generating FMFs (NINF/NNAN), even though this hasn't
been well explained anywhere I can find :(

Helps with regressions from #145939
2025-06-27 11:49:08 +01:00
Matt Arsenault
a65e0edd6a
PowerPC: Stop reporting memcpy as an alias of memmove on AIX (#143836)
Instead of reporting ___memmove as an implementation of memcpy,
make it unavailable and let the lowering logic consider memmove as
a fallback path.

This avoids a special case 1:N mapping for libcall implementations.
2025-06-23 22:15:37 +09:00
Craig Topper
5eb24fde11
[SelectionDAG][RISCV] Preserve nneg flag when folding (trunc (zext X))->(zext X). (#144807)
If X is known non-negative, that's still true if we fold the truncate
to create a smaller zext.
    
In the i128 tests, SelectionDAGBuilder aggressively truncates the
`zext nneg` to i64 to match `getShiftAmountTy`. If we don't preserve
the `nneg` we can't see that the shift amount argument being `signext`
means we don't need to do any extension
2025-06-19 08:06:07 -07:00
Craig Topper
ad9e591fd5
[SelectionDAG][RISCV] Fold (add (vscale * C0), (vscale * C1)) to (vscale * (C0 + C1)) in getNode. (#144565)
We already have shl/mul vscale related folds in getNode.

This is an alternative to the DAGCombine proposed in #144507.
2025-06-17 21:33:50 -07:00
Craig Topper
e7e491f6ee
[SelectionDAG] Add ISD::VSELECT to SelectionDAG::canCreateUndefOrPoison. (#143760) 2025-06-11 13:06:22 -07:00
Simon Pilgrim
bb531ffccc
[DAG] getNode - assert that INSERT_VECTOR_ELT operand types are legal (#143502)
Helped track down a typo in the X86ISD::CVTPH2PS lowering.
2025-06-10 13:51:12 +01:00
Philip Reames
939666380f
[SDAG] Add partial_reduce_sumla node (#141267)
We have recently added the partial_reduce_smla and partial_reduce_umla
nodes to represent Acc += ext(b) * ext(b) where the two extends have to
have the same source type, and have the same extend kind.

For riscv64 w/zvqdotq, we have the vqdot and vqdotu instructions which
correspond to the existing nodes, but we also have vqdotsu which
represents the case where the two extends are sign and zero respective
(i.e. not the same type of extend).

This patch adds a partial_reduce_sumla node which has sign extension for
A, and zero extension for B. The addition is somewhat mechanical.
2025-06-09 07:17:45 -07:00
Nikita Popov
d74831efeb Revert "[SDAG] Fix fmaximum legalization errors (#142170)"
This reverts commit 58cc1675ec7b4aa5bc2dab56180cb7af1b23ade5.

I also made the incorrect assumption that we know both values are
+/-0.0 here as well. Revert for now.
2025-06-04 14:35:30 +02:00
Harrison Hao
0107c9333c
[DAG] canCreateUndefOrPoison – mark fneg/fadd/fsub/fmul/fdiv/frem as not poison generating (#142345)
After revisiting the LLVM Language Reference Manual, it is confirmed
that
plain floating-point operations (`fneg`, `fadd`, `fsub`, `fmul`, `fdiv`,
and `frem`)
propagate poison but do not inherently create new poison values. Thus, 
`SelectionDAG::canCreateUndefOrPoison` should return `false` for these 
operations by default.

Poison generation in FP instructions occurs only when specific fast-math
flags (`nnan`, `ninf`, or the collective fast) are present, as these
flags
explicitly convert NaN or Inf results into poison.

References:

- [`fneg` instruction
documentation](https://llvm.org/docs/LangRef.html#fneg-instruction)
- [`fadd` instruction
documentation](https://llvm.org/docs/LangRef.html#fadd-instruction)
- [`fsub` instruction
documentation](https://llvm.org/docs/LangRef.html#fsub-instruction)
- [`fmul` instruction
documentation](https://llvm.org/docs/LangRef.html#fmul-instruction)
- [`fdiv` instruction
documentation](https://llvm.org/docs/LangRef.html#fdiv-instruction)
- [`frem` instruction
documentation](https://llvm.org/docs/LangRef.html#frem-instruction)
- [Fast-Math Flags
documentation](https://llvm.org/docs/LangRef.html#fast-math-flags)
2025-06-03 19:21:40 +08:00
Nikita Popov
58cc1675ec
[SDAG] Fix fmaximum legalization errors (#142170)
FMAXIMUM is currently legalized via IS_FPCLASS for the signed zero
handling. This is problematic, because it assumes the equivalent integer
type is legal. Many targets have legal fp128, but illegal i128, so this
results in legalization failures.

Fix this by replacing IS_FPCLASS with checking the bitcast to integer
instead. In that case it is sufficient to use any legal integer type, as
we're just interested in the sign bit. This can be obtained via a stack
temporary cast. There is existing FloatSignAsInt functionality used for
legalization of FABS and similar we can use for this purpose.

Fixes https://github.com/llvm/llvm-project/issues/139380.
Fixes https://github.com/llvm/llvm-project/issues/139381.
Fixes https://github.com/llvm/llvm-project/issues/140445.
2025-06-02 10:14:33 +02:00
Fabian Ritter
8adcc8a669
[SelectionDAG] Introduce ISD::PTRADD (#140017)
This opcode represents the addition of a pointer value (first operand)
and an integer offset (second operand). PTRADD nodes are only generated
if the TargetMachine opts in by overriding
TargetMachine::shouldPreservePtrArith().

The PTRADD node and respective visitPTRADD() function were adapted by
@rgwott from the CHERI/Morello LLVM tree.
Original authors: @davidchisnall, @jrtc27, @arichardson.

The changes in this PR were extracted from PR #105669.

---------

Co-authored-by: David Chisnall <github@theravensnest.org>
Co-authored-by: Jessica Clarke <jrtc27@jrtc27.com>
Co-authored-by: Alexander Richardson <alexrichardson@google.com>
Co-authored-by: Rodolfo Wottrich <rodolfo.wottrich@arm.com>
2025-05-28 09:09:17 +02:00
Kazu Hirata
3bc174ba77
[CodeGen] Remove unused includes (NFC) (#141320)
These are identified by misc-include-cleaner.  I've filtered out those
that break builds.  Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
2025-05-24 00:00:00 -07:00
Benjamin Maxwell
c9d6249198
[SDAG] Ensure load is included in output chain of sincos expansion (#140525)
The load not being included in the chain meant that it could materialize
after a `@llvm.lifetime.end` annotation on the pointer. This could
result in miscompiles if the stack slot is reused for another value.

Fixes https://github.com/llvm/llvm-project/issues/140491
2025-05-20 10:43:50 +01:00
Liam Semeria
d067014f13
[APInt] Added APInt::clearBits() method (#137098)
Added APInt::clearBits(unsigned loBit, unsigned hiBit) that clears bits within a certain range.

Fixes #136550

---------

Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
2025-05-19 12:41:04 +01:00
Kazu Hirata
9658c55116 [SelectionDAG] Fix a warning
This patch fixes:

  llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:7506:17: error:
  unused variable 'NoFPClass' [-Werror,-Wunused-variable]
2025-05-15 07:05:33 -07:00
YunQiang Su
780054d3ff
CodeGen: Add ISD::AssertNoFPClass (#138839)
It is used to mark a value that we are sure that it is not some fcType.
The examples include:

  * An arguments of a function is marked with nofpclass
  * Output value of an intrinsic can be sure to not be some type

So that the following operation can make some assumptions.
2025-05-15 16:05:15 +08:00
Philip Reames
80370465d9
[DAG] Add wrappers for insert_vector_elt and extract_vector_elt [nfc] (#139141)
As with the recently added subvector variants, provide the unsigned
index operand to simplify a bunch of code.

---------

Co-authored-by: Luke Lau <luke_lau@icloud.com>
2025-05-09 06:37:58 -07:00
Philip Reames
6e654caabe
[DAG] Add wrappers for insert and extract sub-vector [nfc] (#137230)
Mechanical change to introduce the new wrappers, and add enough users to
make the usage pattern clear. Once this lands, I'm going to do a further
pass to adjust more callsites as separate changes.

---------

Co-authored-by: Luke Lau <luke_lau@icloud.com>
2025-05-08 06:49:37 -07:00
Alexander Peskov
cffb8aee14
[DEBUGINFO] Propagate debug metadata for sext SDNode. (#135971)
In some cases of chained `sext` operators the debug metadata can be
missed. This patch propagates proper metadata to resulting node.

Particular case of issue is NVPTX codegen for function with bool local
variable:
```
void test(int i) {
  bool xyz = i == 0;
  foo(i);
}
```

---------

Signed-off-by: Alexander Peskov <apeskov@nvidia.com>
2025-05-02 08:31:41 -04:00
Jonathan Thackray
6e49f73825
Reland [llvm] Add support for llvm IR atomicrmw fminimum/fmaximum instructions (#137701)
This patch adds support for LLVM IR atomicrmw `fmaximum` and `fminimum`
instructions.

These mirror the `llvm.maximum.*` and `llvm.minimum.*` instructions, but
are atomic and use IEEE754 2019 handling for NaNs, which is different to
`fmax` and `fmin`. See:
     https://llvm.org/docs/LangRef.html#llvm-minimum-intrinsic
for more details.

Future changes will allow this LLVM IR to be lowered to specialised
assembler instructions on suitable targets, such as AArch64.
2025-04-30 22:06:37 +01:00
YunQiang Su
db859db74d Revert "CodeGen: Add ISD::AssertNoFPClass (#135946)"
This reverts commit f0c61d2242bbc7576ca5e4137a5ea8f63e4859a9.
2025-04-30 16:16:26 +08:00
Jonathan Thackray
7ee0097b48
Revert "[llvm] Add support for llvm IR atomicrmw fminimum/fmaximum instructions" (#137657)
Reverts llvm/llvm-project#136759 due to bad interaction with c792b25e4
2025-04-28 16:53:36 +01:00
Jonathan Thackray
ba420d8122
[llvm] Add support for llvm IR atomicrmw fminimum/fmaximum instructions (#136759)
This patch adds support for LLVM IR atomicrmw `fmaximum` and `fminimum`
instructions.

These mirror the `llvm.maximum.*` and `llvm.minimum.*` instructions, but
are atomic and use IEEE754 2019 handling for NaNs, which is different to
`fmax` and `fmin`. See:
     https://llvm.org/docs/LangRef.html#llvm-minimum-intrinsic
for more details.

Future changes will allow this LLVM IR to be lowered to specialised
assembler instructions on suitable targets, such as AArch64.
2025-04-28 15:31:44 +01:00
Craig Topper
e17f07c4de
[SelectionDAG] Reduce code duplication between getStore, getTruncStore, and getIndexedStore. (#137435)
Create an extra overload of getStore that can handle of the 3 types of
stores. This is similar to how getLoad/getExtLoad/getIndexLoad is
structure.
2025-04-27 22:32:53 -07:00
Jie Fu
46f91173c5 [CodeGen] Fix -Wunused-variable in SelectionDAG.cpp (NFC)
/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:7502:17:
 error: unused variable 'NoFPClass' [-Werror,-Wunused-variable]
    FPClassTest NoFPClass = static_cast<FPClassTest>(N2->getAsZExtVal());
                ^
1 error generated.
2025-04-25 14:03:09 +08:00
YunQiang Su
f0c61d2242
CodeGen: Add ISD::AssertNoFPClass (#135946)
It is used to mark a value that we are sure that it is not some fcType.
The examples include:
  * An arguments of a function is marked with nofpclass
  * Output value of an intrinsic can be sure to not be some type

So that the following operation can make some assumptions.

---------

Co-authored-by: Your Name <you@example.com>
2025-04-25 09:12:41 +08:00
Craig Topper
f261f1406d
[SelectionDAG][RISCV] Teach computeKnownBits to use range metadata for atomic_load. (#137119)
And teach SelectionDAGBuilder to get the range metadata in
visitAtomicLoad.

This allows us to recognize that sign extending a byte load of a
boolean value from memory will produce zeros for the extended bits.
This allow us to remove an AND on RISC-V.

Tests copied from #136502 with range metadata added to i1 cases.
Some of the test effects overlap with #136502, but that patch can't
handle the acquire or seq_cst cases with the Zalasr extension. We
only have sign extending versions of those loads.
2025-04-24 12:14:05 -07:00
Craig Topper
dbb0605f87 [SelectionDAG] Add NewSDValueDbgMsg to getAtomic. 2025-04-23 22:56:52 -07:00
Peter Collingbourne
dbb8434ff7
SelectionDAG: Add missing AddNodeIDCustom case for MDNodeSDNode.
Without this we ended up never deduplicating MDNodeSDNodes.

Reviewers: arsenm

Reviewed By: arsenm

Pull Request: https://github.com/llvm/llvm-project/pull/136805
2025-04-23 11:00:48 -07:00
zhijian lin
afda4c295b
Reland [SelectionDAG] Folding ZERO-EXTEND/SIGN_EXTEND poison to Poison value in getNode (#136701)
This patch addresses the signed/zero extension of poison by using a
poison value of the extended type instead of a constant zero of the
extended type.
2025-04-22 17:36:41 -04:00
Craig Topper
f6178cdad0
[SelectionDAG] Pass LoadExtType when ATOMIC_LOAD is created. (#136653)
Rename one signature of getAtomic to getAtomicLoad and pass LoadExtType.
Previously we had to set the extension type after the node was created,
but we don't usually modify SDNodes once they are created. It's possible
the node already existed and has been CSEd. If that happens, modifying
the node may affect the other users. It's therefore safer to add the
extension type at creation so that it is part of the CSE information.

I don't know of any failures related to the current implementation. I
only noticed that it doesn't match how we usually do things.
2025-04-22 09:11:46 -07:00
Craig Topper
497382ee07
[SelectionDAG] Make the FoldingSet profile in getAtomic match AddNodeIDCustom. (#136651)
In theory, the mismatch would have made CSE of AtomicSDNodes not work,
but I don't know how to test it.
2025-04-21 22:39:31 -07:00