28741 Commits

Author SHA1 Message Date
Matt Arsenault
f5c8242042
SimplifyLibCalls: Prefer to emit intrinsic in pow(2, x) -> ldexp(1, x) (#92363) 2024-05-17 14:28:03 +02:00
David Sherwood
0ad275c158
[InstCombine] Fold vector.reduce.op(vector.reverse(X)) -> vector.reduce.op(X) (#91743)
For all of the following reductions:

vector.reduce.or
vector.reduce.and
vector.reduce.xor
vector.reduce.add
vector.reduce.mul
vector.reduce.umin
vector.reduce.umax
vector.reduce.smin
vector.reduce.smax
vector.reduce.fmin
vector.reduce.fmax

if the input operand is the result of a vector.reverse then we can
perform a reduction on the vector.reverse input instead since the answer
is the same. If the reassociation is permitted we can also do the same
folds for these:

vector.reduce.fadd
vector.reduce.fmul
2024-05-17 12:58:14 +01:00
Florian Hahn
1e7d047c71
[VPlan] Mark LoopInfo preserved in native-path as well (NFC).
LoopInfo is updated during VPlan execution now, so it will also be
updated correctly in the native path.
2024-05-17 12:18:01 +01:00
Shan Huang
d0e2808f80
[DebugInfo][LoopLoadElim] Fix missing debug location updates (#91839) 2024-05-17 10:56:05 +01:00
DianQK
c79690040a
[GlobalOpt] Don't replace aliasee with alias that has weak linkage (#91483)
Fixes #91312.

Don't perform the transform if the alias may be replaced at link time.
2024-05-17 05:51:49 +08:00
Noah Goldstein
23f1047daa [InstCombine] Fold (icmp pred (trunc nuw/nsw X), C) -> (icmp pred X, (zext/sext C))
This is valid as long as the sign of the wrap flag doesn't differ from
the sign of the `pred`.

Proofs: https://alive2.llvm.org/ce/z/35NsrR

NB: The online Alive2 hasn't been updated with `trunc nuw/nsw`
support, so the proofs must be reproduced locally.

Closes #87935
2024-05-16 13:03:32 -05:00
Noah Goldstein
ebbf484e1c [InstCombine] Add tests for folding (icmp pred (trunc nuw/nsw X), C); NFC 2024-05-16 13:03:32 -05:00
Noah Goldstein
05347f8c2f [ValueTracking] Compute knownbits from (icmp upred (add/sub nuw X, Y), C)
`(icmp ule/ult (add nuw X, Y), C)` implies both `(icmp ule/ult X, C)` and
`(icmp ule/ult Y, C)`. We can use this to deduce leading zeros in `X`/`Y`.

`(icmp uge/ugt (sub nuw X, Y), C)` implies `(icmp uge/uge X, C)` . We
can use this to deduce leading ones in `X`.

Proofs: https://alive2.llvm.org/ce/z/sc5k22

Closes #87180
2024-05-16 13:03:32 -05:00
Noah Goldstein
80a0a067fb [ValueTracking] Add tests for computing knownbits from (icmp upred (add/sub nuw X, Y), C); NFC 2024-05-16 13:03:32 -05:00
Tim Besard
e8692b88be
[NewPM] Add pass options for InternalizePass to preserve GVs (reland) (#92383)
Reland of https://github.com/llvm/llvm-project/pull/91334, which broke
the gcc7 buildbot and was reverted in
https://github.com/llvm/llvm-project/pull/92321.
Work around the failure by being explicit about returning an `Expected`.

cc @joker-eph
2024-05-16 09:18:37 -07:00
Matt Arsenault
cdb41e416a
PlaceSafepoints: Fix using default constructed TargetLibraryInfo (#92411) 2024-05-16 17:54:26 +02:00
Simon Pilgrim
54e52aa5eb
[X86] Reduce znver3/4 LoopMicroOpBufferSize to practical loop unrolling values (#91340)
The znver3/4 scheduler models have previously associated the LoopMicroOpBufferSize with the maximum size of their op caches, and when this led to quadratic complexity issues this were reduced to a value of 512 uops, based mainly on compilation time and not its effectiveness on runtime performance.

From a runtime performance POV, a large LoopMicroOpBufferSize leads to a higher number of loop unrolls, meaning the cpu has to rely on the frontend decode rate (4 ins/cy max) for much longer to fill the op cache before looping begins and we make use of the faster op cache rate (8/9 ops/cy).

This patch proposes we instead cap the size of the LoopMicroOpBufferSize based off the maximum rate from the op cache (znver3 = 8op/cy, znver4 = 9op/cy) and the branch misprediction penalty from the opcache (~12cy) as a estimate of the useful number of ops we can unroll a loop by before mispredictions are likely to cause stalls. This isn't a perfect metric, but does try to be closer to the spirit of how we use LoopMicroOpBufferSize in the compiler vs the size of a similar naming buffer in the cpu.
2024-05-16 14:44:00 +01:00
XChy
fdaad73875
[Reg2Mem] Handle CallBr instructions (#90953)
Fixes #90900
2024-05-16 20:13:39 +08:00
Yingwei Zheng
46bc54f4e6
[ValueTracking] Fix assertion failure when computeKnownFPClass returns fcNone (#92355)
Fixes
https://github.com/llvm/llvm-project/pull/92084#issuecomment-2114083188.
2024-05-16 19:14:30 +08:00
Dmitri Gribenko
83974a4b92 Revert "[LoopUnroll] Clamp PartialThreshold for large LoopMicroOpBufferSize (#67657)"
This reverts commit f0b3654701bde1cf7821d60698b42383edaff9f3.

This commit triggers UB by reading an uninitialized variable.

`UP.PartialThreshold` is used uninitialized in `getUnrollingPreferences()` when
it is called from `LoopVectorizationPlanner::executePlan()`. In this case the
`UP` variable is created on the stack and its fields are not initialized.

```
==8802==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x557c0b081b99 in llvm::BasicTTIImplBase<llvm::X86TTIImpl>::getUnrollingPreferences(llvm::Loop*, llvm::ScalarEvolution&, llvm::TargetTransformInfo::UnrollingPreferences&, llvm::OptimizationRemarkEmitter*) llvm-project/llvm/include/llvm/CodeGen/BasicTTIImpl.h
    #1 0x557c0b07a40c in llvm::TargetTransformInfo::Model<llvm::X86TTIImpl>::getUnrollingPreferences(llvm::Loop*, llvm::ScalarEvolution&, llvm::TargetTransformInfo::UnrollingPreferences&, llvm::OptimizationRemarkEmitter*) llvm-project/llvm/include/llvm/Analysis/TargetTransformInfo.h:2277:17
    #2 0x557c0f5d69ee in llvm::TargetTransformInfo::getUnrollingPreferences(llvm::Loop*, llvm::ScalarEvolution&, llvm::TargetTransformInfo::UnrollingPreferences&, llvm::OptimizationRemarkEmitter*) const llvm-project/llvm/lib/Analysis/TargetTransformInfo.cpp:387:19
    #3 0x557c0e6b96a0 in llvm::LoopVectorizationPlanner::executePlan(llvm::ElementCount, unsigned int, llvm::VPlan&, llvm::InnerLoopVectorizer&, llvm::DominatorTree*, bool, llvm::DenseMap<llvm::SCEV const*, llvm::Value*, llvm::DenseMapInfo<llvm::SCEV const*, void>, llvm::detail::DenseMapPair<llvm::SCEV const*, llvm::Value*>> const*) llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:7624:7
    #4 0x557c0e6e4b63 in llvm::LoopVectorizePass::processLoop(llvm::Loop*) llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:10253:13
    #5 0x557c0e6f2429 in llvm::LoopVectorizePass::runImpl(llvm::Function&, llvm::ScalarEvolution&, llvm::LoopInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::BlockFrequencyInfo*, llvm::TargetLibraryInfo*, llvm::DemandedBits&, llvm::AssumptionCache&, llvm::LoopAccessInfoManager&, llvm::OptimizationRemarkEmitter&, llvm::ProfileSummaryInfo*) llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:10344:30
    #6 0x557c0e6f2f97 in llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:10383:9

[...]

  Uninitialized value was created by an allocation of 'UP' in the stack frame
    #0 0x557c0e6b961e in llvm::LoopVectorizationPlanner::executePlan(llvm::ElementCount, unsigned int, llvm::VPlan&, llvm::InnerLoopVectorizer&, llvm::DominatorTree*, bool, llvm::DenseMap<llvm::SCEV const*, llvm::Value*, llvm::DenseMapInfo<llvm::SCEV const*, void>, llvm::detail::DenseMapPair<llvm::SCEV const*, llvm::Value*>> const*) llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:7623:3
```
2024-05-16 12:11:42 +02:00
Matt Arsenault
0ea178b085
SimplifyLibCalls: Emit vector ldexp intrinsics in exp2->ldexp combine (#92219)
Co-authored-by: Nikita Popov <github@npopov.com>
2024-05-16 10:24:56 +02:00
Matt Arsenault
ce1ce5d30c
InstCombine: Try to use exp10 intrinsic instead of libcall (#92287)
Addresses old TODO about the exp10 intrinsic not existing.
2024-05-16 09:09:02 +02:00
Craig Topper
487b43cdc9
[RISCV] Pass subvector type to isLegalInterleavedAccessType in getInterleavedMemoryOpCost. (#91825)
isLegalInterleavedAccessType expects the subvector type, but
getInterleavedMemoryOpCost is called with the full vector type. So we
need to divide by Factor.
2024-05-15 21:47:29 -07:00
Nikita Popov
83e61d03de [SeparateConstOffsetFromGEP] Add tests for multiple indices (NFC) 2024-05-16 12:20:18 +09:00
Nikita Popov
b4d1a606c7 [SeparateConstOffsetFromGEP] Check correct index for non-negativity
We were checking the index of GEP twice, instead of checking both
GEP and PtrGEP.
2024-05-16 11:59:07 +09:00
Nikita Popov
31c903890a [SeparateConstOffsetFromGEP] Add additional inbounds preservation tests (NFC)
Adding these for NVPTX because for AMDGPU the problematic -1 case
does not get reordered in the first place.
2024-05-16 11:59:07 +09:00
Nikita Popov
f0b3654701
[LoopUnroll] Clamp PartialThreshold for large LoopMicroOpBufferSize (#67657)
The znver3/znver4 scheduler models are outliers, specifying very large
LoopMicroOpBufferSizes at 512, while typical values for other subtargets
are on the order of ~50. Even if this information is
micro-architecturally correct (*), this does not mean that we want to
runtime unroll all loops to a size that completely fills the loop
buffer. Unless this is the single hot loop in the entire application,
the massive code size increase will bust the micro-op and instruction
caches.

Protect against this by clamping to the default PartialThreshold of 150,
which is the same as the default full-unroll threshold and half the
aggressive full-unroll threshold. Allowing more partial unrolling than
full unrolling certainly does not make sense.

(*) I strongly doubt that this is actually correct -- I believe this may
derive from an incorrect reading of Agner Fog's micro-architecture
guide. The number 4096 that was originally used here is the size of the
general micro-op cache, not that of a loop buffer. A separate loop
buffer is not listed for the Zen microarchitecture. Comparing this to
the listing for Skylake, it has a 1536 micro-op buffer, but only a 64
micro-op loopback buffer, with a note that it's rarely fully utilized.
Our scheduling model specifies LoopMicroOpBufferSize of 50 in that case.
2024-05-16 10:21:22 +09:00
Mehdi Amini
537a94b2ef
Revert "[NewPM] Add pass options for InternalizePass to preserve GVs." (#92321)
Reverts llvm/llvm-project#91334

This broke the gcc7 build.
I suspect the issue is a mismatch on user-defined move constructor on
the return: `return PreservedGVs;` does not match the return type of the
function.
2024-05-15 15:06:08 -07:00
Tim Besard
ee765b0c94
[NewPM] Add pass options for InternalizePass to preserve GVs. (#91334)
This PR adds a string interface to `InternalizePass`' `MustPreserveGV`
option, which is a callback function to indicate if a GV is not to be
internalized. This is for use in LLVM.jl, the Julia wrapper for LLVM,
which uses the C API and is thus required to use the PassBuilder string
API for building NewPM pipelines.
2024-05-15 13:17:29 -07:00
Hans
3bb39690d7
[coro] Lower llvm.coro.await.suspend.handle to resume with tail call (#89751)
The C++ standard requires that symmetric transfer from one coroutine to
another is performed via a tail call. Failure to do so is a miscompile
and often breaks programs by quickly overflowing the stack.

Until now, the coro split pass tried to ensure this in the
`addMustTailToCoroResumes()` function by searching for
`llvm.coro.resume` calls to lower as tail calls if the conditions were
right: the right function arguments, attributes, calling convention
etc., and if a `ret void` was sure to be reached after traversal with
some ad-hoc constant folding following the call.

This was brittle, as the kind of implicit variants required for a tail
call to happen could easily be broken by other passes (e.g. if some
instruction got in between the `resume` and `ret`), see for example
9d1cb18d19862fc0627e4a56e1e491a498e84c71 and
284da049f5feb62b40f5abc41dda7895e3d81d72.

Also the logic seemed backwards: instead of searching for possible tail
call candidates and doing them if the circumstances are right, it seems
better to start with the intention of making the tail calls we need, and
forcing the circumstances to be right.

Now that we have the `llvm.coro.await.suspend.handle` intrinsic (since
f78688134026686288a8d310b493d9327753a022) which corresponds exactly to
symmetric transfer, change the lowering of that to also include the
`resume` part, always lowered as a tail call.
2024-05-15 15:29:08 +02:00
Pietro Ghiglio
83d9aa2768
[VPlan] Add scalar inferencing support for addrspace cast (#92107)
Fixes https://github.com/llvm/llvm-project/issues/91434

PR: https://github.com/llvm/llvm-project/pull/92107
2024-05-15 14:03:21 +01:00
Jay Foad
1650f1b3d7
Fix typo "indicies" (#92232) 2024-05-15 13:10:16 +01:00
Florian Hahn
b0a1ae2cca
[LV] Add additional variants of tests with udiv/urem/sdiv/srem in TC.
Add additional tests with udiv/urem/sdiv/srem in trip counts, where the
divisor is constant.

For https://github.com/llvm/llvm-project/pull/92177.
2024-05-15 11:17:23 +01:00
Florian Hahn
d187005cad
[VPlan] Update VPBlendRecipe codegen for for first-lane only.
Update VPBlendRecipe::execute to support generating code for first-lane
only. This fixes a crash in the newly added test
@test_not_first_lane_only_wide_compare_incoming_order_swapped.
2024-05-15 11:00:15 +01:00
Matt Arsenault
d7bb0723fe
InstCombine: Emit ldexp intrinsic in exp2->ldexp combine (#92039)
Prefer to emit the intrinsic over a libcall in the
intrinsic or no-math-errno case.
2024-05-15 07:41:28 +02:00
Matt Arsenault
847c83f7cc
InstCombine: Process addrspacecast uses in PointerReplacer (#91953)
This was looking through an addrspacecast, and not finding a later
unfoldable cast to another address space. Fixes improperly deleting
a required alloca + memcpy and introducing an illegal addrspacecast.
    
This also required fixing some worklist management issues with
addrspacecast, and assuming that only memcpy sources could need
replacement.
    
Regresses one test function, but this looks like it optimized
before by accident. It never saw the pointer use by the call
to readonly_callee, which should require insertion of a new cast.
    
Fixes #68120
2024-05-15 07:02:31 +02:00
AtariDreams
4d1ecf1923
[Transforms] Preserve inbounds attribute of transformed GEPs when flattening loops (#86961)
When flattening the loop, if the GEP was inbound, it should stay
inbound, because the only thing that changed is how the pointers are
calculated, not the elements being accessed.

Proof: https://alive2.llvm.org/ce/z/dApMpQ
2024-05-15 10:26:23 +09:00
Philip Reames
baca93fc83 [LSR] Tweak debug output to always print initial cost 2024-05-14 13:34:20 -07:00
Florian Hahn
cf5db39907
[LV] Add tests with trip counts containing UDIV expressions.
Add test cases for
https://github.com/llvm/llvm-project/issues/89958.
2024-05-14 20:28:27 +01:00
Florian Hahn
67d840b60f
[VPlan] Relax over-aggressive assertion in VPTransformState::get().
There are cases where a vector value has some users that demand the
the single scalar value only (NeedsScalar), while other users demand the
vector value (see attached test cases). In those cases, the NeedsScalar
users should only demand the first lane.

Fixes https://github.com/llvm/llvm-project/issues/91883.
2024-05-14 19:10:49 +01:00
AdityaK
bf7a0f9958
Fix incorrect codegen with respect to GEPs #85333 (#92047)
As mentioned in #68882 and
https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699

Gep arithmetic isn't consistent with different types. GVNSink didn't
realize this and sank all geps as long as their operands can be wired
via PHIs
in a post-dominator.

Fixes: #85333
Reapply: #88440 after fixing the non-determinism issues in #90995
2024-05-14 06:13:11 -07:00
wanglei
9d4f7f44b6 [test][LoongArch] Add -mattr=+d option. NFC
Because most of tests assume target-abi=`lp64d`, adding the
corresponding feature is reasonable.

rg -l loongarch -g '!*.s' | xargs sed -i '/mtriple=loongarch/ {/-mattr=/!{/target-abi/! s/mtriple=loongarch.. /&-mattr=+d /}}'
2024-05-14 20:23:04 +08:00
Yingwei Zheng
3aae916ff7
Reland "[ValueTracking] Compute knownbits from known fp classes" (#92084)
This patch relands https://github.com/llvm/llvm-project/pull/86409.

I mistakenly thought that `Known.makeNegative()` clears the sign bit of
`Known.Zero`. This patch fixes the assertion failure by explicitly
clearing the sign bit.
2024-05-14 18:10:28 +08:00
Florian Hahn
632317e9ab
[VPlan] Add non-poison propagating LogicalAnd VPInstruction opcode. (#91897)
Add a new opcode to mode non-poison propagating logical AND operations
used when generating edge masks. This follows the similar decision to
model Not as dedicated opcode as well, to improve clarity.

This also helps to simplify the matchers for
https://github.com/llvm/llvm-project/pull/89386.


PR: https://github.com/llvm/llvm-project/pull/91897
2024-05-14 09:42:49 +01:00
Martin Storsjö
2e165a2c4b Revert "[ValueTracking] Compute knownbits from known fp classes (#86409)"
This reverts commit d03a1a6e5838c7c2c0836d71507dfdf7840ade49.

This change caused failed assertions, see
https://github.com/llvm/llvm-project/pull/86409#issuecomment-2109469845
for details.
2024-05-14 10:37:23 +03:00
Nikita Popov
b7adba8e78 [LICM] Add must exec hoisting test with commuted operands (NFC) 2024-05-14 12:29:20 +09:00
Nikita Popov
3a25e358e2 [LICM] Generate test checks (NFC) 2024-05-14 12:26:15 +09:00
Lei Wang
5b6f151104
[SampleFDO] Improve stale profile matching by diff algorithm (#87375)
This change improves the matching algorithm by using the diff algorithm,
the current matching algorithm only processes the callsites grouped by
the same name functions, it doesn't consider the order relationships
between different name functions, this sometimes fails to handle this
ambiguous anchor case. For example. (`Foo:1` means a
calliste[callee_name: callsite_location])
```
IR :      foo:1  bar:2  foo:4  bar:5 
Profile :        bar:3  foo:5  bar:6
```
The `foo:1` is matched to the 2nd `foo:5` and using the diff
algorithm(finding longest common subsequence ) can help on this issue.
One well-known diff algorithm is the Myers diff algorithm(paper "An
O(ND) Difference Algorithm and Its Variations∗" Eugene W. Myers), its
variations have been implemented and used in many famous tools, like the
GNU diff or git diff. It provides an efficient way to find the longest
common subsequence or the shortest edit script through graph searching.
There are several variations/refinements for the algorithm, but as in
our case, the num of function callsites is usually very small, so we
implemented the basic greedy version in this change which should be good
enough.
We observed better matchings and positive perf improvement on our
internal services.
2024-05-13 16:01:29 -07:00
Fangrui Song
ef9090fcb5 [test] Fix check prefixes 2024-05-13 14:01:00 -07:00
Fangrui Song
4a67f80982 [test] Fix check prefixes 2024-05-13 11:25:12 -07:00
Yingwei Zheng
d03a1a6e58
[ValueTracking] Compute knownbits from known fp classes (#86409)
This patch calculates knownbits from fp instructions/dominating fcmp
conditions. It will enable more optimizations with signbit idioms.
2024-05-14 01:58:45 +08:00
chenlin
79643565a8
[LoopUnroll] Remove redundant debug instructions after blocks have been merged (#91246)
Remove redundant debug instructions after blocks have been merged into
the predecessor, It can reduce some compile time in some cases.

This change only fixes the situation of loop unrolling, and other
situations are not considered. "RemoveRedundantDbgInstrs" seems to be
very time-consuming. Thus, we just add here after the "Dest" has been
merged into the "Fold", this may be a more targeted solution!!!

fixes: https://github.com/llvm/llvm-project/issues/89073
2024-05-13 09:42:04 -07:00
Matt Arsenault
c5b0da9d83
InstCombine: Preserve inbounds in PointerReplacer (#91735)
This avoids spurious test changes in a future commit.
2024-05-13 13:49:09 +02:00
David Green
220756f1f9 [AArch64][Inline] Regenerate Inline/AArch64/binop.ll test check lines. NFC
Should hopefully help with #91854
2024-05-13 09:49:09 +01:00
Yingwei Zheng
b5f4210e9f
[InstCombine] Drop nuw flag when CtlzOp is a sub nuw (#91776)
See the following case:
```
define i32 @src1(i32 %x) {
  %dec = sub nuw i32 -2, %x
  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %dec, i1 false)
  %sub = sub nsw i32 32, %ctlz
  %shl = shl i32 1, %sub
  %ugt = icmp ult i32 %x, -2
  %sel = select i1 %ugt, i32 %shl, i32 1
  ret i32 %sel
}

define i32 @tgt1(i32 %x) {
  %dec = sub nuw i32 -2, %x
  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %dec, i1 false)
  %sub = sub nsw i32 32, %ctlz
  %and = and i32 %sub, 31
  %shl = shl nuw i32 1, %and
  ret i32 %shl
}
```
`nuw` in `%dec` should be dropped after the select instruction is
eliminated.

Alive2: https://alive2.llvm.org/ce/z/7S9529

Fixes https://github.com/llvm/llvm-project/issues/91691.
2024-05-13 14:27:59 +08:00