4049 Commits

Author SHA1 Message Date
Craig Topper
97ad0f4b3d
[DAGCombiner][RISCV] Don't propagate the exact flag from udiv/sdiv to urem/srem. (#145387)
If we simplify a udiv/sdiv using the exact flag we shouldn't
propagate that simplifaction to any urem/srem that happens to
use the same operands. If the exact flag is wrong, the udiv/sdiv
will produce poison, but that doesn't mean we can make the urem/srem
simplify to 0.
    
Fixes #145360.
2025-06-23 14:29:17 -07:00
Kazu Hirata
76ae9aa4d2
[CodeGen] Use range-based for loops (NFC) (#145251) 2025-06-22 19:09:38 -07:00
Iris Shi
f2eb5d416e
[SelectionDAG] Handle fneg/fabs/fcopysign in SimplifyDemandedBits (#139239) 2025-06-22 22:48:59 +08:00
Simon Pilgrim
c734377544 [DAG] foldMaskedMerge - fix Wparentheses operator precedence warning. NFC. 2025-06-20 16:20:28 +01: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
woruyu
0018921148
[DAG] add (~a | x) & (a | y) -> (a & (x ^ y)) ^y for foldMaskedMerge (#144342)
### Summary
This PR resolves https://github.com/llvm/llvm-project/issues/143864

Add (~a | x) & (a | y) -> (a & (x ^ y)) ^y for foldMaskedMerge func
using SDPatternMatch

aftering adding this pattern, run ```ninja check-llvm-codegen```, all
other cases remain unchanged, so I add a
testcase(fold-masked-merge-demorgan.ll) for it

---------

Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
2025-06-18 17:22:53 +01:00
Rajveer Singh Bharadwaj
e07b1b26c3
[DAG] Implement SDPatternMatch m_Abs() matcher (#144512) 2025-06-18 12:59:27 +05:30
Simon Pilgrim
71f72f4d5d [DAG] Move foldMaskedMerge before visitAND. NFC.
Reduces diff in #144342
2025-06-17 11:21:56 +01:00
Xu Zhang
7c25db3fbf
[DAG] Fold (and X, (add (not Y), Z)) -> (and X, (not (sub Y, Z))). (#141476)
Fixes #140639

---------

Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
2025-06-16 15:55:26 +01:00
woruyu
41c8df147b
[DAG] Convert foldMaskedMerge to SDPatternMatch to match (m & x) | (~m & y) (#143855)
This PR resolves https://github.com/llvm/llvm-project/issues/143363

Remove foldMaskedMergeImpl entirely to use SDPatternMatch
2025-06-12 13:46:07 +01:00
Iris Shi
24d730b380
Reland "[SelectionDAG] Make (a & x) | (~a & y) -> (a & (x ^ y)) ^ y available for all targets" (#143651) 2025-06-11 15:56:37 +08:00
Iris Shi
8c890eaa3f
Revert "[SelectionDAG] Make (a & x) | (~a & y) -> (a & (x ^ y)) ^ y available for all targets" (#143648) 2025-06-11 10:19:12 +08:00
Matt Arsenault
505c550e4c
DAG: Assert fcmp uno runtime calls are boolean values (#142898)
This saves 2 instructions in the ARM soft float case for fcmp ueq.

This code is written in an confusingly overly general way. The point
of getCmpLibcallCC is to express that the compiler-rt implementations
of the FP compares are different aliases around functions which may
return -1 in some cases. This does not apply to the call for unordered,
which returns a normal boolean.

Also stop overriding the default value for the unordered compare for ARM.
This was setting it to the same value as the default, which is now assumed.
2025-06-10 10:46:29 +09: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
Iris Shi
bfb48363b0
[SelectionDAG] Make (a & x) | (~a & y) -> (a & (x ^ y)) ^ y available for all targets (#137641) 2025-06-09 17:57:15 +08:00
Harrison Hao
102dfa8a48
[DAGCombiner] Allow freeze to sink through fmul by adding it to AllowMultipleMaybePoisonOperands (#142250)
Allow freeze to sink through fmul by treating it as a
non-poison-generating op
when operands are not poison.

Adding `ISD::FMUL` to `AllowMultipleMaybePoisonOperands` lets DAG
combine
push freeze through fmul. This helps expose patterns like `fmul+fadd`
for `FMA` fusion.

When rebuilding the node, we drop flags like nnan/ninf/nsz that imply
poison,
but keep contract, reassoc, afn, and arcp.


Closes: https://github.com/llvm/llvm-project/issues/141622
2025-06-08 19:38:57 +08:00
AZero13
7730853fa1
[SelectionDAG] Use DAG.getSelect (NFC) (#143276) 2025-06-08 10:27:10 +09:00
Craig Topper
b4b3be7faa
[DAGCombiner] Teach SearchForAndLoads to handle an AND with 2 constant operands. (#142062)
If opaque constants are involved we can have an AND with 2 constant
operands that hasn't been simplified. If this is the case, we need
to modify at least one of the constants if it is out of range.
    
Fixes #142004
2025-05-30 16:00:43 -07:00
Craig Topper
c5a17e6bea
[DAGCombiner] Use APInt::isSubsetOf. NFC (#142029) 2025-05-30 09:01:36 -07:00
Philip Reames
1651aa2943
[SDAG] Split the partial reduce legalize table by opcode [nfc] (#141970)
On it's own, this change should be non-functional. This is a preparatory
change for https://github.com/llvm/llvm-project/pull/141267 which adds a
new form of PARTIAL_REDUCE_*MLA. As noted in the discussion on that
review, AArch64 needs a different set of legal and custom types for the
PARTIAL_REDUCE_SUMLA variant than the currently existing
PARTIAL_REDUCE_UMLA/SMLA.
2025-05-29 14:05:31 -07:00
Nicholas Guy
a5d97ebe8b
[AArch64][SelectionDAG] Add type legalization for partial reduce wide adds (#141075)
Based on work initially done by @JamesChesterman.
2025-05-29 14:42:23 +01:00
Marius Kamp
10647685ca
[SDAG] Make Select-with-Identity-Fold More Flexible; NFC (#136554)
This change adds new parameters to the method
`shouldFoldSelectWithIdentityConstant()`. The method now takes the
opcode of the select node and the non-identity operand of the select
node. To gain access to the appropriate arguments, the call of
`shouldFoldSelectWithIdentityConstant()` is moved after all other checks
have been performed. Moreover, this change adjusts the precondition of
the fold so that it would work for `SELECT` nodes in addition to
`VSELECT` nodes.
    
No functional change is intended because all implementations of
`shouldFoldSelectWithIdentityConstant()` are adjusted such that they
restrict the fold to a `VSELECT` node; the same restriction as before.
    
The rationale of this change is to make more fine grained decisions
possible when to revert the InstCombine canonicalization of
`(select c (binop x y) y)` to `(binop (select c x idc) y)` in the
backends.
2025-05-29 09:46:39 +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
Paul Walker
5dfaf8418d
[LLVM][AArch64] Correctly lower funnel shifts by constants. (#140058)
Prevent LowerFunnelShift from creating an invalid ISD::FSHR when
lowering "ISD::FSHL X, Y, 0". Such inputs are rare because it's a NOP
that DAGCombiner will optimise away. However, we should not rely on this
and so this PR mirrors the same optimisation.
    
Ensure LowerFunnelShift normalises constant shift amounts because isel
rules expect them to be in the range [0, src bit length).
    
NOTE: To simiplify testing, this PR also adds a command line option to
disable the DAG combiner (-combiner-disabled).
2025-05-20 11:15:21 +01:00
David Green
b95ad8eca6
[DAGCombine] Use isLegalExtLoad for MatchLoadCombine (#140536)
This looks wrong to me, but I don't have a test case where it alters the
generated code.
2025-05-20 09:59:41 +01:00
Piotr Fusik
9e22f9611a
[DAGCombiner] Fix a "subtraction if above a constant threshold" miscompile (#140042)
This fixes #135194 incorrectly reusing the existing `add nuw/nsw`
while the transformed code relies on an unsigned wrap.
2025-05-17 12:18:52 +02:00
Craig Topper
dcd62f3674
[SelectionDAG] Rename MemSDNode::getOriginalAlign to getBaseAlign. NFC (#139930)
This matches the underlying function in MachineMemOperand and how it is
printed when BaseAlign differs from Align.
2025-05-16 09:37:02 -07:00
Pierre van Houtryve
5e7bc5e080
[DAGCombiner] Remove hasOneUse check from sext+sext_inreg to sext_inreg combine (#140207)
The hasOneUseCheck does not really add anything and makes the combine too
restrictive. Upcoming patches benefit from removing the hasOneUse check.
2025-05-16 10:25:49 +02:00
Alexander Peskov
2bc9f43ba1
[DAGCombiner] Fold pattern for srl-shl-zext (REAPPLIED) (#140038)
Fold (srl (lop x, (shl (zext y), c1)), c1) -> (lop (srl x, c1), (zext y)) where c1 <= leadingzeros(zext(y)).

This is equivalent of existing fold chain (srl (shl (zext y), c1), c1) -> (and (zext y), mask) -> (zext y), but logical op in the middle prevents it from combining.

Profit : Allow to reduce the number of instructions.

Original commit: #138290 / bbc5221

Previously reverted due to conflict in LIT test. Mainline changed
default version of load instruction to untyped version by this #137698 .
Updated test uses `ld.param.b64` instead of `ld.param.u64`.
2025-05-15 18:04:33 +01:00
Simon Pilgrim
ca912c7c08
Revert bbc5221c95343d8d6869dce83d6fcf183767bd9f "[DAGCombiner] Fold pattern for srl-shl-zext" (#139876)
Reverts llvm/llvm-project#138290 due to buildbot failures in shift-opt.ll
2025-05-14 12:13:54 +01:00
Alexander Peskov
bbc5221c95
[DAGCombiner] Fold pattern for srl-shl-zext (#138290)
Fold `(srl (lop x, (shl (zext y), c1)), c1) -> (lop (srl x, c1), (zext y))` where c1 <= leadingzeros(zext(y)).

This is equivalent of existing fold chain `(srl (shl (zext y), c1), c1) -> (and (zext y), mask) -> (zext y)`, but logical op in the middle prevents it from combining.

Profit : Allow to reduce the number of instructions.

---------

Signed-off-by: Alexander Peskov <apeskov@nvidia.com>
2025-05-14 11:57:55 +01:00
AZero13
af6261b50b
[DAG] visitINSERT_VECTOR_ELT - convert to or mask if all insertions are -1 (#138213)
We did this for 0 and and, but we can do this with or and -1.

Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
2025-05-13 17:10:54 +01:00
Philip Reames
cf2f558501 [DAG/RISCV] Continue mitgrating to getInsertSubvector and getExtractSubvector
Follow up to 6e654caab, use the new routines in more places.  Note that
I've excluded from this patch any case which uses a getConstant index
instead of a getVectorIdxConstant index just to minimize room for
error.  I'll get those in a separate follow up.
2025-05-08 09:40:45 -07:00
Nicholas Guy
a8ed244178
[DAGCombiner] Add DAG combine for PARTIAL_REDUCE_MLA when no mul op (#131326)
Generic DAG combine for ISD::PARTIAL_REDUCE_U/SMLA to convert:
PARTIAL_REDUCE_*MLA(Acc, ZEXT(UnextOp1), Splat(1)) into
PARTIAL_REDUCE_UMLA(Acc, UnextOp1, TRUNC(Splat(1))) and
PARTIAL_REDUCE_*MLA(Acc, SEXT(UnextOp1), Splat(1)) into
PARTIAL_REDUCE_SMLA(Acc, UnextOp1, TRUNC(Splat(1))).

---------

Co-authored-by: James Chesterman <james.chesterman@arm.com>
2025-05-06 16:54:39 +01:00
Sander de Smalen
d90cac9641
[DAGCombine] Simplify partial_reduce_*mla with constant. (#138289)
partial_reduce_*mla(acc, mul(ext(x), splat(C)), splat(1))
-> partial_reduce_*mla(acc, x, C)
2025-05-06 13:51:52 +01:00
Simon Pilgrim
bde39d7251
[DAG] Add SDPatternMatch::m_BitwiseLogic common matcher for AND/OR/XOR nodes (#138301) 2025-05-06 12:50:50 +01:00
Kazu Hirata
aa15596b5f
[llvm] Remove unused local variables (NFC) (#138478) 2025-05-04 21:33:54 -07:00
Kazu Hirata
c51a3aa6ce
[llvm] Remove unused local variables (NFC) (#138467) 2025-05-04 13:05:18 -07:00
Simon Pilgrim
b5dbddd200
[DAG] visitEXTRACT_SUBVECTOR - change fold helper methods to take operands instead of EXTRACT_SUBVECTOR node. NFC. (#138279)
Call with the individual subvector type, source vector and index operands instead of the original EXTRACT_SUBVECTOR node.

Some of these folds still assumed that EXTRACT_SUBVECTOR/INSERT_SUBVECTOR nodes could have variable indices, despite us moving to all constant indices some time ago - all of that code has now been simplified.

I've moved the narrowExtractedVectorBinOp call higher up, but it won't affect fold order - it didn't rely on the peekThroughBitcasts call, and worked on BinOps, not BUILD_VECTOR/INSERT_SUBVECTOR nodes.

Prep work to make it easier for more of these folds to work through BITCAST nodes.
2025-05-02 17:24:56 +01:00
John Brawn
dd87127f4e
[DAGCombiner] Eliminate fp casts if we have the right fast math flags (#131345)
When floating-point operations are legalized to operations of a higher
precision (e.g. f16 fadd being legalized to f32 fadd) then we get
narrowing then widening operations between each operation. With the
appropriate fast math flags (nnan ninf contract) we can eliminate these
casts.
2025-04-28 11:21:51 +01:00
Simon Pilgrim
10f6c3e270
[DAG] visitCONCAT_VECTORS - relax legality checks (#137210)
We can fold combineConcatVectorOfConcatVectors/combineConcatVectorOfExtracts until after vector legalization
2025-04-24 19:08:06 +01:00
Simon Pilgrim
79151244d6
[DAG] narrowExtractedVectorLoad - reuse existing SDLoc. NFC (#136870) 2025-04-23 16:50:06 +01:00
Nicholas Guy
a1f369e630
[AArch64][SVE] Add dot product lowering for PARTIAL_REDUCE_MLA node (#130933)
Add lowering in tablegen for PARTIAL_REDUCE_U/SMLA ISD nodes. Only
happens when the combine has been performed on the ISD node. Also adds
in check to only do the DAG combine when the node can then eventually be
lowered, so changes neon tests too.

---------

Co-authored-by: James Chesterman <james.chesterman@arm.com>
2025-04-23 13:19:41 +01:00
Simon Pilgrim
a99e055030
[DAG] shouldReduceLoadWidth - add optional<unsigned> byte offset argument (#136723)
Based off feedback for #129695 - we need to be able to determine the
load offset of smaller loads when trying to determine whether a multiple
use load should be split (in particular for AVX subvector extractions).

This patch adds a std::optional<unsigned> ByteOffset argument to
shouldReduceLoadWidth calls for where we know the constant offset to
allow targets to make use of it in future patches.
2025-04-23 12:30:27 +01:00
Luke Lau
8204931038
[RISCV] Add disjoint or patterns for vwadd[u].v{v,x} (#136716)
DAGCombiner::hoistLogicOpWithSameOpcodeHands will hoist

(or disjoint (ext a), (ext b)) -> (ext (or disjoint a, b))

So this adds patterns to match vwadd[u].v{v,x} in this case.

We have to teach the combine to preserve the disjoint flag.
2025-04-23 15:17:04 +08: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
Iris
2b71269388
[SelectionDAG][X86] Fold sub(x, mul(divrem(x,y)[0], y)) to divrem(x, y)[1] (#136565)
Closes #51823.
2025-04-22 20:57:03 +08:00
Kazu Hirata
81b4fc2bed
[CodeGen] Construct SmallVector with ArrayRef (NFC) (#135930)
Note that we can drop the call to reserve because the constructor that
takes ArrayRef calls append, which in turn calls reserve.
2025-04-16 08:37:56 -07:00
Alex MacLean
1bfd444628
[DAGCombiner] Fold and/or of NaN SETCC (#135645)
Fold an AND or OR of two NaN SETCC nodes into a single SETCC where
possible. This optimization already exists in InstCombine but adding in
here as well can allow for additional folding if more logical operations
are exposed.
2025-04-16 06:48:42 -07:00
Craig Topper
8ed397d8e4
[DAGCombiner] Disable narrowExtractedVectorLoad for indexed loads. (#135847)
The later code does not expect or preserve the index output.

Fixes #135821
2025-04-15 14:58:15 -07:00