Without Zfa we use pseudos that are lowered to a stack load/store. With
Zfa we have instructions that can move a pair of registers to an FPR. Or
move the high or low half of an FPR to a GPR.
I've used a GINodeEquiv to make use of 3 of the 4 tablegen patterns. The
split case with Zfa requires 2 instructions which I'm doing through
custom isel like we do in SelectionDAG.
Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),
in which imm = imm0 + imml and both imm0 and imm1 are simm12. We make
imm0 as large as possible and imm1 as small as possible so that we might
be able to use c.addi for the small immediate.
Note that PointerUnion::{is,get,dyn_cast} have been soft deprecated in
PointerUnion.h:
// FIXME: Replace the uses of is(), get() and dyn_cast() with
// isa<T>, cast<T> and the llvm::dyn_cast<T>
SelectionDAG uses VTSDNode to store the extension type. GlobalISel uses
a literal constant operand.
For vectors, SelectionDAG uses a type with the same number of elements
as other operand of the sext_inreg. I assume for GISel we would just use
the scalar size.
I plan to make i32 an illegal type for RV64 to match SelectionDAG and to
remove i32 from the GPR register class.
I've added a sexti32 ComplexPattern to select sext.w+fcvt.s.l as
fcvt.s.w. The recently added zexti32 handles selecting and+fcvt.s.lu as
fcvt.s.wu. There are still some regressions that suggest we should match
g_zero_extend in zexti32.
It was requested in
https://github.com/llvm/llvm-project/pull/110782#discussion_r1784939348
that MRI be made a member of RISCVInstructionSelector.
RISCVInstructionSelector is created in the RISCVSubtarget, independent
of MachineFunction. So it cannot be passed by reference during
construction of RISCVInstructionSelector.
The MachineRegisterInfo object belongs to each MachineFunction, so
set it in setupMF.
The InstructionSelector objects all take these arguments in as `const`.
This function does not modify the object. Therefore we can mark them as
`const` here.
This patch fixes cases where G_AND creating the shift mask is eliminated
if one of its source operands is a constant, resulting from an incorrect
predicate.
Here we introduce three new GMIR instructions to cover a set of trap
intrinsics. The idea behind it is that generic intrinsics shouldn't be
used with G_INTRINSIC opcode.
These new instructions can match perfectly with existing trap ISD nodes.
It allows X86, AArch64, RISCV and Mips to reuse SelectionDAG patterns for
selection and avoid manual selection. However AMDGPU is an exception. It
selects traps during legalization regardless SelectionDAG or GlobalISel.
Since there are not many places where traps are used, this change
attempts to clean up all the usages of G_INTRINSIC with trap intrinsics. So,
there is no stage when both G_TRAP and
G_INTRINSIC_W_SIDE_EFFECTS(@llvm.trap) are allowed.
RegisterBank Selection for scalable vector G_ADD and G_SUB by creating
new mappings for different types of vector register banks.
Then implement Instruction Selection for the same operations by choosing
the correct RISC-V vector register class.
…[UN]MERGE_VALUES
When MERGE or UNMERGE s64 on a subtarget that is non-64bit, it must have
the D extension and use FPR in order to be legal.
All other instances of MERGE and UNMERGE that can be made legal should
be narrowed, widend, or replaced by the combiner.
Try to pick the FP register bank based on surrounding use/defs. Code is
basically copied from AArch64.
Need legalizer changes to make this more useful. Right now we're stuck
with only being able to FP select types less than or equal to XLen.
We only have instructions for OEQ, OLT, and OLE. We need to convert
other comparison codes into those.
I think we'll likely want to split this up in the future to support
optimizations. Maybe do some of it in the legalizer or in a new post
legalizer lowering pass. So this patch is just enough to get something
working without adding 11 additional patterns to tablegen for each type.
RISCVII::MO_HI was being passed to the offset argument instead of
the flags argument.
Adjust some other calls to not pass an explicit 0 to the offset argument
since it already has a default value of 0.
This reverts commit 28ae42e6625154dfd164803850b15d8a0c296b94.
The assert in getIConstantVRegVal was not updated for this change.
The ValAndVReg->VReg == VReg check fails if any look through happens.
RISC-V was the only target using the lookthrough functionality, but I'm
not sure it was needed so I'm removing that too.