Resolve the TODO: on RV32, when constructing the double-precision
constant `+0.0` for `s64`, `BuildPairF64Pseudo` can be optimized to use
the `fcvt.d.w` instruction to generate the result directly.
The information whether a specific argument is vararg or fixed is
currently stored separately from all the other argument information in
ArgFlags. This means that it is not accessible from CCAssign, and
backends have developed all kinds of workarounds for how they can access
it after all.
Move this information to ArgFlags to make it directly available in all
relevant places.
I've opted to invert this and store it as IsVarArg, as I think that both
makes the meaning more obvious and provides for a better default (which
is IsVarArg=false).
This adds a GISelValueTrackingPrinterPass that can print the known bits
and sign bit of each def in a function. It is built on the new pass
manager and so adds a NPM GISelValueTrackingAnalysis, renaming the older
class to GISelValueTrackingAnalysisLegacy.
The first 2 functions from the AArch64GISelMITest are ported over to an
mir test to show it working. It also runs successfully on all files in
llvm/test/CodeGen/AArch64/GlobalISel/*.mir that are not invalid. It can
hopefully be used to test GlobalISel known bits analysis more directly
in common cases, without jumping through the hoops that the C++ tests
requires.
If there is another branch instruction also with immediate operand, but
it is used to specify which bit to be tested is set or clear. We only
check whether operand2 is immediate or not here. There are no way to
distinguish between them.
So add new CondCode COND_CV_BEQIMM/COND_CV_BNEIMM that we can know what
kinds of immediate branch instruction are matched in Select_* Pseudo.
The function currently only checks to see if we compare against an
immediate before selecting the two branch immediate instructions that
are a part of the XCVbi vendor extension. This works at the moment since
there are no other extensions that have a branch immediate instruction.
It would be better if we explicitly check if the XCVbi extension is enabled
before returning the appropriate instruction.
This is also done in preparation for the branch immediate instructions
that are a part of the Xqcibi vendor extension from Qualcomm.
The VLMUL and policy enums originally lived in RISCVBaseInfo.h in the
backend which is where everything else in the RISCVII namespace is
defined.
RISCVTargetParser.h is used by much more of the compiler and it
doesn't really make sense to have 2 different namespaces exposed.
These enums are both associated with VTYPE so using the RISCVVType
namespace seems like a good home for them.
Found using https://github.com/codespell-project/codespell
```
codespell RISCV --write-changes \
--ignore-words-list=FPR,fpr,VAs,ORE,WorstCase,hart,sie,MIs,FLE,fle,CarryIn,vor,OLT,VILL,vill,bu,pass-thru
```
Ported hasAllNBitUsers to RISCV GISel side. Add GISelPredicate code to
each of the 16,32, and 64 bit words. It allows for generation of
optimized packw sequences along with other transparent narrowing
operations. Included a few new .ll files to expand testing and limited
the OptW pass Optimization to fewer options until GISel is ready for
more code generation paths
---------
Signed-off-by: Luke Quinn <quic_lquinn@quicinc.com>
Custom lowering for s32 G_ADD/SUB to help match selection dag better.
Specifically for RV64 a s32 is produced as a add+sext the output this
allows for fewer instructions to sign extend a couple patterns. Allows
for the generation of addiw,subw,negw to reduce required instructions to
load values quicker
Log2_ceil_i32 in rvzbb.ll shows a more obvious improvement case.
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.
There are a number of backends (specifically AArch64, AMDGPU, Mips, and
RISCV) which contain a “TODO: make CombinerHelper methods const”
comment. This PR does just that and makes all of the CombinerHelper
methods const, removes the TODO comments and makes the associated
instances const. This change makes some sense because the CombinerHelper
class simply modifies the state of _other_ objects to which it holds
pointers or references.
Note that AMDGPU contains an identical comment for an instance of
AMDGPUCombinerHelper (a subclass of CombinerHelper). I deliberately
haven’t modified the methods of that class in order to limit the scope
of the change. I’m happy to do so either now or as a follow-up.
Our byval call lowering isn't copying the argument. Looks like our
SelectionDAG code for byval is different than AArch64 so this may be
non-trivial to fix. Reject for now.
This allows us to handle small coerced structs that are passed as
[2 x i64]. This is one of the last big reasons for -O0 fallbacks
in some of my testing.
We can support these via libcalls in libgcc/compiler-rt or integer
operations for fneg/fabs/fcopysign. fp128 values will be passed in two
64-bit GPRs according to the psABI.
Supporting RV32 requires sret which is not supported by libcall handling
in LegalizerHelper.cpp yet. It doesn't call canLowerReturn.
When we have legal instructions we want to promote to sXLen and let isel
pattern matching removing the and/sext_inreg.
When using a libcall we want to use a 'si' libcall for small types
instead of 'di'. To match the RV64 ABI, we need to sign extend `unsigned
int` arguments. We reuse the shouldSignExtendTypeInLibCall hook from
SelectionDAG.
Bug fix FCLASS instruction in RISCV. The bug is due the fact that FCLASS
has an input float register and output GPR this caused reg bank select
regression.
Need to force libcall legalization to treat the integer argument as
signed so that it can be promoted to XLen in call lowering for RV64.
Alternatively we could promote the operand before converting to libcall,
but going through call lowering is closer to what SelectionDAG does.
This is based on what fails when adding integer only RUN lines to
float-intrinsics.ll and double-intrinsics.ll.
We're still missing a lot of test cases that SelectionDAG has. These
will be added in future patches.
This is needed to support Zfh loads/stores.
This requires supporting extends from sext/zext form i16 and s16
G_FREEZE to support the current tests we have.