3868 Commits

Author SHA1 Message Date
Kazu Hirata
f4fb735840
[llvm] Construct SmallVector<SDValue> with ArrayRef (NFC) (#102578) 2024-08-09 09:15:42 -07:00
Simon Pilgrim
ad00e8a8dd [DAG] Replace m_SpecificInt(1) -> m_One()
For SDPatternMatch there's no difference in undef/poison vector element handling - in fact m_One() just wraps m_SpecificInt(1)
2024-08-08 18:20:46 +01:00
Simon Pilgrim
13d04fa560 [DAG] Add legalization handling for ABDS/ABDU (#92576) (REAPPLIED)
Always match ABD patterns pre-legalization, and use TargetLowering::expandABD to expand again during legalization.

abdu(lhs, rhs) -> sub(xor(sub(lhs, rhs), usub_overflow(lhs, rhs)), usub_overflow(lhs, rhs))
Alive2: https://alive2.llvm.org/ce/z/dVdMyv

REAPPLIED: Fix regression issue with "abs(ext(x) - ext(y)) -> zext(abd(x, y))" fold failing after type legalization
2024-08-08 11:39:05 +01:00
Simon Pilgrim
e4e96b3e26 Revert b1234ddbe2652aa7948242a57107ca7ab12fd2f8. "[DAG] Add legalization handling for ABDS/ABDU (#92576)"
Reverting #92576 while we identify a reported regression
2024-08-07 17:11:25 +01:00
Simon Pilgrim
6e60d549d4 [DAG] Add foldSelectToABD helper. NFC.
Pull out of visitVSELECT to allow reuse in the future.
2024-08-06 13:31:53 +01:00
Simon Pilgrim
b1234ddbe2
[DAG] Add legalization handling for ABDS/ABDU (#92576)
Always match ABD patterns pre-legalization, and use TargetLowering::expandABD to expand again during legalization.

abdu(lhs, rhs) -> sub(xor(sub(lhs, rhs), usub_overflow(lhs, rhs)), usub_overflow(lhs, rhs))
Alive2: https://alive2.llvm.org/ce/z/dVdMyv
2024-08-06 10:18:06 +01:00
Luke Lau
33fc322696
[SelectionDAG] Simplify vselect true, T, F -> T (#100992)
This addresses a TODO where we can fold a vselect to it's true operand
if the boolean is known to be all trues, by factoring out the logic from
extractBooleanFlip which checks TLI.getBooleanContents.
2024-08-06 10:49:20 +08:00
Kazu Hirata
8d1b17b662
[CodeGen] Construct SmallVector with ArrayRef (NFC) (#101841) 2024-08-04 00:41:29 -07:00
Michael Maitland
22ce33304e Revert "[DAG][NFC] Use SDPatternMatch for VScale in some instances"
This reverts commit d2304427cb0270259bc083a3db27413823f56e59.

The m_Add and m_Mul are commutative but the code does not expect the
communtativity.
2024-07-31 04:55:13 -07:00
Michael Maitland
d2304427cb [DAG][NFC] Use SDPatternMatch for VScale in some instances 2024-07-29 06:50:27 -07:00
Matt Davis
404071b059
[SelectionDAG] Preserve volatile undef stores. (#99918)
This patch preserves `undef` SDNodes that are `volatile` qualified.
Previously, these nodes would be discarded. The motivation behind this
change is to adhere to the
[LangRef](https://llvm.org/docs/LangRef.html#volatile-memory-accesses),
even though that doc is mostly in terms of LLVM-IR, it seems reasonable
to imply that the volatile constraints also imply to SDNodes.

> Certain memory accesses, such as
[load](https://llvm.org/docs/LangRef.html#i-load)’s,
[store](https://llvm.org/docs/LangRef.html#i-store)’s, and
[llvm.memcpy](https://llvm.org/docs/LangRef.html#int-memcpy)’s may be
marked volatile. The optimizers must not change the number of volatile
operations or change their order of execution relative to other volatile
operations. The optimizers may change the order of volatile operations
relative to non-volatile operations. This is not Java’s “volatile” and
has no cross-thread synchronization behavior.

Source: https://llvm.org/docs/LangRef.html#volatile-memory-accesses
2024-07-24 08:41:56 -04:00
David Green
b42fe6740e
[DAG] Add users of operand of simplified extract_vector_elt to worklist (#100074)
This helps to ensure we revisit the last extract_element uses of a node
so that it can be optimized away in cases such as extract(insert(scalartovec(x), 1), 0).
2024-07-23 16:34:09 +01:00
Björn Pettersson
2b78303e3f
[DAGCombiner] Freeze maybe poison operands when folding select to logic (#84924)
Just like for regular IR we need to treat SELECT as conditionally
blocking poison in SelectionDAG. So (unless the condition itself is
poison) the result is only poison if the selected true/false value is
poison.
Thus, when doing DAG combines that turn SELECT into arithmetic/logical
operations (e.g. AND/OR) we need to make sure that the new operations
aren't more poisonous. One way to do that is to use FREEZE to make
sure the operands aren't posion.

This patch aims at fixing the kind of miscompiles reported in
  https://github.com/llvm/llvm-project/issues/84653
and
  https://github.com/llvm/llvm-project/issues/85190

Solution is to make sure that we insert FREEZE, if needed to make
the fold sound, when using the foldBoolSelectToLogic and
foldVSelectToSignBitSplatMask DAG combines.
2024-07-22 17:19:46 +02:00
Bjorn Pettersson
8ebe7e60f5 [DAGCombiner] Push freeze through SETCC and SELECT_CC (#64718)
Allow pushing freeze through SETCC and SELECT_CC even if there are
multiple "maybe poison" operands. In the past we have limited it to
a single "maybe poison" operand, but it seems profitable to also
allow the multiple operand scenario.

One goal here is to avoid some regressions seen in review of
  https://github.com/llvm/llvm-project/pull/84924
when solving the select->and miscompiles described in
  https://github.com/llvm/llvm-project/issues/84653
2024-07-22 16:01:59 +02:00
Simon Pilgrim
f406d83d95 [DAG] widenCtPop - reuse existing SDLoc. NFC. 2024-07-22 11:24:23 +01:00
Joseph Huber
615b7eeaa9 Reapply "[LLVM][LTO] Factor out RTLib calls and allow them to be dropped (#98512)"
This reverts commit 740161a9b98c9920dedf1852b5f1c94d0a683af5.

I moved the `ISD` dependencies into the CodeGen portion of the handling,
it's a little awkward but it's the easiest solution I can think of for
now.
2024-07-20 09:29:31 -05:00
NAKAMURA Takumi
740161a9b9 Revert "[LLVM][LTO] Factor out RTLib calls and allow them to be dropped (#98512)"
This reverts commit c05126bdfc3b02daa37d11056fa43db1a6cdef69.
(llvmorg-19-init-17714-gc05126bdfc3b)
See #99610
2024-07-20 12:36:57 +09:00
Simon Pilgrim
497ea1d849 [DAG] tryToFoldExtendSelectLoad - reuse existing SDLoc. NFC. 2024-07-18 16:19:15 +01:00
Lawrence Benson
177ce1900f
[LLVM] Add llvm.experimental.vector.compress intrinsic (#92289)
This PR adds a new vector intrinsic `@llvm.experimental.vector.compress`
to "compress" data within a vector based on a selection mask, i.e., it
moves all selected values (i.e., where `mask[i] == 1`) to consecutive
lanes in the result vector. A `passthru` vector can be provided, from
which remaining lanes are filled.

The main reason for this is that the existing
`@llvm.masked.compressstore` has very strong constraints in that it can
only write values that were selected, resulting in guard branches for
all targets except AVX-512 (and even there the AMD implementation is
_very_ slow). More instruction sets support "compress" logic, but only
within registers. So to store the values, an additional store is needed.
But this combination is likely significantly faster on many target as it
avoids branches.

In follow up PRs, my plan is to add target-specific lowerings for x86,
SVE, and possibly RISCV. I also want to combine this with a store
instruction, as this is probably a common case and we can avoid some
memory writes in that case.

See [discussion in
forum](https://discourse.llvm.org/t/new-intrinsic-for-masked-vector-compress-without-store/78663)
for initial discussion on the design.
2024-07-17 14:24:24 +02:00
Joseph Huber
c05126bdfc
[LLVM][LTO] Factor out RTLib calls and allow them to be dropped (#98512)
Summary:
The LTO pass and LLD linker have logic in them that forces extraction
and prevent internalization of needed runtime calls. However, these
currently take all RTLibcalls into account, even if the target does not
support them. The target opts-out of a libcall if it sets its name to
nullptr. This patch pulls this logic out into a class in the header so
that LTO / lld can use it to determine if a symbol actually needs to be
kept.

This is important for targets like AMDGPU that want to be able to use
`lld` to perform the final link step, but does not want the overhead of
uncalled functions. (This adds like a second to the link time trivially)
2024-07-16 06:22:09 -05:00
Simon Pilgrim
290537238b [X86] visitADDLike - pull out repeated SDLoc. NFC. 2024-07-15 17:20:58 +01:00
Simon Pilgrim
3560e1d0ce [DAG] visitADDLike - convert (A-B)+(C-D) --> (A+C)-(B+D) fold to sd_match. NFC. 2024-07-15 17:20:58 +01:00
Simon Pilgrim
ba8792b667 [X86] visitFCOPYSIGN - pull out repeated SDLoc. NFC. 2024-07-15 16:34:21 +01:00
Simon Pilgrim
61a4e1e70f
[DAG] Add SDPatternMatch::m_SetCC and update some combines to use it (#98646)
The plan is to add more TernaryOp in the future (SELECT/VSELECT and FMA in particular)
2024-07-14 17:18:43 +01:00
Kazu Hirata
66cd2e0f9a
[CodeGen] Use range-based for loops (NFC) (#98706) 2024-07-13 13:29:47 -07:00
AtariDreams
4f8b2fff6d
[DAG] Use break instead of continue to leave do while (false) loop (NFC) (#97966) 2024-07-10 20:51:06 +04:00
Craig Topper
33112cbf59 [DAGCombiner] Remove unnecessary assert from getShiftAmountTy wrapper. NFC
The same assert appears in the TargetLowering function.

Refine comment to describe as a convenience wrapper and leave it to
TargetLowering documentation to explain.
2024-07-04 19:05:54 -07:00
Craig Topper
8419da8bd4
[SelectionDAG] Remove LegalTypes argument from getShiftAmountConstant. (#97653)
#97645 proposed to remove LegalTypes from getShiftAmountTy. This patches
removes it from getShiftAmountConstant which is one of the callers of
getShiftAmountTy.
2024-07-04 18:33:25 -07:00
Craig Topper
3141c11fe8
[SelectionDAG] Remove LegalTypes argument from getShiftAmountTy. NFC (#97757)
This argument is no longer used inside the function. Remove it from the
interface.
2024-07-04 15:24:54 -07:00
Craig Topper
34fe032fdb
[DAGCombiner] Use getShiftAmountConstant where possible. (#97683)
In #97645, I proposed removing the LegalTypes operand to
TargetLowering::getShiftAmountTy. This means we don't need to use the
DAGCombiner wrapper for getShiftAmountTy that manages this flag. Now we
can use getShiftAmountConstant and let it call
TargetLowering::getShiftAmountTy.
2024-07-04 08:44:50 -07:00
Craig Topper
a3c5c83273 [DAGCombiner] Remove unneeded getValueType() calls in visitMULHS/MULHU. NFC
We have an existing VT variable that should match N0.getValueType.
2024-07-03 13:35:04 -07:00
Simon Pilgrim
163d00c666 [DAG] Pull out repeated SDLoc in SELECT/SETCC folds. NFC. 2024-07-01 18:03:46 +01:00
Matt Arsenault
8eee6d33f7
DAG: Call SimplifyDemandedBits on copysign value operand (#97180)
So far the only cases that seem to benefit are the weird
copysign with different typed inputs.
2024-07-01 12:29:11 +02:00
Matt Arsenault
db9252b115
DAG: Call SimplifyDemandedBits on fcopysign sign value (#97151)
Math library code has quite a few places with complex bit
logic that are ultimately fed into a copysign. This helps
avoid some regressions in a future patch.

This assumes the position in the float type, which should
at least be valid for IEEE types. Not sure if we need to guard
against ppc_fp128 or anything else weird.

There appears to be some value in simplifying the value operand
as well, but I'll address that separately.
2024-07-01 12:19:17 +02: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
Simon Pilgrim
7e3507e2f5 [DAG] visitAVG - avoid duplication in the avg(ext(x), ext(y)) -> ext(avg(x, y)) folds
m_BinOp doesn't need a compile time opcode - so we can merge these into signed/unsigned cases.
2024-06-17 18:01:12 +01:00
Paul Walker
f06d96995a
[LLVM][DAGCombiner] Extend coverage for insert_subv(undef, extract_subv(A, 0), 0) (#95242)
There is an existing combine to remove the need for extract_subv that
requires matching vector types (all fixed or all scalable).

The combine doesn't need this restriction and so I've changed it to use
ValueType's "knownBits??" interface that supports mixed vector types. In
doing so we also need extra guards to prevent invalid operations (e.g.
extracting a scalable vector from a fixed length vector).
2024-06-17 12:26:04 +01:00
Simon Pilgrim
213e308633 [DAG] Fold Y = sra (X, size(X)-1); mul (or (Y, 1), X) -> (abs X)
Similar to InstCombine implementation except we don't have to handle the NSW/is_int_min_poison case.
2024-06-15 21:10:00 +01:00
c8ef
08fae467e4
[DAG] fold avgs(sext(x), sext(y)) -> sext(avgs(x, y)) (#95365)
Follow up of #95134.

Context:
https://github.com/llvm/llvm-project/pull/95134#issuecomment-2162825594.
2024-06-14 21:53:29 +08:00
Simon Pilgrim
b1484f7de0 [DAG] visitAVG - use X/Y SDValue args to match the fold comment. NFC. 2024-06-12 16:32:35 +01:00
Simon Pilgrim
ea2ee5dc2f
[DAG] Add legalization handling for AVGCEIL/AVGFLOOR nodes (#92096)
Always match AVG patterns pre-legalization, and use TargetLowering::expandAVG to expand again during legalization.

I've removed the X86 custom AVGCEILU pattern detection and replaced with combines to try and convert other AVG nodes to AVGCEILU.
2024-06-12 14:11:07 +01:00
c8ef
0e346eeac6
[DAG] fold avgu(zext(x), zext(y)) -> zext(avgu(x, y)) (#95134)
close: #86301
2024-06-12 12:58:49 +01:00
David Green
a284bdb311 [DAG] Fold fdiv X, c2 -> fmul X, 1/c2 without AllowReciprocal if exact (#93882)
This moves the combine of fdiv by constant to fmul out of an
'if (Options.UnsafeFPMath || Flags.hasAllowReciprocal()' block,
so that it triggers if the divide is exact. An extra check for
Recip.isDenormal() is added as multiple places make reference
to it being unsafe or slow on certain platforms.
2024-06-09 12:28:20 +01:00
Yingwei Zheng
d9507a3e10
[DAGCombine] Fix miscompilation caused by PR94008 (#94850)
The pr description in #94008 mismatches with the code.
> + When VT is smaller than ShiftVT, it is safe to use trunc.
> + When VT is larger than ShiftVT, it is safe to use zext iff
`is_zero_poison` is true (i.e., `opcode == ISD::CTTZ_ZERO_UNDEF`). See
also the counterexample `src_shl_cttz2 -> tgt_shl_cttz2` in the alive2
    proofs.

Closes #94824.
2024-06-08 21:40:57 +08:00
Quentin Colombet
25506f4864
[SDISel][Combine] Constant fold FP16_TO_FP (#94790)
In some case, constant can survive early constant folding optimization
because they are hidden behind several layers of type changes.

E.g., consider the following sequence (extracted from the arm test that
this commit changes):
```
    t2: v1f16 = BUILD_VECTOR ConstantFP:f16<APFloat(0)>
    t4: v1f16 = insert_vector_elt t2, ConstantFP:f16<APFloat(0)>, Constant:i32<0>
  t5: f16 = bitcast t4
t6: f32 = fp_extend t5
```

Because the constant (APFloat(0)) is hidden behind a <1 x ty> type, all
the constant folding that normally happen for scalar nodes when using
`SelectionDAG::getNode` are blocked.

As a result the constant manages to survive as an actual conversion
instruction down to the select phase:
```
t11: f32 = fp16_to_fp Constant:i32<0>
```

With the change in this patch, we try to do constant folding one more
time during dag combine, which in the motivating example result in the
much better sequence:
```
t7: ch = CopyToReg t0, Register:f32 %0, ConstantFP:f32<0.000000e+00>
```

Note: I'm sure we have this problem in a lot of other places. Generally
speaking I believe SDISel is not that good with <1 x ty> compared to
pure scalar. However, I only changed what I could easily test.
2024-06-08 11:31:13 +02:00
aengelke
74d62c2f73
[CodeGen][SDAG] Remove CombinedNodes SmallPtrSet (#94609)
This "small" set grows quite large and it's more performant to store
whether a node has been combined before in the node itself.

As this information is only relevant for nodes that are currently not in
the worklist, add a second state to the CombinerWorklistIndex (-2) to
indicate that a node is currently not in a worklist, but was combined
before.

This brings a substantial performance improvement.
2024-06-07 13:17:27 +02:00
Simon Pilgrim
af3ffff34f
[DAG] Always allow folding XOR patterns to ABS pre-legalization (#94601)
Removes residual ARM handling for vXi64 ABS nodes to prevent infinite loops.
2024-06-07 11:02:50 +01:00
Simon Pilgrim
03a2fe9a75 [DAG] visitSUB - update the ABS matching code to use SDPatternMatch and hasOperation.
Avoids the need to explicitly test both commuted variants and doesn't match custom lowering after legalization.

Cleanup for #94504
2024-06-06 10:06:57 +01:00
aengelke
6150e84cfc
[CodeGen][SDAG] Remove Combiner WorklistMap (#92900)
DenseMap for pointer lookup is expensive, and this is only used for
deduplication and index lookup. Instead, store the worklist index in the
node itself.

This brings a substantial performance improvement.
2024-06-05 17:58:08 +02:00