180 Commits

Author SHA1 Message Date
Nikita Popov
4b3ba64ba7
[SCEVExpander] Clear flags when reusing GEP (#109293)
As pointed out in the review of #102133, SCEVExpander currently
incorrectly reuses GEP instructions that have poison-generating flags
set. Fix this by clearing the flags on the reused instruction.
2024-10-01 14:22:54 +02:00
Mehdi Amini
68ddd6c80e
Revert "Fix LLVM_ENABLE_ABI_BREAKING_CHECKS macro check: use #if instead of #ifdef" (#110310)
Reverts llvm/llvm-project#110185

There are inconsistencies in some of these macros, which unfortunately
isn't caught by a single upstream bot.
2024-09-27 20:34:14 +02:00
Mehdi Amini
5e98136679
Fix LLVM_ENABLE_ABI_BREAKING_CHECKS macro check: use #if instead of #ifdef (#110185)
This macros is always defined: either 0 or 1. The correct pattern is to
use #if.
2024-09-27 11:52:22 +02:00
Nikita Popov
4ec4ac15ed
[SCEVExpander] Fix addrec cost model (#106704)
The current isHighCostExpansion cost model for addrecs computes the cost
for some kind of polynomial expansion that does not appear to have any
relation to addrec expansion whatsoever.

A literal expansion of an affine addrec is a phi and add (plus the
expansion of start and step). For a non-affine addrec, we get another
phi+add for each additional addrec nested in the step recurrence.

This partially `fixes` https://github.com/llvm/llvm-project/issues/53205
(the runtime unroll test case in this PR).
2024-09-19 09:39:35 +02:00
Stephen Tozer
d75f9dd1d2 Revert "[IR][NFC] Update IRBuilder to use InsertPosition (#96497)"
Reverts the above commit, as it updates a common header function and
did not update all callsites:

  https://lab.llvm.org/buildbot/#/builders/29/builds/382

This reverts commit 6481dc57612671ebe77fe9c34214fba94e1b3b27.
2024-06-24 18:00:22 +01:00
Stephen Tozer
6481dc5761
[IR][NFC] Update IRBuilder to use InsertPosition (#96497)
Uses the new InsertPosition class (added in #94226) to simplify some of
the IRBuilder interface, and removes the need to pass a BasicBlock
alongside a BasicBlock::iterator, using the fact that we can now get the
parent basic block from the iterator even if it points to the sentinel.
This patch removes the BasicBlock argument from each constructor or call
to setInsertPoint.

This has no functional effect, but later on as we look to remove the
`Instruction *InsertBefore` argument from instruction-creation
(discussed
[here](https://discourse.llvm.org/t/psa-instruction-constructors-changing-to-iterator-only-insertion/77845)),
this will simplify the process by allowing us to deprecate the
InsertPosition constructor directly and catch all the cases where we use
instructions rather than iterators.
2024-06-24 17:27:43 +01:00
Philip Reames
cb76896d6e
[SCEVExpander] Recognize urem idiom during expansion (#96005)
If we have a urem expression, emitting it as a urem is significantly
better that letting the fully expansion kick in. We have the risk of a
udiv or mul which could have previously been shared, but loosing that
seems like a reasonable tradeoff for being able to round trip a urem w/o
modification.
2024-06-19 08:40:04 -07:00
Simon Pilgrim
38a814f9bc Revert 291b415c6c39156c82c7cdefd7a6a67657fb6927 : [Misc] Use LLVM_ENABLE_ABI_BREAKING_CHECKS correctly (#94212)
The patch didn't consistently clean up `#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS` and '#if defined(LLVM_ENABLE_ABI_BREAKING_CHECKS)' paths, causing a lot of build failures
2024-06-10 15:11:15 +01:00
paperchalice
291b415c6c
[Misc] Use LLVM_ENABLE_ABI_BREAKING_CHECKS correctly (#94212)
`LLVM_ENABLE_ABI_BREAKING_CHECKS` is always defined:

72c901f5e5/llvm/include/llvm/Config/abi-breaking.h.cmake (L16C2-L16C15)
It uses `cmakedefine01` rather than `cmakedefine`, so
`LLVM_ENABLE_ABI_BREAKING_CHECKS` is always defined,
so the preprocessed code is probably not what the author wanted.
2024-06-10 20:24:11 +08:00
Florian Hahn
e949b54a5b
[LAA] Use PSE::getSymbolicMaxBackedgeTakenCount. (#93499)
Update LAA to use PSE::getSymbolicMaxBackedgeTakenCount which returns
the minimum of the countable exits.

When analyzing dependences and computing runtime checks, we need the
smallest upper bound on the number of iterations. In terms of memory
safety, it shouldn't matter if any uncomputable exits leave the loop,
as long as we prove that there are no dependences given the minimum of
the countable exits. The same should apply also for generating runtime
checks.

Note that this shifts the responsiblity of checking whether all exit
counts are computable or handling early-exits to the users of LAA.

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

PR: https://github.com/llvm/llvm-project/pull/93499
2024-06-04 22:23:30 +01:00
Andreas Jonson
ff3523f67b
[IR] Drop poison-generating return attributes when necessary (#89138)
Rename has/dropPoisonGeneratingFlagsOrMetadata to
has/dropPoisonGeneratingAnnotations and make it also handle
nonnull, align and range return attributes on calls, similar
to the existing handling for !nonnull, !align and !range metadata.
2024-04-18 15:27:36 +09:00
elhewaty
7d3924cee3
[IR] Add nowrap flags for trunc instruction (#85592)
This patch adds the nuw (no unsigned wrap) and nsw (no signed wrap)
poison-generating flags to the trunc instruction.

Discourse thread:
https://discourse.llvm.org/t/rfc-add-nowrap-flags-to-trunc/77453
2024-03-29 14:08:49 +08:00
Jeremy Morse
6b62a9135a [RemoveDIs] Reapply 3fda50d3915, insert instructions using iterators
I'd reverted this in 6c7805d5d1 after a bad stage. Original commit
messsage follows:

[NFC][RemoveDIs] Bulk update utilities to insert with iterators

As part of the RemoveDIs project we need LLVM to insert instructions using
iterators wherever possible, so that the iterators can carry a bit of
debug-info. This commit implements some of that by updating the contents of
llvm/lib/Transforms/Utils to always use iterator-versions of instruction
constructors.

There are two general flavours of update:
 * Almost all call-sites just call getIterator on an instruction
 * Several make use of an existing iterator (scenarios where the code is
   actually significant for debug-info)
The underlying logic is that any call to getFirstInsertionPt or similar
APIs that identify the start of a block need to have that iterator passed
directly to the insertion function, without being converted to a bare
Instruction pointer along the way.

I've also switched DemotePHIToStack to take an optional iterator: it needs
to take an iterator, and having a no-insert-location behaviour appears to
be important. The constructors for ICmpInst and FCmpInst have been updated
too. They're the only instructions that take block _references_ rather than
pointers for certain calls, and a future patch is going to make use of
default-null block insertion locations.

All of this should be NFC.
2024-03-04 13:14:39 +00:00
Jeremy Morse
6c7805d5d1 Revert "[NFC][RemoveDIs] Bulk update utilities to insert with iterators"
This reverts commit 3fda50d3915b2163a54a37b602be7783a89dd808.

Apparently I've missed a hunk while staging this; will back out for now.

Picked up here: https://lab.llvm.org/buildbot/#/builders/139/builds/60429/steps/6/logs/stdio
2024-02-29 16:50:22 +00:00
Jeremy Morse
3fda50d391 [NFC][RemoveDIs] Bulk update utilities to insert with iterators
As part of the RemoveDIs project we need LLVM to insert instructions using
iterators wherever possible, so that the iterators can carry a bit of
debug-info. This commit implements some of that by updating the contents of
llvm/lib/Transforms/Utils to always use iterator-versions of instruction
constructors.

There are two general flavours of update:
 * Almost all call-sites just call getIterator on an instruction
 * Several make use of an existing iterator (scenarios where the code is
   actually significant for debug-info)
The underlying logic is that any call to getFirstInsertionPt or similar
APIs that identify the start of a block need to have that iterator passed
directly to the insertion function, without being converted to a bare
Instruction pointer along the way.

I've also switched DemotePHIToStack to take an optional iterator: it needs
to take an iterator, and having a no-insert-location behaviour appears to
be important. The constructors for ICmpInst and FCmpInst have been updated
too. They're the only instructions that take block _references_ rather than
pointers for certain calls, and a future patch is going to make use of
default-null block insertion locations.

All of this should be NFC.
2024-02-29 16:39:09 +00:00
Nikita Popov
07292b7203
[LIR][SCEVExpander] Restore original flags when aborting transform (#82362)
SCEVExpanderCleaner will currently remove instructions created by
SCEVExpander, but not restore poison generating flags that it may have
dropped. As such, running LIR can currently spuriously drop flags
without performing any transforms.

Fix this by keeping track of original instruction flags in SCEVExpander.

Fixes https://github.com/llvm/llvm-project/issues/82337.
2024-02-21 10:13:41 +01:00
Florian Hahn
4db93e5d56
[IndVars] Recompute flags if needed in widenIVUse of IV increment. (#82352)
widenIVUse may hoist a wide induction increment and introduce new uses,
but does not recompute the wrap flags. In some cases this can make the
new uses of the wide IV inc more poisonous.

Update the code to recompute flags if needed when hoisting an IV. If
both the narrow and wide IV increment's flags match and we can re-use
the flags from the increments, there's no need to recompute the flags,
as the replacement won't make the new uses of the wide IV's increment
more poisonous.

Note that this also updates a stale comment which claimed that the widen
increment is only used if it dominates the new use.

The helper should also be used to guard the code added in da437330be,
which I am planning on doing separately once the helper lands.

Fixes https://github.com/llvm/llvm-project/issues/82243.
2024-02-20 14:03:25 +00:00
Nikita Popov
bec7181d5b [SCEVExpander] Don't use recursive expansion for ptr IV inc
Similar to the non-ptr case, directly create the getelementptr
instruction. Going through expandAddToGEP() no longer makes sense
with opaque pointers, where generating the necessary instruction
is trivial.

This avoids recursive expansion of (the SCEV of) StepV while the
IR is in an inconsistent state, in particular with an incomplete
IV phi node, which utilities may not be prepared to deal with.

Fixes https://github.com/llvm/llvm-project/issues/80954.
2024-02-07 11:27:26 +01:00
Nikita Popov
43dd1e84df [SCEV] Move canReuseInstruction() helper into SCEV (NFC)
To allow reusing it in IndVars.
2024-02-02 16:48:00 +01:00
Nikita Popov
5b8e1a6ebf
[SCEVExpander] Do not reuse disjoint or (#80281)
SCEV treats "or disjoint" the same as "add nsw nuw". However, when
expanding, we cannot generally replace an add SCEV node with an "or
disjoint" instruction. Just dropping the poison flag is insufficient in
this case, we would have to actually convert the or into an add.

This is a partial fix for #79861.
2024-02-02 10:52:05 +01:00
Florian Hahn
da437330be
[SCEVExp] Keep NUW/NSW if both original inc and isomporphic inc agree. (#79512)
We are replacing with a wider increment. If both OrigInc and
IsomorphicInc are NUW/NSW, then we can preserve them on the wider
increment; the narrower IsomorphicInc would wrap before the wider
OrigInc, so the replacement won't make IsomorphicInc's uses more
poisonous.

PR: https://github.com/llvm/llvm-project/pull/79512
2024-02-01 11:01:29 +00:00
Kazu Hirata
d7ff7c3d18 [Transforms] Use llvm::pred_size and llvm::pred_successors (NFC) 2024-01-25 18:17:20 -08:00
Florian Hahn
d88e3658ce
[SCEVExp] Move logic to replace congruent IV increments to helper (NFC).
Move logic to replace congruent IV increments to helper function, to
reduce the indentation by using early returns. This is in preparation
for a follow-up patch.
2024-01-25 21:40:31 +00:00
Nikita Popov
6c2fbc3a68
[IRBuilder] Add CreatePtrAdd() method (NFC) (#77582)
This abstracts over the common pattern of creating a gep with i8 element
type.
2024-01-12 14:21:21 +01:00
Philip Reames
ffb2af3ed6
[SCEVExpander] Attempt to reinfer flags dropped due to CSE (#72431)
LSR uses SCEVExpander to generate induction formulas. The expander
internally tries to reuse existing IR expressions. To do that, it needs
to strip any poison generating flags (nsw, nuw, exact, nneg, etc..)
which may not be valid for the newly added users.

This is conservatively correct, but has the effect that LSR will strip
nneg flags on zext instructions involved in trip counts in loop
preheaders. To avoid this, this patch adjusts the expanded to reinfer
the flags on the CSE candidate if legal for all possible users.

This should fix the regression reported in
https://github.com/llvm/llvm-project/issues/71200.

This should arguably be done inside canReuseInstruction instead, but
doing it outside is more conservative compile time wise. Both
canReuseInstruction and isGuaranteedNotToBePoison walk operand lists, so
right now we are performing work which is roughly O(N^2) in the size of
the operand graph. We should fix that before making the per operand step
more expensive. My tenative plan is to land this, and then rework the
code to sink the logic into more core interfaces.
2023-12-07 13:20:36 -08:00
Nikita Popov
192e7d3d52 [IRBuilder] Add IsNonNeg param to CreateZExt() (NFC) 2023-11-10 12:00:34 +01:00
Philip Reames
f8742b8d6a
[SCEV] Teach SCEVExpander to use zext nneg when possible (#70815)
zext nneg was recently added to the IR in #67982. Teaching SCEVExpander
to emit nneg when possible is valuable since SCEV may have proved
non-trivial facts about loop bounds which would otherwise be lost when
materializing the value.
2023-10-31 09:33:07 -07:00
Mikael Holmen
02eb38119e [SCEVExpander] Remove unused variable [NFC]
gcc warned about it:
 ../lib/Transforms/Utils/ScalarEvolutionExpander.cpp: In lambda function:
 ../lib/Transforms/Utils/ScalarEvolutionExpander.cpp:2104:22: warning: unused variable 'ARPtrTy' [-Wunused-variable]
  2104 |     if (PointerType *ARPtrTy = dyn_cast<PointerType>(ARTy)) {
       |                      ^~~~~~~
Fix the warning by removing the variable and turn dyn_cast into isa.
2023-09-29 10:35:59 +02:00
Nikita Popov
45778602f4 [SCEVExpander] Clarify absence of no-op casts (NFC)
Remove all the expandCodeFor() uses that specify an explicit type,
as well as InsertNoopCastOfTo() calls and most uses of
getEffectiveSCEVType().

The only place where no-op casts can now be inserted are public
expandCodeFor() uses.
2023-09-22 09:40:12 +02:00
Jie Fu
8ffe73b6aa [SCEV] Fix -Wunused-variable in ScalarEvolutionExpander.cpp (NFC)
llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp:1077:15: error: unused variable 'Start' [-Werror,-Wunused-variable]
  const SCEV *Start = Normalized->getStart();
              ^
1 error generated.
2023-09-22 15:23:09 +08:00
Nikita Popov
2d8d622c73 [SCEV] Require that addrec operands dominate the loop
SCEVExpander currently has special handling for the case where the
start or the step of an addrec do not dominate the loop header,
which is not used by any lit test.

Initially I thought that this is entirely dead code, because
addrec operands are required to be loop invariant. However,
SCEV currently allows creating an addrec with operands that are
loop invariant but defined *after* the loop.

This doesn't seem like a useful case to allow, and we don't
appear to be using this outside a single easy to adjust unit test.
2023-09-22 09:02:54 +02:00
Nikita Popov
65c053d67a [SCEVExpander] Drop ExpandTy argument from expandIVInc() (NFC)
Check the type of the phi node instead (as the comment already
indicates).
2023-09-21 16:20:41 +02:00
Nikita Popov
eb31208be1 [SCEVExpander] Drop Ty argument from expandAddToGEP() (NFC)
We can directly use the type of Offset here.
2023-09-21 16:15:49 +02:00
Nikita Popov
3301fd2147 [SCEVExpander] Remove some unnecessary effective type handling (NFC)
A lot of SCEV expressions only work on integers -- in which case
the effective type will always be the same as the type.

There is a lot more cleanup to do here.
2023-09-21 16:04:38 +02:00
Nikita Popov
32e15ae6e9 [SCEVExpander] Remove unnecessary expandCodeForImpl() wrapper (NFC)
expandCodeFor() was directly calling expandCodeForImpl(). Drop the
Impl variant.
2023-09-21 15:02:44 +02:00
Jeremy Morse
e54277fa10 [NFC][RemoveDIs] Use iterators over inst-pointers when using IRBuilder
This patch adds a two-argument SetInsertPoint method to IRBuilder that
takes a block/iterator instead of an instruction, and updates many call
sites to use it. The motivating reason for doing this is given here [0],
we'd like to pass around more information about the position of debug-info
in the iterator object. That necessitates passing iterators around most of
the time.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939

Differential Revision: https://reviews.llvm.org/D152468
2023-09-11 20:01:19 +01:00
Jeremy Morse
6942c64e81 [NFC][RemoveDIs] Prefer iterator-insertion over instructions
Continuing the patch series to get rid of debug intrinsics [0], instruction
insertion needs to be done with iterators rather than instruction pointers,
so that we can communicate information in the iterator class. This patch
adds an iterator-taking insertBefore method and converts various call sites
to take iterators. These are all sites where such debug-info needs to be
preserved so that a stage2 clang can be built identically; it's likely that
many more will need to be changed in the future.

At this stage, this is just changing the spelling of a few operations,
which will eventually become signifiant once the debug-info bearing
iterator is used.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939

Differential Revision: https://reviews.llvm.org/D152537
2023-09-11 11:48:45 +01:00
Nikita Popov
1c6e6432ca [SCEVExpander] Fix incorrect reuse of more poisonous instructions (PR63763)
SCEVExpander tries to reuse existing instruction with the same
SCEV expression. However, doing this replacement blindly is not
safe, because the instruction might be more poisonous.

What we were already doing is to drop poison-generating flags on
the reused instruction. But this is not the only way that more
poison can be introduced. The poison-generating flag might not
be directly on the reused instruction, or the poison contribution
might come from something like 0 * %var, which folds to 0 but can
still introduce poison.

This patch fixes the issue in a principled way, by determining which
values can contribute poison to the SCEV expression, and then
checking whether any additional values can contribute poison to the
instruction being reused. Poison-generating flags are dropped if
doing that enables reuse.

This is a pretty big hammer and does cause some regressions in
tests, but less than I would have expected. I wasn't able to come
up with a less intrusive fix that still satisfies the correctness
requirements.

Fixes https://github.com/llvm/llvm-project/issues/63763.
Fixes https://github.com/llvm/llvm-project/issues/63926.
Fixes https://github.com/llvm/llvm-project/issues/64333.
Fixes https://github.com/llvm/llvm-project/issues/63727.

Differential Revision: https://reviews.llvm.org/D158181
2023-08-22 09:27:07 +02:00
Nikita Popov
7ed4b7e583 [SCEVExpander] Change getRelatedExistingExpansion() to return bool (NFC)
This method is only used to determine whether a related expansion
exists, the actual value is unused. Clarify that by renaming
get -> has and returning bool.
2023-08-21 11:51:22 +02:00
Bjorn Pettersson
a7ee80fab2 [llvm] Drop some more typed pointer bitcasts etc. 2023-08-13 16:46:56 +02:00
Nikita Popov
5820c9257e [SCEVExpander] Use early continue and move comment (NFC)
In preparation for adding additional checks here.
2023-08-11 16:56:02 +02:00
Eli Friedman
60712732ea [IndVars] Teach replaceCongruentIVs to avoid scrambling induction variables
replaceCongruentIVs analysis is based on ScalarEvolution; this makes
comparing different PHIs and performing the replacement straightforward.
However, it can have some side-effects: it isn't aware whether an
induction variable is in canonical form, so it can perform replacements
which obscure the meaning of the IR.

In test22 in widen-loop-comp.ll, the resulting loop can't be analyzed by
ScalarEvolution at all.

My attempted solution is to restrict the transform: don't try to replace
induction variables using PHI nodes that don't represent simple
induction variables.

I'm not sure if this is the best solution; suggestions welcome.

Differential Revision: https://reviews.llvm.org/D121950
2023-07-12 12:27:39 -07:00
Nikita Popov
b75254270e [SCEVExpander] Remove GEP add rec splitting code (NFCI)
I don't believe this is relevant anymore with opaque pointers,
where we always expand the entire offset, without splitting it into
parts.
2023-07-12 16:53:51 +02:00
Jie Fu
67f1e8d737 [Transforms] Remove FactorOutConstant to fix -Wunneeded-internal-declaration (NFC)
/Users/jiefu/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp:293:13: error: function 'FactorOutConstant' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration]
static bool FactorOutConstant(const SCEV *&S, const SCEV *&Remainder,
            ^
1 error generated.
2023-07-12 21:57:12 +08:00
Nikita Popov
02ba40593d [SCEVExpander] Remove typed pointer support (NFC) 2023-07-12 15:34:58 +02:00
Nikita Popov
d69033d245 [SCEVExpander] Fix GEP IV inc reuse logic for opaque pointers
Instead of checking the pointer type, check the element type of
the GEP.

Previously we ended up reusing GEP increments that were not in
expanded form, thus not respecting LSRs choice of representation.

The change in 2011-10-06-ReusePhi.ll recovers a regression that
appeared when converting that test to opaque pointers.

Changes in various Thumb tests now compute the step outside the
loop instead of using add.w inside the loop, which is LSR's
preferred representation for this target.
2023-07-12 11:32:13 +02:00
Florian Hahn
69ca5c9d62
[SCEV] Add flag to control invertible check for normalization.
When normalizing a SCEV expression during expansion, there should be
no need for it to be invertible, as it will only be used for code
generation. This fixes a crash after 7f5b15ad150e.

Fixes https://github.com/llvm/llvm-project/issues/63678.
2023-07-05 18:11:44 +01:00
Nikita Popov
143ed21b26 Revert "[LCSSA] Remove unused ScalarEvolution argument (NFC)"
This reverts commit 5362a0d859d8e96b3f7c0437b7866e17a818a4f7.

In preparation for reverting a dependent revision.
2023-06-05 16:45:38 +02:00
Nikita Popov
d5c56c5162 [SCEVExpander] Remember phi nodes inserted by LCSSA construction
SCEVExpander keeps track of all instructions it inserted. However,
it currently misses some phi nodes created during LCSSA construction.
Fix this by collecting these into another argument.

This also removes the IRBuilder argument, which was added for
essentially the same purpose, but only handles the root LCSSA nodes,
not those inserted by SSAUpdater.

This was reported as a regression on D149344, but the reduced test
case also reproduces without it.

Differential Revision: https://reviews.llvm.org/D150681
2023-05-25 09:34:19 +02:00
eopXD
c8eb535aed [1/11][IR] Permit load/store/alloca for struct of the same scalable vector type
This patch-set aims to simplify the existing RVV segment load/store
intrinsics to use a type that represents a tuple of vectors instead.

To achieve this, first we need to relax the current limitation for an
aggregate type to be a target of load/store/alloca when the aggregate
type contains homogeneous scalable vector types. Then to adjust the
prolog of an LLVM function during lowering to clang. Finally we
re-define the RVV segment load/store intrinsics to use the tuple types.

The pull request under the RVV intrinsic specification is
riscv-non-isa/rvv-intrinsic-doc#198

---

This is the 1st patch of the patch-set. This patch is originated from
D98169.

This patch allows aggregate type (StructType) that contains homogeneous
scalable vector types to be a target of load/store/alloca. The RFC of
this patch was posted in LLVM Discourse.

https://discourse.llvm.org/t/rfc-ir-permit-load-store-alloca-for-struct-of-the-same-scalable-vector-type/69527

The main changes in this patch are:

Extend `StructLayout::StructSize` from `uint64_t` to `TypeSize` to
accommodate an expression of scalable size.

Allow `StructType:isSized` to also return true for homogeneous
scalable vector types.

Let `Type::isScalableTy` return true when `Type` is `StructType`
and contains scalable vectors

Extra description is added in the LLVM Language Reference Manual on the
relaxation of this patch.

Authored-by: Hsiangkai Wang <kai.wang@sifive.com>
Co-Authored-by: eop Chen <eop.chen@sifive.com>

Reviewed By: craig.topper, nikic

Differential Revision: https://reviews.llvm.org/D146872
2023-05-19 09:39:36 -07:00