sifive-7-series can predicate ALU instructions in the shadow of a
branch not just move instructions.
This patch implements analyzeSelect/optimizeSelect to predicate
these operations. This is based on ARM's implementation which can
predicate using flags and condition codes.
I've restricted it to just the instructions we have test cases for,
but it can be extended in the future.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D140053
Most of VP intrinsics are implemented in RISC-V backends, but
vp.reduce.mul (element length > 1) does not yet. Legalizes vp.reduce.mul
using ExpandVectorPredication Pass.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D139721
SelectionDAG aggressively creates sext_inreg operations after
promoting an i32 add. If the add is later matched to a sh1add,
sh2add or sh3add, a sext.w from the sext_inreg will get left behind.
In many cases we can prove this sext.w is unnecessary by checking
if its upper bits are ever used.
This extends the backwards walk to allow mutating the previous vsetvl's AVL value if it was not used by any instructions in between. In practice, this mostly benefits vmv.x.s and fvmv.f.s patterns since vector instructions which ignore VL are rare.
Differential Revision: https://reviews.llvm.org/D140048
Alignment of an alloca in IR can be lower than the preferred alignment
on purpose, but this override essentially treats the preferred
alignment as the minimum alignment.
The patch changes this behavior to always use the specified
alignment. If alignment is not set explicitly in LLVM IR, it is set to
DL.getPrefTypeAlign(Ty) in computeAllocaDefaultAlign.
Tests are changed as well: explicit alignment is increased to match
the preferred alignment if it changes output, or omitted when it is
hard to determine the right value (e.g. for pointers, some structs, or
weird types).
Differential Revision: https://reviews.llvm.org/D135462
If the divisor is repeated at least twice, we will convert the FDIVs to the
calculation of the reciprocal and FMULs.
We perform the transformation only under fast-math mode. FDIVs must have
'arcp' flag.
Differential Revision: https://reviews.llvm.org/D140024
We don’t have W versions of AND/OR/XOR/ANDN/ORN/XNOR so we should recursively check their users. We should limit the recursion to SelectionDAG::MaxRecursionDepth levels.
We need to add a Depth argument, all existing callers should pass 0 to the Depth. The new recursive calls should increment it by 1. At the top of the function we should give up and return false if Depth >= SelectionDAG::MaxRecursionDepth.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D139462
On RV64 these instructions produce a 32-bit value and sign extend
to 64-bits.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D140036
This is a follow up to patch discussion on D139656. As noted there, M2/M4/M8 versions of these instructions don't actually exist, and using them results in overly constrained register allocation.
In that review, we'd talked about moving towards a variant of the instructions which ignored LMUL. I decided to see what happened if we just stopped generating the high LMUL variants, and the results are surprisingly neutral. I only see one minor thing which looks like a real regression among all the churn. I think this is worth doing now to loosen register allocation constraints, and avoid digging our hole around these instructions deeper while thinking about the right model change.
Differential Revision: https://reviews.llvm.org/D140027
The patch also adds expandVPCTPOP in TargetLowering to expand VP_CTPOP nodes.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D139920
This is an alternative patch on a path to D137530.
The basic problem being tackled here is that we need to place a scalar into lane 0 of a vector register before our reduction instructions. Since we only care about lane 0 of the vector, we can use any VL >= 1 provided that the total amount of work performed matches the work performed for a VL=1.
This change does not contain the logic from D137530 to perform the insert at the original VT, and then extract down to LMUL1. That turns out to be a good choice, as discussion in this review has indicated there are issues around LMUL2 and above with our representation of vmv.s.x. We'd also need to be careful with the splat logic for the same reasons.
The only potentially concerning codegen change I spot here is that we stop using a broadcast load (for VL=1) and instead do a scalar load and insert. I think this is probably reasonable; if reviewers disagree, I can investigate using a broadcast load which writes to the undef lanes. If we want to do that, we should do it for VECTOR_INSERT_ELT as well, so that'll end up as it's own patch series.
Differential Revision: https://reviews.llvm.org/D139656
The implementation is inspired by code from PPCInstrInfo.
We look for a copy from X10(A0) preceded by an ADJCALLSTACKUP and
a PseudoCall. We use the PseudoCall to look up the IR function being
called to find it's return attributes.
Reviewed By: asb
Differential Revision: https://reviews.llvm.org/D139808
If we're initializing lane 0 of an undef vector, we can optionally write to other lanes of the vector. Doing so may require additional work, so we don't want to e.g. always use a splat. However, since we don't have an immediate form of vmv.s.x it's useful to use a vmv.v.i if the work required is expected to be equal in practice. We restrict this to when LMUL <= 1 to a) prevent doing additional work at higher LMULs, and b) avoid overconstraining the register allocator.
At the moment, the new utility is only used by one case in INSERT_VECTOR_ELT lowering. My expectation is that we will reuse this in a couple other places, but each of those deserve individual review.
This change is inspired by D137530, but is not directly related to it. I vaguely remember we discussed the tradeoffs of using vmv.v.i in another recent review, but couldn't find it.
Differential Revision: https://reviews.llvm.org/D139648
Now with fix to limit added tagged-globals.ll to risc-v platform
--
[RISC-V][HWASAN] Support tagging global variables for RISC-V HWASAN
Reviewed by: luismarques
Differential Revision: https://reviews.llvm.org/D132995
For reductions, we need to put the start value into a source vector. For fractional LMULs, we can perform the operation at the original LMUL. For LMUL > 1, we eventually want to use a scalar insert, but that's outside the scope of this patch.
Differential Revision: https://reviews.llvm.org/D139747
The patch also added function expandVPBITREVERSE to expand ISD::VP_BITREVERSE nodes.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D139697
This teaches the DemandedElts version of isConstOrConstSplat about
SPLAT_VECTORS, in the same way as the non-DemandedElts version by
calling the demanded-bits version from the non-demanded-bits version.
Differential Revision: https://reviews.llvm.org/D128919
2048 requires an LUI and ADDI instruction due to ADDI using a
signed immediate. It can also be done with C.LI+C.SLLI for better
code size.
With Zbs we can use a single BSETI to have an instruction.
Reorder the checks so that BSETI is checked first, with an extra
qualification to prefer a single LUI or ADDI when possible. I'm
continuing to think about other ways to structure this code, but
this works for now.
Fixes PR59362.
I've enabled Zfhmin on 2 basic tests to show this isn't
completely broken.
Reviewed By: monkchiang
Differential Revision: https://reviews.llvm.org/D139562
The MC layer instructions have the correct register classes, and
the pseudos don't have any additional operands. So there doesn't
seem to be any reason for them to exist.
The pseudos were incorrectly going through code in RISCVMCInstLower
that converted LMUL>1 register classes to LMUL1 register class.
This makes the MCInst technically malformed, and prevented the
vl2r.v, vl4r.v, and vl8r.v InstAliases from matching. This accounts
for all of the .ll test diffs.
Differential Revision: https://reviews.llvm.org/D139511
Machine combiner supports generic reassociation only of associative and
commutative instructions, for example (A + X) + Y => (X + Y) + A. However, we
can extend this generic support to handle patterns like
(X + A) - Y => (X - Y) + A), where `-` is the inverse of `+`.
This patch adds interface functions to process reassociation patterns of
associative/commutative instructions and their inverse variants with minimal
changes in backends.
Differential Revision: https://reviews.llvm.org/D136754
This reverts commit 7883e5b061.
The original commit was reverted that it didn't update test files after D136263
landed. The recommit fixed those.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D139509
The Zfhmin subset only has FLH, FSH, FMV.X.H, FMV.H.X, FCVT.S.H, and FCVT.H.S.
If the D extension is present, the FCVT.D.H and FCVT.H.D instructions are also included.
Since most instructions are not included for Zfhmin, so most operations are promoted.
The patch primarily about making f16 a legal type.
RISC-V ISA info:
https://wiki.riscv.org/display/HOME/Recently+Ratified+Extensions
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D139391
The patch made VectorLegalizer expand ISD::VP_FSHL and ISD::VP_FSHR to
achieve the codegen.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D138379
We need a scratch GPR to increment the base pointer for each subsequent
register. We currently reuse the input GPR for the base pointer without
declaring it as a Def of the pseudo.
We can't add it as a Def of the pseudo at creation time because it doesn't
get register allocated. This was tried in D109405.
Seems the only choice we have is to scavenge the GPR. This patch
moves the expansion to eliminateFrameIndex where we can create
virtual registers that will be scavenged. This also eliminates the
extra operand for passing vlenb from frame lowering to expand pseudos.
I need to do more testing on real world code, but wanted to get this
up for early review.
I hope this will fix the issue reported in D123394, but I haven't
checked yet.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D139169
With C extension, li with a 6 bit immediate followed by slli is 4 bytes.
The lui+addi(w) sequence is at least 6 bytes.
The two sequences probably have similar execution latency. The exception
being if the target supports lui+addi(w) macrofusion.
Since the execution latency is probably the same I didn't restrict
this to C extension.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D139135
Cannonical frame address after RVV stack adjustment is sp + StackSize +
RVVStackSize * vlenb, and since vlenb is unknown at compile-time (but it
is a constant for particular HW implementation), emit
.cfi_def_cfa_expression so libunwind can read VLENB CSR register at
run-time and obtain correct frame address.
Fixes https://github.com/llvm/llvm-project/issues/58356 (but additional
run-time support for reading CSR may be required)
Differential Revision: https://reviews.llvm.org/D136263
This patch implements shouldFoldSelectWithIdentityConstant for RISCV. It would try to generate vmerge after the binary instruction and let them folded to maksed instruction later.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D131551
Currently per-function metadata consists of:
(start-pc, size, features)
This adds a new UAR feature and if it's set an additional element:
(start-pc, size, features, stack-args-size)
Reviewed By: melver
Differential Revision: https://reviews.llvm.org/D136078
Fold the low 12 bits of an immediate offset into the offset field of the using instruction. That using instruction will be a load, store, or addi which performs an add of a signed 12-bit immediate as part of it's operation. Splitting out the low bits allows the high bits to be generated via a single LUI instead of needing an LUI/ADDI pair.
The codegen effect of this is mostly converting cases where "split addi" kicks in to using LUI + a folded offset. There are a couple of straight dynamic instruction count wins, and using a canonical LUI is probably better than a chain of SP adds if the dynamic instruction count is equal.
Differential Revision: https://reviews.llvm.org/D139037
These instructions requires both register operands to be compressible
so I've only applied the hint if we already have a GPRC physical register
assigned for the other register operand.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D139079
In branch relaxation pass, restore blocks are created and placed before
the jump destination if indirect branches are required. For example:
foo
sd s11, 0(sp)
jump .restore, s11
bar
bar
bar
j .dest
.restore:
ld s11, 0(sp)
.dest:
baz
The BasicBlock information of the restore MachineBasicBlock should be
identical to the dest MachineBasicBlock.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D131863
A new pass MachineLateInstrsCleanup is added to be run after PEI.
This is a simple pass that removes redundant and identical instructions
whenever found by scanning the MF once while keeping track of register
definitions in a map. These instructions are typically immediate loads
resulting from rematerialization, and address loads emitted by target in
eliminateFrameInde().
This is enabled by default, but a target could easily disable it by means of
'disablePass(&MachineLateInstrsCleanupID);'.
This late cleanup is naturally not "optimal" in removing instructions as it
is done by looking at phys-regs, but still quite effective. It would be
desirable to improve other parts of CodeGen and avoid these redundant
instructions in the first place, but there are no ideas for this yet.
Differential Revision: https://reviews.llvm.org/D123394
Reviewed By: RKSimon, foad, craig.topper, arsenm, asb