39674 Commits

Author SHA1 Message Date
Alexey Bataev
9400270449 [SLP]Fix comparator for vector operands of extractelements in PHICompare
Need to make comparator to follow strict-weak ordering to fix compiler
crashes.

Fixes #138178
2025-05-01 14:28:20 -07:00
Florian Hahn
8d02529f77
[VPlan] Consistently use ArrayRef<VPValue *> for operands in ctors (NFC) (#137798)
Now that there is an ArrayRef constructor taking iterator_ranges, use it
consistently to slightly simplify code.

Depends on https://github.com/llvm/llvm-project/pull/137796.

PR: https://github.com/llvm/llvm-project/pull/137798
2025-05-01 21:19:10 +01: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
Samuel Tebbs
fa769655e7 [LV] NFC: Make VPPartialReductionRecipe a VPReductionRecipe 2025-04-30 19:44:40 +01:00
Luke Lau
2cd829fc2c
[VectorUtils][VPlan] Consolidate VPWidenIntrinsicRecipe::onlyFirstLaneUsed and isVectorIntrinsicWithScalarOpAtArg (#137497)
We can reuse isVectorIntrinsicWithScalarOpAtArg in VectorUtils to
determine if only the first lane will be used for a
VPWidenIntrinsicRecipe, provided that we also move the VP EVL operand
check into it.

This was needed by a local patch I was working on that created a
VPWidenIntrinsicRecipe with a VP intrinsic, and prevents the need to
update the scalar arguments in two places.
2025-05-01 01:25:41 +08:00
Jonas Paulsson
f5c8c1eedb
[SLPVectorizer] Move X86 specific handling into X86TTIImpl. (#137830)
`ad9909d "[SLP]Fix perfect diamond match with extractelements in scalars" `
changed SLPVectorizer getScalarizationOverhead() to call
TTI.getVectorInstrCost() instead of TTI.getScalarizationOverhead() in some
cases. This was due to X86 specific handlings in these (overridden) methods,
and unfortunately the general preference of TTI.getScalarizationOverhead()
was dropped. If VL is available it should always be preferred to use
getScalarizationOverhead(), and this is indeed the case for SystemZ which
has a special insertion instruction that can insert two GPR64s.

Then ` 33af951 "[SLP]Synchronize cost of gather/buildvector nodes with
codegen"` reworked SLPVectorizer getGatherCost() which together with
ad9909d caused the SystemZ test vec-elt-insertion.ll to fail.

This patch restores the SystemZ test and reverts the change in SLPVectorizer
getScalarizationOverhead() so that TTI.getScalarizationOverhead() is always
called again. The ForPoisonSrc argument is now passed on to the TTI method
so that X86 can handle this as required.

Fixes: #135346
2025-04-30 17:11:27 +02:00
Iris Shi
b54b3e81f2
Recommit "[ConstraintElim] Simplify cmp after uadd.sat/usub.sat (#135603)" (#136467) 2025-04-30 21:49:18 +08:00
Paul Walker
3b12bac6d1
[LLVM][Reassociate] Extend ConvertShiftToMul to allow for ConstantInt vectors. (#137340)
This has the side effect of fixing the FIXME for when
use-constant-int-for-fixed-length-splat becomes the default.
2025-04-30 13:41:40 +01:00
Simon Pilgrim
26da8870ed Fix MSVC "not all control paths return a value" warning. NFC. 2025-04-30 12:32:22 +01:00
Stephen Tozer
92195f6fc8 Reapply "[DLCov] Implement DebugLoc coverage tracking (#107279)"
Reapplied after fixing the config issue that was causing issues following
the previous merge.

This reverts commit fdbf073a86573c9ac4d595fac8e06d252ce1469f.
2025-04-30 11:39:29 +01:00
Ricardo Jesus
c91c3f930c
[InstCombine] Do not combine shuffle+bitcast if the bitcast is eliminable. (#135769)
If we are attempting to combine shuffle+bitcast but the bitcast is
pairable with a subsequent bitcast, we should not fold the shuffle as
doing so can block further simplifications.

The motivation for this is a long-standing regression affecting SIMDe on
AArch64, introduced indirectly by the AlwaysInliner (1a2e77cf). Some
reproducers:
* https://godbolt.org/z/53qx18s6M
* https://godbolt.org/z/o5e43h5M7
2025-04-30 08:22:38 +01:00
Nikita Popov
c96f019fa3
[BasicBlockUtils] Remove broken support for eh pads in SplitEdge() (#137816)
d81d9e8b8604c85709de0a22bb8dd672a28f0401 changed SplitEdge() to make use
of ehAwareSplitEdge() for critical edges where the target is an eh pad.
However, the implementation is incorrect at least for landing pads. What
is currently produced for the code in the modified unit test is
something like this:

    continue:
      invoke void @sink()
              to label %normal unwind label %new_bb

    new_bb:
      %cp = cleanuppad within %exception []
      cleanupret from %cp unwind label %exception

    exception:
      %cleanup = landingpad i8 cleanup
      br label %trivial-eh-handler

This mixes different exception handling mechanisms in a nonsensical way,
and is not well-formed IR. To actually "split" the landingpad edge (for
a rather loose definition of "split"), I think we'd have to generate
something along these lines:

      exception.split:
        %cleanup.split = landingpad i8 cleanup
        br label %exception.cont

      exception:
        %cleanup.orig = landingpad i8 cleanup
        br label %exception.cont
      
      exception.cont:
%cleanup = phi i8 [ %cleanup.split, %exception_split ], [ %cleanup.orig,
%exception ]

I didn't bother actually implementing that, seeing as how nobody noticed
the existing codegen being broken in the last four years, so clearly
nobody actually needs this function to work with EH edges. Just return
nullptr instead.
2025-04-30 09:07:55 +02:00
NewSigma
af497d9a65
[DSE] Simpily if condition (NFC) (#137777)
Note that the key-value pair has already been initialized, so assignment
is not necessary.
2025-04-30 09:01:19 +02:00
Florian Hahn
d431921677
Revert "[VPlan] Add canonical IV during construction (NFC)."
This reverts commit e17122fffa8d233fcf9f717354ecda46173f1b8d.

Revert as this seems to break some unit tests on some bots.
2025-04-29 22:55:11 +01:00
Florian Hahn
e17122fffa
[VPlan] Add canonical IV during construction (NFC).
This addresses an existing TODO and simply moves the current code to add
canonical IV recipes to the initial skeleton construction, at the same
place where the corresponding region will be introduced.
2025-04-29 22:38:59 +01:00
Florian Hahn
7e71466900
[VPlan] Preserve dbg location on canonical IVs in native path.
Pass the debug location of the primary IV to addCanonicalIVRecipes in
the native path, matching the behavior of inner loop vectorization.
2025-04-29 21:40:42 +01:00
Yingwei Zheng
d20796dab7
[InstCombine] Offset both sides of an equality icmp (#134086)
Proof: https://alive2.llvm.org/ce/z/zQ2UW4
Closes https://github.com/llvm/llvm-project/issues/134024
2025-04-30 00:19:23 +08:00
黃國庭
f37ab15254
[InstCombine] Infer exact for lshr by cttz (#136696)
Infer the 'exact' flag on an 'lshr' or 'ashr' instruction when the shift
amount is computed via a 'cttz' intrinsic on the same operand.
 
Proof: https://alive2.llvm.org/ce/z/CQR2PG

Fixes #131444.
2025-04-29 17:50:53 +02:00
Luke Lau
c5d780bb72
[VPlan] Remove no longer needed VP intrinsic handling in VPWidenIntrinsicRecipe::computeCost. NFCI (#137573)
Whenever calls were transformed to VP intrinsics with EVL tail folding
in #110412, this workaround was added in computeCost to avoid an
assertion when checking ICA.getArgs().

However it turned out that the actual arguments were never used and this
assertion was removed in #115983 afterwards, so it's now fine to leave
the arguments empty and use the type based cost instead.

The type based cost and value based cost are the same for these VP
intrinsics.

This was tested by adding back in the transformation code in #110412 and
checking that no assertions were still hit.
2025-04-29 21:55:20 +08:00
Gaëtan Bossu
c5c4f0d11c
[SLP] Simplify tryToFindDuplicates() (NFC) (#135766)
This NFC aims to simplify the control-flow and interfaces used in tryToFindDuplicates(). The point is to make it easier to understand where decisions for scalar de-duplication are made.

In particular:
 - Limit indentation
 - Rename some variables to better match their use case
- Always give consistent outputs for VL and ReuseShuffleIndices. This makes it possible to use the same code for building gather TreeEntry everywhere. This also allows to remove the TryToFindDuplicates lambda.
2025-04-29 14:47:22 +01:00
Luke Lau
b0f2bfc7e4
[VPlan] Use correct non-FMF constructor in VPInstructionWithType createNaryOp (#137632)
Currently if we try to create a VPInstructionWithType without a FMF via
VPBuilder::createNaryOp we will use the constructor that asserts
`assert(isFPMathOp() && "this op can't take fast-math flags");`.

This fixes it by checking if FMFs have a value, similar to the other
createNaryOp overloads.

This is needed by #129508
2025-04-29 20:35:19 +08:00
Florian Hahn
d68b446933
[IR] Add matchers for remaining FP min/max intrinsics (NFC). (#137612)
Add dedicated matchers for minimum,maximum,minimumnum and maximumnum
intrinsics, similar for the existing matchers for maxnum and minnum.

As suggested in https://github.com/llvm/llvm-project/pull/137335.

PR: https://github.com/llvm/llvm-project/pull/137612
2025-04-29 12:20:00 +01:00
Ramkumar Ramachandra
49842426f3
[LV] Fix MinBWs in WidenIntrinsic case (#137005)
There is a bug in the computation and handling of MinBWs in the case of
VPWidenIntrinsicRecipe: a crash is observed in
VPlanTransforms::truncateToMinimalBitwidths due to a mismatch between
the number of recipes processed and the number of entries in MinBWs. Fix
handling of calls in llvm::computeMinimumValueSizes, and handle
VPWidenIntrinsicRecipe in truncateToMinimalBitwidths, fixing the bug.

Fixes #87407.
2025-04-29 09:47:38 +01:00
Luke Lau
7ca6490636
[VPlan] Factor out isUnrolled() helper in VPWidenIntOrFpInductionRecipe. NFC (#137635)
Split off from #129508, this generalizes getSplatVFValue and
getLastUnrolledPartOperand so they don't need changed if another operand
is added.
2025-04-29 10:18:47 +08:00
Thurston Dang
d913ea307e
[msan] Implement support for avx512fp16.mask.{add/sub/mul/div/max/min}.sh.round (#137441)
This adds a handler, visitGenericScalarHalfwordInst, which works for
mask.{add/sub/mul/div/max/min}.sh.round.

Updates the tests in https://github.com/llvm/llvm-project/pull/136260
2025-04-28 18:41:23 -07:00
Florian Hahn
d2ce88a939
[VPlan] Create initial skeleton before creating regions. (NFC)
Move out the logic to prepare for vectorization to a separate transform,
before creating loop regions. This was discussed as follow-up
in https://github.com/llvm/llvm-project/pull/136455.

This just moves the existing code around slightly  and will simplify
follow-up patches to include the exiting edges during initial VPlan
construction.
2025-04-28 21:51:32 +01:00
Florian Hahn
043b04acff
Reapply "[VPlan] Fold NOT into predicate of wide compares." (#130347)
This reverts commit 8dd160f4767f971572eac065c8650d9202ff5bf9.

The recommit contains an adjustment to planContainsAdditionalSimplifications,
which considers changes to the original predicate for compares.

Original commit message:

Add simplification to fold negation into a compare, if the negation is
the only user of the compare. This removes a number of redundant
negations.

Alive2 Proofs for FPCMP test changes:  https://alive2.llvm.org/ce/z/WGDz9U

PR: https://github.com/llvm/llvm-project/pull/129430
2025-04-28 20:01:37 +01:00
Krzysztof Pszeniczny
acaf403c63
[SampleProfile] Fix UB in Demangler invocation. (#137659)
Currently the backing buffer of a `std::vector<char>` is passed[1] to
`Demangler.getFunctionBaseName`. However, deeply inside the call stack
`OutputBuffer::grow` will call[2] `std::realloc` if it needs to grow the
buffer, leading to UB.

The demangler APIs specify[3] that "`Buf` and `N` behave like the second
and third parameters to `__cxa_demangle`" and the docs for the latter
say[4] that the output buffer must be allocated with `malloc` (but can
also be `NULL` and will then be realloced accordingly).

Note: PR #135863 changed this from a stack array to a `std::vector` and
increased the size to 65K, but this can still lead to a crash if the
demangled name is longer than that - yes, I'm surprised that a >65K-long
function name happens in practice...

[1]:
d7e631c7cd/llvm/lib/Transforms/IPO/SampleProfileMatcher.cpp (L744)
[2]:
d7e631c7cd/llvm/include/llvm/Demangle/Utility.h (L50)
[3]:
d7e631c7cd/llvm/include/llvm/Demangle/Demangle.h (L92-L93)
[4]:
https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html
2025-04-28 19:28:56 +02: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
Alexey Bataev
73d90ec825 [SLP][NFC]Consider non-profitable trees with only phis, gathers, splits and small nodes with reuses
Improves compile time for non-profitable cases.
Fixes #135965
2025-04-28 03:56:08 -07:00
Florian Hahn
ec1016f7ef
[IVDescriptors] Support reductions with minimumnum/maximumnum. (#137335)
Add a new reduction recurrence kind for reductions with
minimumnum/maximumnum. Such reductions can be vectorized without
nsz/nnans, same as reductions with maximum/minimum intrinsics.

Note that a new reduction kind is needed to make sure partial reductions
are also combined with minimumnum/maximumnum.

Note that the final reduction to a scalar value is performed with
vector.reduce.fmin/fmax. This should be fine, as the results of the
partial reductions with maximumnum/minimumnum silences any sNaNs.

In-loop and reductions in SLP are not supported yet, as there's no
reduction version of maximumnum/minimumnum yet and fmax may be
incorrect.

PR: https://github.com/llvm/llvm-project/pull/137335
2025-04-28 11:16:36 +01:00
Yingwei Zheng
a0c4876eed
[InstCombine] Fix ninf propagation for fcmp+sel -> minmax (#136433)
Proof: https://alive2.llvm.org/ce/z/nCrvfr
Closes https://github.com/llvm/llvm-project/issues/136430
2025-04-28 17:24:46 +08:00
Yingwei Zheng
1f69d6354a
[InstCombine] Preserve the sign bit of NaN in SimplifyDemandedUseFPClass (#137287)
Alive2: https://alive2.llvm.org/ce/z/uiUzEf

Closes https://github.com/llvm/llvm-project/issues/137196.

Note: To avoid regression in
`ret_nofpclass_nopositives_copysign_nnan_flag`, the second commit takes
FMF into account.
2025-04-28 17:01:43 +08:00
Florian Hahn
92bfbbc4e5
[VPlan] Invert condition if needed when creating inner regions. (#132292)
As pointed out by @iamlouk in
https://github.com/llvm/llvm-project/pull/129402, the current code
doesn't handle latches with different successor orders correctly.
Introduce a `NOT`, if needed.

Depends on  https://github.com/llvm/llvm-project/pull/129402

PR: https://github.com/llvm/llvm-project/pull/132292
2025-04-28 09:40:43 +01:00
Nikita Popov
50aacb9e1b
[InstCombine] Support ptrtoint of gep folds for chain of geps (#137323)
Support the ptrtoint(gep null, x) -> x and ptrtoint(gep inttoptr(x), y)
-> x+y folds for the case where there is a chain of geps that ends in
null or inttoptr. This avoids some regressions from #137297.
    
While here, also be a bit more careful about edge cases like pointer to
vector splats and mismatched pointer and index size.
2025-04-28 09:02:29 +02:00
Luke Lau
92c3af7c3e
[VPlan] Use correct constructor when cloning VPWidenIntrinsicRecipe without underlying CallInst (#137493)
I noticed this when working on a patch downstream, and I don't think
this is an issue upstream yet.

But if a VPWidenIntrinsicRecipe is created without an underlying
CallInst, e.g. in createEVLRecipe, it will crash if you try to clone it
because it assumes the CallInst always exists.

This fixes it by using the CallInst-less constructor in this case.
2025-04-28 10:08:45 +08:00
Owen Rodley
d3d856ad84
Clean up external users of GlobalValue::getGUID(StringRef) (#129644)
See https://discourse.llvm.org/t/rfc-keep-globalvalue-guids-stable/84801
for context.

This is a non-functional change which just changes the interface of
GlobalValue, in preparation for future functional changes. This part
touches a fair few users, so is split out for ease of review. Future
changes to the GlobalValue implementation can then be focused purely on
that class.

This does the following:

* Rename GlobalValue::getGUID(StringRef) to
  getGUIDAssumingExternalLinkage. This is simply making explicit at the
  callsite what is currently implicit.
* Where possible, migrate users to directly calling getGUID on a
  GlobalValue instance.
* Otherwise, where possible, have them call the newly renamed
  getGUIDAssumingExternalLinkage, to make the assumption explicit.


There are a few cases where neither of the above are possible, as the
caller saves and reconstructs the necessary information to compute the
GUID themselves. We want to migrate these callers eventually, but for
this first step we leave them be.
2025-04-28 11:09:43 +10:00
Kazu Hirata
5cfd81b0cc
[llvm] Use range constructors of *Set (NFC) (#137552) 2025-04-27 15:59:57 -07:00
Kazu Hirata
52fcb076c0
[llvm] Use llvm::transform (NFC) (#137532) 2025-04-27 12:32:12 -07:00
Kazu Hirata
1f56716a7e
[llvm] Use hash_combine_range with ranges (NFC) (#137530) 2025-04-27 12:31:28 -07:00
Florian Hahn
2e934170b0
[LV] Remove LoopVectorizationLegality from InnerLoopVectorizer (NFC).
a51e28278 removed the last real use of Legal in InnerLoopVectorizer. Now
that it isn't used any longer, remove it to avoid new users being
introduced.
2025-04-27 20:30:48 +01:00
Kazu Hirata
2e230f5685
[llvm] Use llvm::interleaved (NFC) (#137496) 2025-04-26 23:28:46 -07:00
Kazu Hirata
9c356b233c
[Utils] Use llvm::partition (NFC) (#137494) 2025-04-26 23:28:07 -07:00
Kazu Hirata
8210cdd764
[llvm] Use llvm::replace (NFC) (#137481) 2025-04-26 18:18:09 -07:00
Kazu Hirata
8ba3a232d1
[llvm] Use llvm::copy (NFC) (#137470) 2025-04-26 15:50:38 -07:00
Florian Hahn
826f237cb4
[VPlan] Don't added separate vector latch block (NFC).
Simplify initial VPlan construction by not creating a separate
vector.latch block, which isn't needed and will get folded away later.
This has been suggested as independent clean-up multiple times.
2025-04-26 22:03:18 +01:00
sallto
419a2cb218
[Inliner] Preserve alignment of byval arguments (#137455)
Previously the inliner always produced a memcpy with alignment 1 for src
and destination, leading to potentially suboptimal Codegen.

Since the Src ptr alignment is only available through the CallBase it
has to be passed to HandleByValArgumentInit. Dst Alignment is already
known so it doesn't have to be passed along.

If there is no specified Src Alignment my changes cause the ptr to have
no align data attached instead of align 1 as before (see
inline-tail.ll), I believe this is fine but since I'm a first time
contributor, please confirm.

My changes are already covered by 4 existing regression tests, so I did
not add any additional ones.

The example from #45778 now results in:
```C
opt -S -passes=inline,instcombine,sroa,instcombine test.ll

define dso_local i32 @test(ptr %t) {
entry:
  %.sroa.0.0.copyload = load ptr, ptr %t, align 8       # this used to be align 1 in the original issue
  %arrayidx.i = getelementptr inbounds nuw i8, ptr %.sroa.0.0.copyload, i64 24
  %0 = load i32, ptr %arrayidx.i, align 4
  ret i32 %0
}
```

Fixes #45778.
2025-04-26 21:38:58 +02:00
Abid Qadeer
58430692fc
[CodeExtractor] Improve debug info for input values. (#136016)
If we use `CodeExtractor` to extract the block1 into a new function,

```
define void @foo() !dbg !2 {
entry:
  %1 = alloca i32, i64 1, align 4
  %2 = alloca i32, i64 1, align 4
  #dbg_declare(ptr %1, !8, !DIExpression(), !1)
  br label %block1

block1:
  store i32 1, ptr %1, align 4
  store i32 2, ptr %2, align 4
  #dbg_declare(ptr %2, !10, !DIExpression(), !1)
  ret void
}
```

it will look like the extracted function shown below (with some
irrelevent details removed).

```
define internal void @extracted(ptr %arg0, ptr %arg1) { 
newFuncRoot:
  br label %block1

block1:
  store i32 1, ptr %arg0, align 4
  store i32 2, ptr %arg1, align 4
  ret void
}
```

You will notice that it has replaced the usage of values that were in
the parent function (%1 and %2) with the arguments to the new function.
But it did not do the same thing with `#dbg_declare` which was simply
dropped because its location pointed to a value outside of the new
function. Similarly arg0 is without any debug record, although the value
that it replaced had one and we could materialize one for it based on
that.

This is not just a theoretical limitations. `CodeExtractor` is used to
create functions that implement many of the `OpenMP` constructs in
`OMPIRBuilder`. As a result of these limitations, the debug information
is missing from the created functions.

This PR tries to address this problem. It iterates over the input to the
extracted function and looks at their debug uses. If they were present
in the new function, it updates their location. Otherwise it materialize
a similar usage in the new function.

Most of these changes are localized in `fixupDebugInfoPostExtraction`.
Only other change is to propagate function inputs and the replacement
values to it.

---------

Co-authored-by: Tim Gymnich <tim@gymni.ch>
Co-authored-by: Michael Kruse <llvm-project@meinersbur.de>
2025-04-26 10:12:44 +01:00
LU-JOHN
571e024d00
[Sink][NFC] Move all checks for unsafe instructions into one function (#137398)
Move check for instruction that is unsafe to sink into isSafeToMove
function.

Signed-off-by: John Lu <John.Lu@amd.com>
2025-04-26 10:10:27 +02:00