Issue #58168 describes the difficulty diagnosing stack size issues
identified by -Wframe-larger-than. For simple code, its easy to
understand the stack layout and where space is being allocated, but in
more complex programs, where code may be heavily inlined, unrolled, and
have duplicated code paths, it is no longer easy to manually inspect the
source program and understand where stack space can be attributed.
This patch implements a machine function pass that emits remarks with a
textual representation of stack slots, and also outputs any available
debug information to map source variables to those slots.
The new behavior can be used by adding `-Rpass-analysis=stack-frame-layout`
to the compiler invocation. Like other remarks the diagnostic
information can be saved to a file in a machine readable format by
adding -fsave-optimzation-record.
Fixes: #58168
Reviewed By: nickdesaulniers, thegameg
Differential Revision: https://reviews.llvm.org/D135488
Like in the scalar domain, combine calls to (fp_to_int (ftrunc X)) on
scalable and fixed-length vectors into a single vfcvt instruction.
For truncating rounds, the static vfcvt.rtz rounding mode is used.
Otherwise use the VFCVT_RM_ variants to set the rounding mode
dynamically.
Closes https://github.com/llvm/llvm-project/issues/56737
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D141599
There's a conflict between the riscv32 and riscv64 output for some
tests which caused the script to drop the check lines.
Add specific check prefixes for these cases.
https://reviews.llvm.org/D140493 is going to teach SROA how to promote allocas
that have variably-indexed loads. That does bring up questions of cost model,
since that requires creating wide shifts.
Indeed, our legalization for them is not optimal.
We either split it into parts, or lower it into a libcall.
But if the shift amount is by a multiple of CHAR_BIT,
we can also legalize it throught stack.
The basic idea is very simple:
1. Get a stack slot 2x the width of the shift type
2. store the value we are shifting into one half of the slot
3. pad the other half of the slot. for logical shifts, with zero, for arithmetic shift with signbit
4. index into the slot (starting from the base half into which we spilled, either upwards or downwards)
5. load
6. split loaded integer
This works for both little-endian and big-endian machines:
https://alive2.llvm.org/ce/z/YNVwd5
And better yet, if the original shift amount was not a multiple of CHAR_BIT,
we can just shift by that remainder afterwards: https://alive2.llvm.org/ce/z/pz5G-K
I think, if we are going perform shift->shift-by-parts expansion more than once,
we should instead go through stack, which is what this patch does.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D140638
Issue #58168 describes the difficulty diagnosing stack size issues
identified by -Wframe-larger-than. For simple code, its easy to
understand the stack layout and where space is being allocated, but in
more complex programs, where code may be heavily inlined, unrolled, and
have duplicated code paths, it is no longer easy to manually inspect the
source program and understand where stack space can be attributed.
This patch implements a machine function pass that emits remarks with a
textual representation of stack slots, and also outputs any available
debug information to map source variables to those slots.
The new behavior can be used by adding `-Rpass-analysis=stack-frame-layout`
to the compiler invocation. Like other remarks the diagnostic
information can be saved to a file in a machine readable format by
adding -fsave-optimzation-record.
Fixes: #58168
Reviewed By: nickdesaulniers, thegameg
Differential Revision: https://reviews.llvm.org/D135488
Type legalization will insert a sign extend anyway. By doing it
early we can remove the zext. ComputeNumSignBits can't spot it
after type legalization because type legalization may expand
the abs to sra+xor+sub.
If the zext result type is larger than the type to be promoted to,
we'll promote to a legal type and then zext the rest of the way.
If the legal type is larger than the destination type we can promote
and then truncate.
Reviewed By: asb
Differential Revision: https://reviews.llvm.org/D140509
This patch relaxes the restriction that both reassociate operands must
be in the same block as the root instruction.
The comment indicates that the reason for this restriction was that the
operands not in the same block won't have a depth in the trace.
I believe this is outdated; if the operand is in a different block, it
must dominate the current block (otherwise it would need to be phi),
which in turn means the operand's block must be included in the current
rance, and depths must be available.
There's a test case (no_reassociate_different_block) added in
70520e2f1c5fc4 which shows that we have accurate depths for operands
defined in other blocks.
This allows reassociation of code that computes the final reduction
value after vectorization, among other things.
Reviewed By: dmgreen
Differential Revision: https://reviews.llvm.org/D141302
Inspired by gcc's assembly: https://godbolt.org/z/54hbzsGYn, while referring to D130203
Replace AND+IMM{32,64} with a slli.
But gcc does not handle 0xffff and 0xffffffff, which also seem to be optimizable.
The testcases copies all the bits in D130203 and adds 16, 32, and 64 bits.
Differential Revision: https://reviews.llvm.org/D141607
If the subtarget does not support VInstructions, expand vp intrinscs to scalar instructions.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D139706
D111904 made RISC-V customized lower ISD::CTLZ_ZERO_UNDEF by converting to float
and using the float result. The expected value of CTLZ with zero input is the
element size of input type. Since the result of above method with zero input
must be greater than the element size, for ISD::CTLZ, we could use the minimum
of element size and the result of CTLZ_ZERO_UNDER with same input.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D141585
Previously lowerCTLZ_CTTZ_ZERO_UNDEF converted the source to float value by
ISD::UINT_TO_FP. ISD::UINT_TO_FP uses dynamic rounding mode, so the rounding
may make the exponent of the result not as expected when converting i32/i64 to f32.
This is the reason why we constrained lowerCTLZ_CTTZ_ZERO_UNDEF to only handle
an i32 source when the f64 type having the same element count as source is legal.
The patch teaches lowerCTLZ_CTTZ_ZERO_UNDEF converts i32/i64 vectors to f32
vectors by vfcvt.f.xu.v with RTZ rounding mode. Using RTZ is to make sure the
exponent of results is correct, although f32 could not totally represent each
value in i32/i64.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D140782
singlethread fences only synchronize with code running on the same hardware thread (i.e. signal handlers). Because of this, we need to prevent instruction reordering, but do not need to emit hardware fence instructions.
The implementation strategy here matches many other backends. The main motivation of this patch is to introduce the MEMBARRIER node and get some test coverage for it.
Differential Revision: https://reviews.llvm.org/D141311
`h` was the prefix of multi-letter extension name, but it become a
extension name in later RISC-V isa spec.
Fortunately we don't have any extension really defined is prefixed
with `h`, so we can just change that.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D136817
We use a special TIED instructions for vwadd(u).wv to avoid an
earlyclobber constraint preventing the first source and the destination
from being the same register.
This prevents our normal post process for forming TU instructions.
Add manual isel pattern instead. This matches what we do for FMA
for example.
These tests show failure to form vwadd(u).wv instructions.
One of the operands of the add is already wide and has an
additional user. We are unnecessary enforcing that operand to
have a single use.
This includes a fix for the tramp3d failure from the llvm-testsuite
that caused the last revert. Hopefully the others failures were the
same issue.
Original commit message:
For RISC-V, load/store(exclude vector load/store) instructions only has a 12 bit immediate operand. If the offset is out-of-range, it must make use of a temp register to make up this offset. If between these offsets, they have a small(IsInt<12>) relative offset, LocalStackSlotAllocation pass can find a value as frame base register's value, and replace the origin offset with this register's value plus the relative offset.
Co-authored-by: luxufan <luxufan@iscas.ac.cn>
Co-authored-by: Craig Topper <craig.topper@sifive.com>
Differential Revision: https://reviews.llvm.org/D98101
Add patterns with seteq/setne conditions.
We don't have instructions for seteq/setne except for comparing
with zero and need to emit an ADDI or XOR before a seqz/snez to
compare other values.
The select ISD node takes a 0/1 value for the condition, but the
VT_MASKC(N) instructions check all XLen bits for zero or non-zero.
We can use this to avoid the seqz/snez in many cases.
This is pretty ridiculous number of patterns. I wonder if we could
use some ComplexPatterns to merge them, but I'd like to do that as
a follow up and focus on correctness of the result in this patch.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D140421
This is based on @frasercrmck's D107290. At least some of the clang
portion of D107290 has already been committed.
This uses vscale_range for min/max vector width unless the command
line overrides are used.
As a follow up, I plan to add a max or exact VLEN option to clang
to control the vscale_range. This will eliminate many of the reasons
for users to use the overrides through the -mllvm interface.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D139873
Fixing a crash during vsetvli insertion pass.
We have a testcase with 3 vsetvli:
1. vsetivli zero, 2, e8, m4, ta, ma
2. li a1, 32; vsetvli zero, a1, e8, m4, ta, mu
3. vsetivli zero, 2, e8, m4, ta, ma
and then we trying to optimize 2nd vsetvli since the only user is vmv.x.s, so
it could mutate the AVL operand to the AVL operand of the 3rd vsetvli.
OK, so we propagate 2 to vsetvli, BUT it's vsetvli not vsetivli, so it expect a
register rather than a immediate value, so we have to update the opcode
if needed.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D141061
The patch also adds expandVPCTLZ and expandVPCTTZ to expand vp.ctlz/cttz nodes
and the cost model of vp.ctlz/cttz.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D140370
The scalar move instructions (vmv.s.x, and fvmv.s.f) depend solely on whether the VL is 0 or non-zero. By tracking the fact we only demand the zeroness and not the whole VL value, we can allow changing VL over a scalar move. This helps to eliminate vsetvli toggles.
Differential Revision: https://reviews.llvm.org/D140157
This is mostly geared at consolidating logic into one form to reduce code duplication, but also has the effect of being a slight generalization. Since these operations aren't masked, we can ignore the mask policy bit when deciding on compatibility. The previous code was overly strict in checking that both policy bits matched.
Note: There's a slight difference from the reviewed version. The reviewed version was based on a local revision which included the isCompatible change to only check AVL if VL is used. I apparently never landed that change, and while functional, the functional change isn't visible without this one. I chose to role the extra change into this patch.
Differential Revision: https://reviews.llvm.org/D140147
The patch tries to make more vslidup nodes use tail agnostic. The idea comes
from D125546 authored by Zack Chen.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D140669
isel is now capable of turning the SUB into XOR for shift amounts.
Though it uses NOT instead of XOR with ShiftSize-1.
By using SUB during lowering we enable more DAG combines with
other arithmetic on the shift amount.
If the shift amount is (sub C, X) where C is -1 modulo the size of
the shift, we can replace the sub with a NOT.
We could also use XORI X, size-1, but NOT would work better with
c.not from the future Zce extension.
If the dividend has leading zeros, we can use them to reduce the
size of the multiplier and avoid the fixup cases.
This patch is for scalars only, but we might be able to do this
for vectors in a follow up.
Differential Revision: https://reviews.llvm.org/D140750
Follow-up patch of D140530.
We can add FMIN, FMAX to isAssociativeAndCommutative to
increase instruction-level parallelism by the existing MachineCombiner
pass.
Differential Revision: https://reviews.llvm.org/D140602
Inspired by D138107.
We can add ADD, AND, OR, XOR, MUL, MIN[U]/MAX[U] to isAssociativeAndCommutative
to increase instruction-level parallelism by the existing MachineCombiner pass.
Differential Revision: https://reviews.llvm.org/D140530
There is no compressed form of ORI but there is a compressed form
for ADDI.
This also works for XORI since DAGCombine will turn Xor with disjoint
bits in Or.
Note: The compressed forms require a simm6 immediate, but I'm doing
this for the full simm12 range.
Reviewed By: kito-cheng
Differential Revision: https://reviews.llvm.org/D140674
There were 4 RUN lines, but only 2 of them were unique. I believe
we were trying to test LMUL=1 and LMUL=8 with riscv32 and riscv64.
But put riscv32 on both LMUL=1 lines and riscv64 on both LMUL=8 lines.
We can recursively look through SRLI if the shift amount is less
than the demanded bits. We can reduce the demanded bit count by
the shift amount and check the users of the SRLI.