13494 Commits

Author SHA1 Message Date
PiJoules
19008d3218
[llvm] Support fixed point multiplication on AArch64 (#84237)
Prior to this, fixed point multiplication would lead to this assertion
error on AArhc64, armv8, and armv7.

```
 _Accum f(_Accum x, _Accum y) { return x * y; }

// ./bin/clang++ -ffixed-point /tmp/test2.cc -c -S -o - -target aarch64 -O3
clang++: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:10245: void llvm::TargetLowering::forceExpandWideMUL(SelectionDAG &, const SDLoc &, bool, EVT, const SDValue, const SDValue, const SDValue, const SDValue, SDValue &, SDValue &) const: Assertion `Ret.getOpcode() == ISD::MERGE_VALUES && "Ret value is a collection of constituent nodes holding result."' failed.
```

This path into forceExpandWideMUL should only be taken if we don't
support [US]MUL_LOHI or MULH[US] for the operand size (32 in this case).
But we should also check if we can just leverage regular wide
multiplication. That is, extend the operands from 32 to 64, do a regular
64-bit mul, then trunc and shift. These ops are certainly available on
aarch64 but for wider types.
2024-05-14 11:23:45 -07:00
Graham Hunter
fbb37e9606
[AArch64] Add an all-in-one histogram intrinsic
Based on discussion from
https://discourse.llvm.org/t/rfc-vectorization-support-for-histogram-count-operations/74788

Current interface is:

llvm.experimental.histogram(<vecty> ptrs, <intty> inc_amount, <vecty> mask)

The integer type used by 'inc_amount' needs to match the type of the buckets in memory.

The intrinsic covers the following operations:
  * Gather load
  * histogram on the elements of 'ptrs'
  * multiply the histogram results by 'inc_amount'
  * add the result of the multiply to the values loaded by the gather
  * scatter store the results of the add

Supports lowering to histcnt instructions for AArch64 targets, and scalarization for all others at present.
2024-05-13 11:35:28 +01:00
Min-Yih Hsu
f8063ffe73
[VP][RISCV] Add vp.reduce.fmaximum/fminimum and its RISC-V codegen (#91782)
`vp.reduce.fmaximum/fminimum` are the VP version of
`vector.reduce.fmaximum/fminimum`.
2024-05-10 16:01:47 -07:00
Simon Pilgrim
7f3e3785d0 Fix MSVC "result of 32-bit shift implicitly converted to 64 bits" warning. NFC. 2024-05-10 22:40:23 +01:00
Simon Pilgrim
7e6879b245 [X86] scalarizeExtractedBinop - reuse existing SDLoc. NFC. 2024-05-10 22:40:23 +01:00
David Green
8fc9e3d577
[DAG] Lower frem of power-2 using div/trunc/mul+sub (#91148)
If we are lowering a frem and the divisor is known to be an integer power-2, we
can use the formula 'frem = x - trunc(x / d) * d'. This avoids the more
expensive call to fmod. The results are identical as fmod so long as d is a
power-2 (so the mul does not round incorrectly), and the sign of the return is
either always positive or not important for zeroes (nsz).

Unfortunately Alive2 does not handle this well at the moment. I was using
exhaustive checking to test this:
(https://gist.github.com/davemgreen/6078015f30d3bacd1e9572f8db5d4b64).

I found this in cpythons implementation of float_pow. I currently added it as a
DAG combine for frem with power-2 fp constants.
2024-05-10 14:58:48 +01:00
Paul Walker
b277bf56d7
[LLVM][CodeGen][SVE] Clean up lowering of VECTOR_SPLICE operations. (#91330)
Remove DAG combine that is performing type legalisation and instead
add isel patterns for all legal types.
2024-05-10 10:53:57 +01:00
David Green
23b673e5b4
[DAG][AArch64] Handle vscale addressing modes in reassociationCanBreakAddressingModePattern (#89908)
reassociationCanBreakAddressingModePattern tries to prevent bad add
reassociations that would break adrressing mode patterns. This adds
support for vscale offset addressing modes, making sure we don't break
patterns that already exist. It does not optimize _to_ the correct
addressing modes yet, but prevents us from optimizating _away_ from
them.
2024-05-10 09:27:02 +01:00
Simon Pilgrim
df21ee4c62 [DAG] Add clang-format off/on wrappers around compact switch handlers. NFC.
Avoids a problem identified in #90503
2024-05-09 17:02:17 +01:00
Matt Arsenault
6a8d30b1c1
DAG: Skip 0 sign handling in minimum/maximum lowering for _ieee case (#91326)
dc9664a8adae17f2083fbcc8e96cfce606c56d57 changed the documentation to
assume these order -0 as less than +0.
2024-05-09 14:41:13 +02:00
David Sherwood
b52fa9461a
[Analysis] Add cost model for experimental.cttz.elts intrinsic (#90720)
In PR #88385 I've added support for auto-vectorisation of some early
exit loops, which requires using the experimental.cttz.elts to calculate
final indices in the early exit block. We need a more accurate cost
model for this intrinsic to better reflect the cost of work required in
the early exit block. I've tried to accurately represent the expansion
code for the intrinsic when the target does not have efficient lowering
for it. It's quite tricky to model because you need to first figure out
what types will actually be used in the expansion. The type used can
have a significant effect on the cost if you end up using illegal vector
types.

Tests added here:

  Analysis/CostModel/AArch64/cttz_elts.ll
  Analysis/CostModel/RISCV/cttz_elts.ll
2024-05-09 09:40:33 +01:00
David Green
fcf945f4ed
[DAG] Fold add(mul(add(A, CA), CM), CB) -> add(mul(A, CM), CM*CA+CB) (#90860)
This is useful when the inner add has multiple uses, and so cannot be
canonicalized by pushing the constants down through the mul. This patch
adds patterns for both `add(mul(add(A, CA), CM), CB)` and with an extra add
`add(add(mul(add(A, CA), CM), B) CB)` as the second can come up when
lowering geps.
2024-05-08 22:11:18 +01:00
Aleksandr Popov
df311a2762
Add interface to check if a call has a deopt bundle (NFC) (#91348)
Encapsulate check that a call has a deopt bundle to make it easier to
change the deopt scheme.
2024-05-08 11:54:49 +02:00
Craig Topper
ef84452571
[DAGCombiner] Be more careful about looking through extends and truncates in mergeTruncStores. (#91375)
Previously we recursively looked through extends and truncates on both
SourceValue and WideVal.

SourceValue is the largest source found for each of the stores we are
combining. WideVal is the source for the current store.

Previously we could incorrectly look through a (zext (trunc X)) pair and
incorrectly believe X to be a good source.

I think we could also look through a zext on one store and a sext on
another store and arbitrarily pick one of the extends as the final
source.

With this patch we only look through one level of extend or truncate.
And we don't look through extends/truncs on both SourceValue and WideVal
at the same time.

This may lose some optimization cases, but keeps everything we had tests
for.

Fixes #90936.
2024-05-07 21:17:50 -07:00
Jinsong Ji
2dade0041a
[Analysis] Attribute Range should not prevent tail call optimization (#91122)
- Remove Range attr when comparing for tailcall
- Add test for testcall with range
2024-05-07 22:02:10 -04:00
Matt Arsenault
82bb2534d4
AMDGPU: Don't bitcast float typed atomic store in IR (#90116)
Implement the promotion in the DAG.

Depends #90113
2024-05-07 21:43:22 +02:00
Paul Walker
235cea720c
[NFC][LLVM] Refactor rounding mode detection of constrained fp intrinsic IDs (#90854)
I've refactored the code to genericise the implementation to better
allow for target specific constrained fp intrinsics.
2024-05-07 11:23:55 +01:00
Quentin Colombet
6ce04747cf
[SDISel] Teach the type legalizer about ADDRSPACECAST (#90969)
Vectorized ADDRSPACECASTs were not supported by the type legalizer.

This patch adds the support for:
- splitting the vector result: <2 x ptr> => 2 x <1 x ptr>
- scalarization: <1 x ptr> => ptr
- widening: <3 x ptr> => <4 x ptr>

This is all exercised by the added NVPTX tests.
2024-05-07 11:08:33 +02:00
Simon Pilgrim
522b4bfe5b
[DAG] Fold bitreverse(shl/srl(bitreverse(x),y)) -> srl/shl(x,y) (#89897)
Noticed while investigating GFNI per-element vector shifts (we can form SHL but not SRL/SRA)

Alive2: https://alive2.llvm.org/ce/z/fSH-rf
2024-05-06 11:13:05 +01:00
Phoebe Wang
02dfbbff19
[SelectionDAG] Make ARITH_FENCE support half and bfloat type (#90836) 2024-05-05 13:08:34 +08:00
Simon Pilgrim
caacf8685a
[DAG] Fold freeze(shuffle(x,y,m)) -> shuffle(freeze(x),freeze(y),m) (#90952)
If the shuffle mask contains no undef elements, then we can move the freeze through a shuffle node.

This requires special case handling to create a new ShuffleVectorSDNode.

Includes VECTOR_SHUFFLE support for isGuaranteedNotToBeUndefOrPoison  / canCreateUndefOrPoison.
2024-05-04 12:03:10 +01:00
Craig Topper
3563af6c06
[DAGCombiner] In mergeTruncStore, make sure we aren't storing shifted in bits. (#90939)
When looking through a right shift, we need to make sure that all of
the bits we are using from the shift come from the shift input and
not the sign or zero bits that are shifted in.
    
Fixes #90936.
2024-05-03 09:59:33 -07:00
Matt Arsenault
edbe6ebb4d
SystemZ: Don't promote atomic store in IR (#90899)
This is the mirror to the recent atomic load change. The same
bitcast-back-to-integer case is a small code quality regression for the
same reason. This would disappear with a bitcastable legal 128-bit type.
2024-05-03 10:04:12 +02:00
Matt Arsenault
b6d24cb018
DAG: Implement softening for fp atomic load (#90839) 2024-05-02 13:38:37 +02:00
Matt Arsenault
d9fc5babb9
DAG: Implement softening for fp atomic store (#90840)
This will prevent SystemZ test regressions in a future change, tested by
#90826
2024-05-02 12:08:52 +02:00
zxc12523
171aeb20ad
[DAG] SelectionDAG.computeKnownBits - add NSW/NUW flags support to ISD::SHL handling (#89877)
fix #89414
2024-05-02 10:31:56 +01:00
Craig Topper
a03eeb0e98
[SelectionDAG][X86] Add a NoWrap flag to SelectionDAG::isAddLike. NFC (#90681)
If this flag is set, Xor will not be considered AddLike. If an Xor were
treated as an Add it may wrap. If we can prove there would be no carry out and
thus no wrap, the Xor would be turned into a disjoint Or by DAGCombine.

Use this new flag to fix a bug in X86 where an Xor is incorrectly being treated
as an NUWAdd.

Fixes #90668.
2024-04-30 16:52:56 -07:00
Craig Topper
267329d7e0 [LegalizeDAG] Simplify interface to PromoteReduction. NFC
Return an SDValue instead of pushing to the Results vector. Let
the caller do the push.
2024-04-30 09:48:41 -07:00
Simon Pilgrim
91c52b966a [DAG] Pull out repeated SDLoc() from SHL/SRL/SRA combines. NFC.
We were always calling SDLoc(N) at the top of each visitSHL/SRL/SRA for the FoldConstantArithmetic call, so just reuse this as much as possible.
2024-04-30 17:30:43 +01:00
Min-Yih Hsu
539f626ecd
[VP][RISCV] Add vp.cttz.elts intrinsic and its RISC-V codegen (#90502)
This intrinsic is the VP version of `experimental.cttz.elts`.
2024-04-30 09:27:10 -07:00
Luke Lau
5e03c0af47
[DAGCombiner] Fix mayAlias not accounting for scalable MMOs with offsets (#90573)
In #70452 DAGCombiner::mayAlias was taught to handle scalable sizes, but
when it checks via AA->isNoAlias it didn't take into account the case
where the size is scalable but there was an offset too.

For the fixed length case the offset was just accounted for by adding to
the LocationSize, but for the scalable case there doesn't seem to be a
way to represent both a scalable and fixed part in it. So this patch
works around it by bailing if there is an offset.

Fixes #90559
2024-04-30 20:20:40 +08:00
Craig Topper
705636a113
[SelectionDAG][RISCV] Move VP_REDUCE* legalization to LegalizeDAG.cpp. (#90522)
LegalizeVectorType is responsible for legalizing nodes that perform an
operation on each element may need to scalarize.

This is not true for nodes like VP_REDUCE.*, BUILD_VECTOR,
SHUFFLE_VECTOR, EXTRACT_SUBVECTOR, etc.

This patch drops any nodes with a scalar result from LegalizeVectorOps
and handles them in LegalizeDAG instead.

This required moving the reduction promotion to LegalizeDAG. I have
removed the support integer promotion as it was incorrect for integer
min/max reductions. Since it was untested, it was best to assert on it
until it was really needed.

There are a couple regressions that can be fixed with a small DAG
combine which I will do as a follow up.
2024-04-29 22:44:24 -07:00
Bjorn Pettersson
55c6bda01e Revert "Revert "[SelectionDAG] Handle more opcodes in canCreateUndefOrPoison (#84921)" and more..."
This reverts commit 16bd10a38730fed27a3bf111076b8ef7a7e7b3ee.

Re-applies:
    b3c55b707110084a9f50a16aade34c3be6fa18da - "[SelectionDAG] Handle more opcodes in canCreateUndefOrPoison (#84921)"
    8e2f6495c0bac1dd6ee32b6a0d24152c9c343624 - "[DAGCombiner] Do not always fold FREEZE over BUILD_VECTOR (#85932)"
    73472c5996716cda0dbb3ddb788304e0e7e6a323 - "[SelectionDAG] Treat CopyFromReg as freezing the value (#85932)"

with a fix in DAGCombiner::visitFREEZE.
2024-04-29 13:08:52 +02:00
Maciej Gabka
bfc0317153
Move several vector intrinsics out of experimental namespace (#88748)
This patch is moving out following intrinsics:
* vector.interleave2/deinterleave2
* vector.reverse
* vector.splice

from the experimental namespace.

All these intrinsics exist in LLVM for more than a year now, and are
widely used, so should not be considered as experimental.
2024-04-29 10:16:45 +01:00
David Spickett
16bd10a387 Revert "[SelectionDAG] Handle more opcodes in canCreateUndefOrPoison (#84921)" and more...
This reverts:
b3c55b707110084a9f50a16aade34c3be6fa18da - "[SelectionDAG] Handle more opcodes in canCreateUndefOrPoison (#84921)"
(because it updates a test case that I don't know how to resolve the conflict for)
8e2f6495c0bac1dd6ee32b6a0d24152c9c343624 - "[DAGCombiner] Do not always fold FREEZE over BUILD_VECTOR (#85932)"
73472c5996716cda0dbb3ddb788304e0e7e6a323 - "[SelectionDAG] Treat CopyFromReg as freezing the value (#85932)"

Due to a test suite failure on AArch64 when compiling for SVE.
https://lab.llvm.org/buildbot/#/builders/197/builds/13955

clang: ../llvm/llvm/include/llvm/CodeGen/ValueTypes.h:307: MVT llvm::EVT::getSimpleVT() const: Assertion `isSimple() && "Expected a SimpleValueType!"' failed.
2024-04-29 09:47:41 +01:00
Qiu Chaofan
4a8f2f2e1a
[Legalizer] Expand fmaximum and fminimum (#67301)
According to langref, llvm.maximum/minimum has -0.0 < +0.0 semantics and
propagates NaN.

Expand the nodes on targets not supporting the operation, by adding
extra check for NaN and using is_fpclass to check zero signs.
2024-04-29 15:09:54 +08:00
Björn Pettersson
b3c55b7071
[SelectionDAG] Handle more opcodes in canCreateUndefOrPoison (#84921)
[SelectionDAG] Handle more opcodes in canCreateUndefOrPoison

Handle SELECT_CC similarly as SETCC.

Handle these operations that only propagate poison/undef based on the
input operands:
  SADDSAT, UADDSAT, SSUBSAT, USUBSAT, MULHU, MULHS,
  SMIN, SMAX, UMIN, UMAX

These operations may create poison based on shift amount and exact
flag being violated:
  SRL, SRA

One goal here is to allow pushing freeze through these operations
when allowed, as well as letting analyses such as
isGuaranteedNotToBeUndefOrPoison to not break on such operations.

Since some problems have been observed with pushing freeze through
SRA/SRL we block that explicitly in DAGCombiner::visitFreeze now.
That way we can still model SRA/SRL properly in
SelectionDAG::canCreateUndefOrPoison, e.g. when used by
isGuaranteedNotToBeUndefOrPoison, even if we do not want to push
freeze through those instructions.
2024-04-29 07:56:49 +02:00
Matt Arsenault
405c018c71
DAG: Simplify demanded bits for truncating atomic_store (#90113)
It's really unfortunate that STORE and ATOMIC_STORE are separate
opcodes. This duplicates a basic simplify demanded for the truncating
case. This avoids some AMDGPU lit regressions in a future patch.

I'm not sure how to craft a test that exposes this without first
introducing the regressions by promoting half to i16.
2024-04-26 15:21:44 +02:00
Simon Pilgrim
55d85c84ac
[DAG] visitORCommutative - fold build_pair(not(x),not(y)) -> not(build_pair(x,y)) style patterns (#90050)
(Sorry, not an actual build_pair node just a similar pattern).

For cases where we're concatenating 2 integers into a double width integer, see if both integer sources are NOT patterns.

We could take this further and handle all logic ops with a constant operands, but I just wanted to handle the case reported on #89533 initially.

Fixes #89533
2024-04-26 14:11:03 +01:00
Bjorn Pettersson
8e2f6495c0 [DAGCombiner] Do not always fold FREEZE over BUILD_VECTOR (#85932)
Avoid turning a BUILD_VECTOR that can be recognized as "all zeros",
"all ones" or "constant" into something that depends on
freeze(undef), as that would destroy those properties.

Instead we replace undef by 0/-1 in such vectors, making it possible
to fold away the freeze. We typically use -1 if the BUILD_VECTOR
would identify as "all ones", and otherwise we use the value 0.
2024-04-26 13:41:21 +02:00
Bjorn Pettersson
73472c5996 [SelectionDAG] Treat CopyFromReg as freezing the value (#85932)
The description of CopyFromReg in ISDOpcodes.h says that the input
valus is defined outside the scope of the current SelectionDAG. I
think that means that we basically can treat it as a FREEZE in the
sense that it can be seen as neither being undef nor poison.

Being able to fold freeze(CopyFromReg) into CopyFromReg seems
useful to avoid regressions if we start to introduce freeze
instruction in DAGCombiner/foldBoolSelectToLogic, e.g. to solve
https://github.com/llvm/llvm-project/issues/84653

Things _not_ dealt with in this patch:
- Depending on calling convention an input argument can be passed
  also on the stack and not in a register. If it is allowed to treat
  an argument received in a register as not being poison, then I think
  we want to treat arguments received on the stack the same way. But
  then we need to attribute load instructions, or add explicit FREEZE
  when lowering formal arguments.
- A common pattern is that there is an AssertZext or AssertSext just
  after CopyFromReg. I think that if we treat CopyFromReg as never
  being poison, then it should be allowed to fold
     (freeze(AssertZext(CopyFromReg))) -> AssertZext(CopyFromReg))
2024-04-26 13:41:21 +02:00
Matt Arsenault
f1112ebe07
AMDGPU: Do not bitcast atomic load in IR (#90060)
These hooks should be removed. This is a trivial legalization transform
the legalizer needs to support. The IR just complicates things, and it
was losing metadata. Implement the DAG promotion support, and switch
AMDGPU over to using it.

Really we'd be a lot better off merging ATOMIC_LOAD and LOAD like
GlobalISel does.
2024-04-26 12:20:40 +02:00
Fangrui Song
5a12f2867a LLVM_FALLTHROUGH => [[fallthrough]]. NFC 2024-04-25 17:50:59 -07:00
Philip Reames
f4e3daa562
[DAG] Early exit for flags in canCreateUndefOrPoison [nfc] (#89834)
This matches the style used in the Analysis version of this routine, and
makes it less likely we'll miss a poison generating flag in future
changes. Unlike IR, the check for poison generating flags doesn't need
to switch over opcode since all nodes have the SDFlags storage.
2024-04-25 09:12:59 -07:00
Simon Pilgrim
d51a17f684 [DAG] visitORCommutative - pull out repeated SDLoc(). NFC. 2024-04-25 14:23:36 +01:00
Craig Topper
c5dcb5239e [SelectionDAG] Move GlobalAddressSDNode and AddrSpaceCastSDNode constructors into header. NFC
These constructors are no more complicated than any of the other
*SDNode constructors that are already in the header.
2024-04-24 13:11:57 -07:00
Craig Topper
fc538b070d
[SelectionDAG] Pass SDVTList instead of VTs to *SDNode constructors. NFC (#89880)
All of these constructors were creating a SDVTList using an EVT* created
by SDNode::getValueTypeList. This EVT needs to live at least as long as
the SDNode that uses it. To do this, SDNode::getValueTypeList contains
several function scoped static variables that hold the memory for the
EVT. So the EVT lives until global destructors run.

This is problematic since an EVT contains a Type* that points to memory
allocated by an LLVMContext. If multiple LLVMContexts are used that
don't have overlapping lifetimes, we can end up with stale or or
incorrect pointers cached in the EVTs owned by SDNode::getValueTypeList.

I want to try to make the EVTs be owned by SelectionDAG instead. This is
already done for SDVTLists with more than 1 VT. The single value case is
a very old optimizaton that should be re-evaluated. In order to do this,
I need the SDVTLists to be created by SelectionDAG rather than by the
SDNode itself.

This patch doesn't change how the allocation is done yet. It just moves
the code around.

This patch does reduce the number of calls to getVTList since we now
share with the call needed for the SDNode FoldingSet.

Part of fixing #88233.
2024-04-24 12:31:14 -07:00
Matt Arsenault
50082d64e6
DAG: Fix widening of fptrunc_round vectors (#89918) 2024-04-24 16:21:40 +02:00
Xu Zhang
f6d431f208
[CodeGen] Make the parameter TRI required in some functions. (#85968)
Fixes #82659

There are some functions, such as `findRegisterDefOperandIdx` and  `findRegisterDefOperand`, that have too many default parameters. As a result, we have encountered some issues due to the lack of TRI  parameters, as shown in issue #82411.

Following @RKSimon 's suggestion, this patch refactors 9 functions, including `{reads, kills, defines, modifies}Register`,  `registerDefIsDead`, and `findRegister{UseOperandIdx, UseOperand, DefOperandIdx, DefOperand}`, adjusting the order of the TRI parameter and making it required. In addition, all the places that call these functions have also been updated correctly to ensure no additional impact.

After this, the caller of these functions should explicitly know whether to pass the `TargetRegisterInfo` or just a `nullptr`.
2024-04-24 14:24:14 +01:00
Simon Pilgrim
9f2a068bff [DAG] Add getValid*ShiftAmountConstant wrappers without DemandedElts
Simplify callers which don't have their own DemandedElts mask.

Noticed while reviewing #88801
2024-04-24 13:26:43 +01:00