aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/RISCV
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/RISCV')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp7
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h9
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVFeatures.td86
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp3
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp182
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.h7
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrFormats.td9
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td8
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td125
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td12
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td2
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVMacroFusion.cpp82
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVProcessors.td27
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td1
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSubtarget.h18
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h2
16 files changed, 399 insertions, 181 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/contrib/llvm-project/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 8f03a7ac41d3..28ec999157c6 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -85,13 +85,12 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
// Merge/Unmerge
for (unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
+ auto &MergeUnmergeActions = getActionDefinitionsBuilder(Op);
unsigned BigTyIdx = Op == G_MERGE_VALUES ? 0 : 1;
unsigned LitTyIdx = Op == G_MERGE_VALUES ? 1 : 0;
- auto &MergeUnmergeActions = getActionDefinitionsBuilder(Op);
if (XLen == 32 && ST.hasStdExtD()) {
- LLT IdxZeroTy = G_MERGE_VALUES ? s64 : s32;
- LLT IdxOneTy = G_MERGE_VALUES ? s32 : s64;
- MergeUnmergeActions.legalFor({IdxZeroTy, IdxOneTy});
+ MergeUnmergeActions.legalIf(
+ all(typeIs(BigTyIdx, s64), typeIs(LitTyIdx, s32)));
}
MergeUnmergeActions.widenScalarToNextPow2(LitTyIdx, XLen)
.widenScalarToNextPow2(BigTyIdx, XLen)
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 00b4751905f6..30ed36525e29 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -113,6 +113,15 @@ enum {
UsesVXRMShift = HasRoundModeOpShift + 1,
UsesVXRMMask = 1 << UsesVXRMShift,
+
+ // Indicates whether these instructions can partially overlap between source
+ // registers and destination registers according to the vector spec.
+ // 0 -> not a vector pseudo
+ // 1 -> default value for vector pseudos. not widening or narrowing.
+ // 2 -> narrowing case
+ // 3 -> widening case
+ TargetOverlapConstraintTypeShift = UsesVXRMShift + 1,
+ TargetOverlapConstraintTypeMask = 3ULL << TargetOverlapConstraintTypeShift,
};
enum VLMUL : uint8_t {
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVFeatures.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVFeatures.td
index 294927aecb94..a66dd135ae5f 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -107,15 +107,15 @@ def HasStdExtZfhmin : Predicate<"Subtarget->hasStdExtZfhmin()">,
def FeatureStdExtZfh
: SubtargetFeature<"zfh", "HasStdExtZfh", "true",
"'Zfh' (Half-Precision Floating-Point)",
- [FeatureStdExtF]>;
+ [FeatureStdExtZfhmin]>;
def HasStdExtZfh : Predicate<"Subtarget->hasStdExtZfh()">,
AssemblerPredicate<(all_of FeatureStdExtZfh),
"'Zfh' (Half-Precision Floating-Point)">;
def NoStdExtZfh : Predicate<"!Subtarget->hasStdExtZfh()">;
def HasStdExtZfhOrZfhmin
- : Predicate<"Subtarget->hasStdExtZfhOrZfhmin()">,
- AssemblerPredicate<(any_of FeatureStdExtZfh, FeatureStdExtZfhmin),
+ : Predicate<"Subtarget->hasStdExtZfhmin()">,
+ AssemblerPredicate<(all_of FeatureStdExtZfhmin),
"'Zfh' (Half-Precision Floating-Point) or "
"'Zfhmin' (Half-Precision Floating-Point Minimal)">;
@@ -146,15 +146,15 @@ def HasStdExtZhinxmin : Predicate<"Subtarget->hasStdExtZhinxmin()">,
def FeatureStdExtZhinx
: SubtargetFeature<"zhinx", "HasStdExtZhinx", "true",
"'Zhinx' (Half Float in Integer)",
- [FeatureStdExtZfinx]>;
+ [FeatureStdExtZhinxmin]>;
def HasStdExtZhinx : Predicate<"Subtarget->hasStdExtZhinx()">,
AssemblerPredicate<(all_of FeatureStdExtZhinx),
"'Zhinx' (Half Float in Integer)">;
def NoStdExtZhinx : Predicate<"!Subtarget->hasStdExtZhinx()">;
def HasStdExtZhinxOrZhinxmin
- : Predicate<"Subtarget->hasStdExtZhinx() || Subtarget->hasStdExtZhinxmin()">,
- AssemblerPredicate<(any_of FeatureStdExtZhinx, FeatureStdExtZhinxmin),
+ : Predicate<"Subtarget->hasStdExtZhinxmin()">,
+ AssemblerPredicate<(all_of FeatureStdExtZhinxmin),
"'Zhinx' (Half Float in Integer) or "
"'Zhinxmin' (Half Float in Integer Minimal)">;
@@ -472,7 +472,7 @@ def HasStdExtZfbfmin : Predicate<"Subtarget->hasStdExtZfbfmin()">,
def FeatureStdExtZvfbfmin
: SubtargetFeature<"experimental-zvfbfmin", "HasStdExtZvfbfmin", "true",
"'Zvbfmin' (Vector BF16 Converts)",
- [FeatureStdExtZve32f, FeatureStdExtZfbfmin]>;
+ [FeatureStdExtZve32f]>;
def HasStdExtZvfbfmin : Predicate<"Subtarget->hasStdExtZvfbfmin()">,
AssemblerPredicate<(all_of FeatureStdExtZvfbfmin),
"'Zvfbfmin' (Vector BF16 Converts)">;
@@ -480,23 +480,23 @@ def HasStdExtZvfbfmin : Predicate<"Subtarget->hasStdExtZvfbfmin()">,
def FeatureStdExtZvfbfwma
: SubtargetFeature<"experimental-zvfbfwma", "HasStdExtZvfbfwma", "true",
"'Zvfbfwma' (Vector BF16 widening mul-add)",
- [FeatureStdExtZvfbfmin]>;
+ [FeatureStdExtZvfbfmin, FeatureStdExtZfbfmin]>;
def HasStdExtZvfbfwma : Predicate<"Subtarget->hasStdExtZvfbfwma()">,
AssemblerPredicate<(all_of FeatureStdExtZvfbfwma),
"'Zvfbfwma' (Vector BF16 widening mul-add)">;
def HasVInstructionsBF16 : Predicate<"Subtarget->hasVInstructionsBF16()">;
-def FeatureStdExtZvfh
- : SubtargetFeature<"zvfh", "HasStdExtZvfh", "true",
- "'Zvfh' (Vector Half-Precision Floating-Point)",
- [FeatureStdExtZve32f, FeatureStdExtZfhmin]>;
-
def FeatureStdExtZvfhmin
: SubtargetFeature<"zvfhmin", "HasStdExtZvfhmin", "true",
"'Zvfhmin' (Vector Half-Precision Floating-Point Minimal)",
[FeatureStdExtZve32f]>;
+def FeatureStdExtZvfh
+ : SubtargetFeature<"zvfh", "HasStdExtZvfh", "true",
+ "'Zvfh' (Vector Half-Precision Floating-Point)",
+ [FeatureStdExtZvfhmin, FeatureStdExtZfhmin]>;
+
def HasVInstructionsF16 : Predicate<"Subtarget->hasVInstructionsF16()">;
def HasVInstructionsF16Minimal : Predicate<"Subtarget->hasVInstructionsF16Minimal()">,
@@ -561,14 +561,14 @@ def HasStdExtZawrs : Predicate<"Subtarget->hasStdExtZawrs()">,
"'Zawrs' (Wait on Reservation Set)">;
def FeatureStdExtZvkb
- : SubtargetFeature<"experimental-zvkb", "HasStdExtZvkb", "true",
+ : SubtargetFeature<"zvkb", "HasStdExtZvkb", "true",
"'Zvkb' (Vector Bit-manipulation used in Cryptography)">;
def HasStdExtZvkb : Predicate<"Subtarget->hasStdExtZvkb()">,
AssemblerPredicate<(all_of FeatureStdExtZvkb),
"'Zvkb' (Vector Bit-manipulation used in Cryptography)">;
def FeatureStdExtZvbb
- : SubtargetFeature<"experimental-zvbb", "HasStdExtZvbb", "true",
+ : SubtargetFeature<"zvbb", "HasStdExtZvbb", "true",
"'Zvbb' (Vector basic bit-manipulation instructions.)",
[FeatureStdExtZvkb]>;
def HasStdExtZvbb : Predicate<"Subtarget->hasStdExtZvbb()">,
@@ -576,35 +576,35 @@ def HasStdExtZvbb : Predicate<"Subtarget->hasStdExtZvbb()">,
"'Zvbb' (Vector basic bit-manipulation instructions.)">;
def FeatureStdExtZvbc
- : SubtargetFeature<"experimental-zvbc", "HasStdExtZvbc", "true",
+ : SubtargetFeature<"zvbc", "HasStdExtZvbc", "true",
"'Zvbc' (Vector Carryless Multiplication)">;
def HasStdExtZvbc : Predicate<"Subtarget->hasStdExtZvbc()">,
AssemblerPredicate<(all_of FeatureStdExtZvbc),
"'Zvbc' (Vector Carryless Multiplication)">;
def FeatureStdExtZvkg
- : SubtargetFeature<"experimental-zvkg", "HasStdExtZvkg", "true",
+ : SubtargetFeature<"zvkg", "HasStdExtZvkg", "true",
"'Zvkg' (Vector GCM instructions for Cryptography)">;
def HasStdExtZvkg : Predicate<"Subtarget->hasStdExtZvkg()">,
AssemblerPredicate<(all_of FeatureStdExtZvkg),
"'Zvkg' (Vector GCM instructions for Cryptography)">;
def FeatureStdExtZvkned
- : SubtargetFeature<"experimental-zvkned", "HasStdExtZvkned", "true",
+ : SubtargetFeature<"zvkned", "HasStdExtZvkned", "true",
"'Zvkned' (Vector AES Encryption & Decryption (Single Round))">;
def HasStdExtZvkned : Predicate<"Subtarget->hasStdExtZvkned()">,
AssemblerPredicate<(all_of FeatureStdExtZvkned),
"'Zvkned' (Vector AES Encryption & Decryption (Single Round))">;
def FeatureStdExtZvknha
- : SubtargetFeature<"experimental-zvknha", "HasStdExtZvknha", "true",
+ : SubtargetFeature<"zvknha", "HasStdExtZvknha", "true",
"'Zvknha' (Vector SHA-2 (SHA-256 only))">;
def HasStdExtZvknha : Predicate<"Subtarget->hasStdExtZvknha()">,
AssemblerPredicate<(all_of FeatureStdExtZvknha),
"'Zvknha' (Vector SHA-2 (SHA-256 only))">;
def FeatureStdExtZvknhb
- : SubtargetFeature<"experimental-zvknhb", "HasStdExtZvknhb", "true",
+ : SubtargetFeature<"zvknhb", "HasStdExtZvknhb", "true",
"'Zvknhb' (Vector SHA-2 (SHA-256 and SHA-512))",
[FeatureStdExtZve64x]>;
def HasStdExtZvknhb : Predicate<"Subtarget->hasStdExtZvknhb()">,
@@ -616,59 +616,59 @@ def HasStdExtZvknhaOrZvknhb : Predicate<"Subtarget->hasStdExtZvknha() || Subtarg
"'Zvknha' or 'Zvknhb' (Vector SHA-2)">;
def FeatureStdExtZvksed
- : SubtargetFeature<"experimental-zvksed", "HasStdExtZvksed", "true",
+ : SubtargetFeature<"zvksed", "HasStdExtZvksed", "true",
"'Zvksed' (SM4 Block Cipher Instructions)">;
def HasStdExtZvksed : Predicate<"Subtarget->hasStdExtZvksed()">,
AssemblerPredicate<(all_of FeatureStdExtZvksed),
"'Zvksed' (SM4 Block Cipher Instructions)">;
def FeatureStdExtZvksh
- : SubtargetFeature<"experimental-zvksh", "HasStdExtZvksh", "true",
+ : SubtargetFeature<"zvksh", "HasStdExtZvksh", "true",
"'Zvksh' (SM3 Hash Function Instructions)">;
def HasStdExtZvksh : Predicate<"Subtarget->hasStdExtZvksh()">,
AssemblerPredicate<(all_of FeatureStdExtZvksh),
"'Zvksh' (SM3 Hash Function Instructions)">;
def FeatureStdExtZvkt
- : SubtargetFeature<"experimental-zvkt", "HasStdExtZvkt", "true",
+ : SubtargetFeature<"zvkt", "HasStdExtZvkt", "true",
"'Zvkt' (Vector Data-Independent Execution Latency)">;
// Zvk short-hand extensions
def FeatureStdExtZvkn
- : SubtargetFeature<"experimental-zvkn", "HasStdExtZvkn", "true",
+ : SubtargetFeature<"zvkn", "HasStdExtZvkn", "true",
"This extension is shorthand for the following set of "
"other extensions: Zvkned, Zvknhb, Zvkb and Zvkt.",
[FeatureStdExtZvkned, FeatureStdExtZvknhb,
FeatureStdExtZvkb, FeatureStdExtZvkt]>;
def FeatureStdExtZvknc
- : SubtargetFeature<"experimental-zvknc", "HasStdExtZvknc", "true",
+ : SubtargetFeature<"zvknc", "HasStdExtZvknc", "true",
"This extension is shorthand for the following set of "
"other extensions: Zvkn and Zvbc.",
[FeatureStdExtZvkn, FeatureStdExtZvbc]>;
def FeatureStdExtZvkng
- : SubtargetFeature<"experimental-zvkng", "HasStdExtZvkng", "true",
+ : SubtargetFeature<"zvkng", "HasStdExtZvkng", "true",
"This extension is shorthand for the following set of "
"other extensions: Zvkn and Zvkg.",
[FeatureStdExtZvkn, FeatureStdExtZvkg]>;
def FeatureStdExtZvks
- : SubtargetFeature<"experimental-zvks", "HasStdExtZvks", "true",
+ : SubtargetFeature<"zvks", "HasStdExtZvks", "true",
"This extension is shorthand for the following set of "
"other extensions: Zvksed, Zvksh, Zvkb and Zvkt.",
[FeatureStdExtZvksed, FeatureStdExtZvksh,
FeatureStdExtZvkb, FeatureStdExtZvkt]>;
def FeatureStdExtZvksc
- : SubtargetFeature<"experimental-zvksc", "HasStdExtZvksc", "true",
+ : SubtargetFeature<"zvksc", "HasStdExtZvksc", "true",
"This extension is shorthand for the following set of "
"other extensions: Zvks and Zvbc.",
[FeatureStdExtZvks, FeatureStdExtZvbc]>;
def FeatureStdExtZvksg
- : SubtargetFeature<"experimental-zvksg", "HasStdExtZvksg", "true",
+ : SubtargetFeature<"zvksg", "HasStdExtZvksg", "true",
"This extension is shorthand for the following set of "
"other extensions: Zvks and Zvkg.",
[FeatureStdExtZvks, FeatureStdExtZvkg]>;
@@ -959,6 +959,10 @@ def TuneNoOptimizedZeroStrideLoad
"false", "Hasn't optimized (perform fewer memory operations)"
"zero-stride vector load">;
+def Experimental
+ : SubtargetFeature<"experimental", "HasExperimental",
+ "true", "Experimental intrinsics">;
+
// Some vector hardware implementations do not process all VLEN bits in parallel
// and instead split over multiple cycles. DLEN refers to the datapath width
// that can be done in parallel.
@@ -973,9 +977,19 @@ def TuneLUIADDIFusion
def TuneAUIPCADDIFusion
: SubtargetFeature<"auipc-addi-fusion", "HasAUIPCADDIFusion",
"true", "Enable AUIPC+ADDI macrofusion">;
-def TuneShiftedZExtFusion
- : SubtargetFeature<"shifted-zext-fusion", "HasShiftedZExtFusion",
- "true", "Enable SLLI+SRLI to be fused when computing (shifted) zero extension">;
+
+def TuneZExtHFusion
+ : SubtargetFeature<"zexth-fusion", "HasZExtHFusion",
+ "true", "Enable SLLI+SRLI to be fused to zero extension of halfword">;
+
+def TuneZExtWFusion
+ : SubtargetFeature<"zextw-fusion", "HasZExtWFusion",
+ "true", "Enable SLLI+SRLI to be fused to zero extension of word">;
+
+def TuneShiftedZExtWFusion
+ : SubtargetFeature<"shifted-zextw-fusion", "HasShiftedZExtWFusion",
+ "true", "Enable SLLI+SRLI to be fused when computing (shifted) zero extension of word">;
+
def TuneLDADDFusion
: SubtargetFeature<"ld-add-fusion", "HasLDADDFusion",
"true", "Enable LD+ADD macrofusion.">;
@@ -997,12 +1011,8 @@ def TuneSiFive7 : SubtargetFeature<"sifive7", "RISCVProcFamily", "SiFive7",
[TuneNoDefaultUnroll,
TuneShortForwardBranchOpt]>;
-def TuneVeyronFusions : SubtargetFeature<"ventana-veyron", "RISCVProcFamily", "VentanaVeyron",
- "Ventana Veyron-Series processors",
- [TuneLUIADDIFusion,
- TuneAUIPCADDIFusion,
- TuneShiftedZExtFusion,
- TuneLDADDFusion]>;
+def TuneVentanaVeyron : SubtargetFeature<"ventana-veyron", "RISCVProcFamily", "VentanaVeyron",
+ "Ventana Veyron-Series processors">;
// Assume that lock-free native-width atomics are available, even if the target
// and operating system combination would not usually provide them. The user
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 09b3ab96974c..098a320c9153 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -915,8 +915,7 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
Opc = RISCV::FMV_H_X;
break;
case MVT::f16:
- Opc =
- Subtarget->hasStdExtZhinxOrZhinxmin() ? RISCV::COPY : RISCV::FMV_H_X;
+ Opc = Subtarget->hasStdExtZhinxmin() ? RISCV::COPY : RISCV::FMV_H_X;
break;
case MVT::f32:
Opc = Subtarget->hasStdExtZfinx() ? RISCV::COPY : RISCV::FMV_W_X;
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 03e994586d0c..c2508a158837 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -122,7 +122,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
if (Subtarget.is64Bit() && RV64LegalI32)
addRegisterClass(MVT::i32, &RISCV::GPRRegClass);
- if (Subtarget.hasStdExtZfhOrZfhmin())
+ if (Subtarget.hasStdExtZfhmin())
addRegisterClass(MVT::f16, &RISCV::FPR16RegClass);
if (Subtarget.hasStdExtZfbfmin())
addRegisterClass(MVT::bf16, &RISCV::FPR16RegClass);
@@ -130,7 +130,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
addRegisterClass(MVT::f32, &RISCV::FPR32RegClass);
if (Subtarget.hasStdExtD())
addRegisterClass(MVT::f64, &RISCV::FPR64RegClass);
- if (Subtarget.hasStdExtZhinxOrZhinxmin())
+ if (Subtarget.hasStdExtZhinxmin())
addRegisterClass(MVT::f16, &RISCV::GPRF16RegClass);
if (Subtarget.hasStdExtZfinx())
addRegisterClass(MVT::f32, &RISCV::GPRF32RegClass);
@@ -439,7 +439,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
ISD::FCEIL, ISD::FFLOOR, ISD::FTRUNC, ISD::FRINT, ISD::FROUND,
ISD::FROUNDEVEN};
- if (Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin())
+ if (Subtarget.hasStdExtZfhminOrZhinxmin())
setOperationAction(ISD::BITCAST, MVT::i16, Custom);
static const unsigned ZfhminZfbfminPromoteOps[] = {
@@ -469,7 +469,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FCOPYSIGN, MVT::bf16, Expand);
}
- if (Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) {
+ if (Subtarget.hasStdExtZfhminOrZhinxmin()) {
if (Subtarget.hasStdExtZfhOrZhinx()) {
setOperationAction(FPLegalNodeTypes, MVT::f16, Legal);
setOperationAction(FPRndMode, MVT::f16,
@@ -675,7 +675,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
ISD::VP_FP_TO_UINT, ISD::VP_SETCC, ISD::VP_SIGN_EXTEND,
ISD::VP_ZERO_EXTEND, ISD::VP_TRUNCATE, ISD::VP_SMIN,
ISD::VP_SMAX, ISD::VP_UMIN, ISD::VP_UMAX,
- ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE};
+ ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE};
static const unsigned FloatingPointVPOps[] = {
ISD::VP_FADD, ISD::VP_FSUB, ISD::VP_FMUL,
@@ -688,7 +688,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND,
ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO,
ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS,
- ISD::EXPERIMENTAL_VP_REVERSE};
+ ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE};
static const unsigned IntegerVecReduceOps[] = {
ISD::VECREDUCE_ADD, ISD::VECREDUCE_AND, ISD::VECREDUCE_OR,
@@ -773,6 +773,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::VECTOR_REVERSE, VT, Custom);
+ setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
setOperationPromotedToType(
@@ -1147,6 +1148,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
ISD::VP_SETCC, ISD::VP_TRUNCATE},
VT, Custom);
+ setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
continue;
}
@@ -1322,7 +1324,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
// Custom-legalize bitcasts from fixed-length vectors to scalar types.
setOperationAction(ISD::BITCAST, {MVT::i8, MVT::i16, MVT::i32, MVT::i64},
Custom);
- if (Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin())
+ if (Subtarget.hasStdExtZfhminOrZhinxmin())
setOperationAction(ISD::BITCAST, MVT::f16, Custom);
if (Subtarget.hasStdExtFOrZfinx())
setOperationAction(ISD::BITCAST, MVT::f32, Custom);
@@ -1388,7 +1390,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
if (Subtarget.hasStdExtZbkb())
setTargetDAGCombine(ISD::BITREVERSE);
- if (Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin())
+ if (Subtarget.hasStdExtZfhminOrZhinxmin())
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
if (Subtarget.hasStdExtFOrZfinx())
setTargetDAGCombine({ISD::ZERO_EXTEND, ISD::FP_TO_SINT, ISD::FP_TO_UINT,
@@ -2099,7 +2101,7 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const {
bool IsLegalVT = false;
if (VT == MVT::f16)
- IsLegalVT = Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin();
+ IsLegalVT = Subtarget.hasStdExtZfhminOrZhinxmin();
else if (VT == MVT::f32)
IsLegalVT = Subtarget.hasStdExtFOrZfinx();
else if (VT == MVT::f64)
@@ -2171,7 +2173,7 @@ MVT RISCVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
// Use f32 to pass f16 if it is legal and Zfh/Zfhmin is not enabled.
// We might still end up using a GPR but that will be decided based on ABI.
if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
- !Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin())
+ !Subtarget.hasStdExtZfhminOrZhinxmin())
return MVT::f32;
MVT PartVT = TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
@@ -2188,7 +2190,7 @@ unsigned RISCVTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context
// Use f32 to pass f16 if it is legal and Zfh/Zfhmin is not enabled.
// We might still end up using a GPR but that will be decided based on ABI.
if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
- !Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin())
+ !Subtarget.hasStdExtZfhminOrZhinxmin())
return 1;
return TargetLowering::getNumRegistersForCallingConv(Context, CC, VT);
@@ -5528,7 +5530,7 @@ static unsigned getRISCVVLOp(SDValue Op) {
case ISD::VP_SELECT:
return RISCVISD::VSELECT_VL;
case ISD::VP_MERGE:
- return RISCVISD::VP_MERGE_VL;
+ return RISCVISD::VMERGE_VL;
case ISD::VP_ASHR:
return RISCVISD::SRA_VL;
case ISD::VP_LSHR:
@@ -5576,6 +5578,8 @@ static bool hasMergeOp(unsigned Opcode) {
return true;
if (Opcode >= RISCVISD::STRICT_FADD_VL && Opcode <= RISCVISD::STRICT_FDIV_VL)
return true;
+ if (Opcode == RISCVISD::VMERGE_VL)
+ return true;
return false;
}
@@ -5761,7 +5765,7 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
EVT Op0VT = Op0.getValueType();
MVT XLenVT = Subtarget.getXLenVT();
if (VT == MVT::f16 && Op0VT == MVT::i16 &&
- Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) {
+ Subtarget.hasStdExtZfhminOrZhinxmin()) {
SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Op0);
SDValue FPConv = DAG.getNode(RISCVISD::FMV_H_X, DL, MVT::f16, NewOp0);
return FPConv;
@@ -6637,6 +6641,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
!Subtarget.hasVInstructionsF16()))
return SplitVPOp(Op, DAG);
return lowerVectorFTRUNC_FCEIL_FFLOOR_FROUND(Op, DAG, Subtarget);
+ case ISD::EXPERIMENTAL_VP_SPLICE:
+ return lowerVPSpliceExperimental(Op, DAG);
case ISD::EXPERIMENTAL_VP_REVERSE:
return lowerVPReverseExperimental(Op, DAG);
}
@@ -8238,8 +8244,8 @@ static SDValue lowerVectorIntrinsicScalars(SDValue Op, SelectionDAG &DAG,
AVL);
// TUMA or TUMU: Currently we always emit tumu policy regardless of tuma.
// It's fine because vmerge does not care mask policy.
- return DAG.getNode(RISCVISD::VP_MERGE_VL, DL, VT, Mask, Vec, MaskedOff,
- AVL);
+ return DAG.getNode(RISCVISD::VMERGE_VL, DL, VT, Mask, Vec, MaskedOff,
+ MaskedOff, AVL);
}
}
@@ -10312,9 +10318,20 @@ SDValue RISCVTargetLowering::lowerVPOp(SDValue Op, SelectionDAG &DAG) const {
for (const auto &OpIdx : enumerate(Op->ops())) {
SDValue V = OpIdx.value();
assert(!isa<VTSDNode>(V) && "Unexpected VTSDNode node!");
- // Add dummy merge value before the mask.
- if (HasMergeOp && *ISD::getVPMaskIdx(Op.getOpcode()) == OpIdx.index())
- Ops.push_back(DAG.getUNDEF(ContainerVT));
+ // Add dummy merge value before the mask. Or if there isn't a mask, before
+ // EVL.
+ if (HasMergeOp) {
+ auto MaskIdx = ISD::getVPMaskIdx(Op.getOpcode());
+ if (MaskIdx) {
+ if (*MaskIdx == OpIdx.index())
+ Ops.push_back(DAG.getUNDEF(ContainerVT));
+ } else if (ISD::getVPExplicitVectorLengthIdx(Op.getOpcode()) ==
+ OpIdx.index()) {
+ // For VP_MERGE, copy the false operand instead of an undef value.
+ assert(Op.getOpcode() == ISD::VP_MERGE);
+ Ops.push_back(Ops.back());
+ }
+ }
// Pass through operands which aren't fixed-length vectors.
if (!V.getValueType().isFixedLengthVector()) {
Ops.push_back(V);
@@ -10583,6 +10600,87 @@ SDValue RISCVTargetLowering::lowerVPFPIntConvOp(SDValue Op,
}
SDValue
+RISCVTargetLowering::lowerVPSpliceExperimental(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+
+ SDValue Op1 = Op.getOperand(0);
+ SDValue Op2 = Op.getOperand(1);
+ SDValue Offset = Op.getOperand(2);
+ SDValue Mask = Op.getOperand(3);
+ SDValue EVL1 = Op.getOperand(4);
+ SDValue EVL2 = Op.getOperand(5);
+
+ const MVT XLenVT = Subtarget.getXLenVT();
+ MVT VT = Op.getSimpleValueType();
+ MVT ContainerVT = VT;
+ if (VT.isFixedLengthVector()) {
+ ContainerVT = getContainerForFixedLengthVector(VT);
+ Op1 = convertToScalableVector(ContainerVT, Op1, DAG, Subtarget);
+ Op2 = convertToScalableVector(ContainerVT, Op2, DAG, Subtarget);
+ MVT MaskVT = getMaskTypeFor(ContainerVT);
+ Mask = convertToScalableVector(MaskVT, Mask, DAG, Subtarget);
+ }
+
+ bool IsMaskVector = VT.getVectorElementType() == MVT::i1;
+ if (IsMaskVector) {
+ ContainerVT = ContainerVT.changeVectorElementType(MVT::i8);
+
+ // Expand input operands
+ SDValue SplatOneOp1 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
+ DAG.getUNDEF(ContainerVT),
+ DAG.getConstant(1, DL, XLenVT), EVL1);
+ SDValue SplatZeroOp1 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
+ DAG.getUNDEF(ContainerVT),
+ DAG.getConstant(0, DL, XLenVT), EVL1);
+ Op1 = DAG.getNode(RISCVISD::VSELECT_VL, DL, ContainerVT, Op1, SplatOneOp1,
+ SplatZeroOp1, EVL1);
+
+ SDValue SplatOneOp2 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
+ DAG.getUNDEF(ContainerVT),
+ DAG.getConstant(1, DL, XLenVT), EVL2);
+ SDValue SplatZeroOp2 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
+ DAG.getUNDEF(ContainerVT),
+ DAG.getConstant(0, DL, XLenVT), EVL2);
+ Op2 = DAG.getNode(RISCVISD::VSELECT_VL, DL, ContainerVT, Op2, SplatOneOp2,
+ SplatZeroOp2, EVL2);
+ }
+
+ int64_t ImmValue = cast<ConstantSDNode>(Offset)->getSExtValue();
+ SDValue DownOffset, UpOffset;
+ if (ImmValue >= 0) {
+ // The operand is a TargetConstant, we need to rebuild it as a regular
+ // constant.
+ DownOffset = DAG.getConstant(ImmValue, DL, XLenVT);
+ UpOffset = DAG.getNode(ISD::SUB, DL, XLenVT, EVL1, DownOffset);
+ } else {
+ // The operand is a TargetConstant, we need to rebuild it as a regular
+ // constant rather than negating the original operand.
+ UpOffset = DAG.getConstant(-ImmValue, DL, XLenVT);
+ DownOffset = DAG.getNode(ISD::SUB, DL, XLenVT, EVL1, UpOffset);
+ }
+
+ SDValue SlideDown =
+ getVSlidedown(DAG, Subtarget, DL, ContainerVT, DAG.getUNDEF(ContainerVT),
+ Op1, DownOffset, Mask, UpOffset);
+ SDValue Result = getVSlideup(DAG, Subtarget, DL, ContainerVT, SlideDown, Op2,
+ UpOffset, Mask, EVL2, RISCVII::TAIL_AGNOSTIC);
+
+ if (IsMaskVector) {
+ // Truncate Result back to a mask vector (Result has same EVL as Op2)
+ Result = DAG.getNode(
+ RISCVISD::SETCC_VL, DL, ContainerVT.changeVectorElementType(MVT::i1),
+ {Result, DAG.getConstant(0, DL, ContainerVT),
+ DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(getMaskTypeFor(ContainerVT)),
+ Mask, EVL2});
+ }
+
+ if (!VT.isFixedLengthVector())
+ return Result;
+ return convertFromScalableVector(VT, Result, DAG, Subtarget);
+}
+
+SDValue
RISCVTargetLowering::lowerVPReverseExperimental(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
@@ -11527,11 +11625,11 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
EVT Op0VT = Op0.getValueType();
MVT XLenVT = Subtarget.getXLenVT();
if (VT == MVT::i16 && Op0VT == MVT::f16 &&
- Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) {
+ Subtarget.hasStdExtZfhminOrZhinxmin()) {
SDValue FPConv = DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Op0);
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, FPConv));
} else if (VT == MVT::i16 && Op0VT == MVT::bf16 &&
- Subtarget.hasStdExtZfbfmin()) {
+ Subtarget.hasStdExtZfbfmin()) {
SDValue FPConv = DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Op0);
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, FPConv));
} else if (VT == MVT::i32 && Op0VT == MVT::f32 && Subtarget.is64Bit() &&
@@ -13493,6 +13591,7 @@ static SDValue performMemPairCombine(SDNode *N,
// (fp_to_int (ffloor X)) -> fcvt X, rdn
// (fp_to_int (fceil X)) -> fcvt X, rup
// (fp_to_int (fround X)) -> fcvt X, rmm
+// (fp_to_int (frint X)) -> fcvt X
static SDValue performFP_TO_INTCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI,
const RISCVSubtarget &Subtarget) {
@@ -13516,10 +13615,7 @@ static SDValue performFP_TO_INTCombine(SDNode *N,
RISCVFPRndMode::RoundingMode FRM = matchRoundingOp(Src.getOpcode());
// If the result is invalid, we didn't find a foldable instruction.
- // If the result is dynamic, then we found an frint which we don't yet
- // support. It will cause 7 to be written to the FRM CSR for vector.
- // FIXME: We could support this by using VFCVT_X_F_VL/VFCVT_XU_F_VL below.
- if (FRM == RISCVFPRndMode::Invalid || FRM == RISCVFPRndMode::DYN)
+ if (FRM == RISCVFPRndMode::Invalid)
return SDValue();
SDLoc DL(N);
@@ -13558,6 +13654,10 @@ static SDValue performFP_TO_INTCombine(SDNode *N,
unsigned Opc =
IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
FpToInt = DAG.getNode(Opc, DL, ContainerVT, XVal, Mask, VL);
+ } else if (FRM == RISCVFPRndMode::DYN) {
+ unsigned Opc =
+ IsSigned ? RISCVISD::VFCVT_X_F_VL : RISCVISD::VFCVT_XU_F_VL;
+ FpToInt = DAG.getNode(Opc, DL, ContainerVT, XVal, Mask, VL);
} else {
unsigned Opc =
IsSigned ? RISCVISD::VFCVT_RM_X_F_VL : RISCVISD::VFCVT_RM_XU_F_VL;
@@ -13594,6 +13694,7 @@ static SDValue performFP_TO_INTCombine(SDNode *N,
// (fp_to_int_sat (ffloor X)) -> (select X == nan, 0, (fcvt X, rdn))
// (fp_to_int_sat (fceil X)) -> (select X == nan, 0, (fcvt X, rup))
// (fp_to_int_sat (fround X)) -> (select X == nan, 0, (fcvt X, rmm))
+// (fp_to_int_sat (frint X)) -> (select X == nan, 0, (fcvt X, dyn))
static SDValue performFP_TO_INT_SATCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI,
const RISCVSubtarget &Subtarget) {
@@ -15998,13 +16099,26 @@ void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
// We can't do anything for most intrinsics.
break;
case Intrinsic::riscv_vsetvli:
- case Intrinsic::riscv_vsetvlimax:
- // Assume that VL output is <= 65536.
- // TODO: Take SEW and LMUL into account.
- if (BitWidth > 17)
- Known.Zero.setBitsFrom(17);
+ case Intrinsic::riscv_vsetvlimax: {
+ bool HasAVL = IntNo == Intrinsic::riscv_vsetvli;
+ unsigned VSEW = Op.getConstantOperandVal(HasAVL + 1);
+ RISCVII::VLMUL VLMUL =
+ static_cast<RISCVII::VLMUL>(Op.getConstantOperandVal(HasAVL + 2));
+ unsigned SEW = RISCVVType::decodeVSEW(VSEW);
+ auto [LMul, Fractional] = RISCVVType::decodeVLMUL(VLMUL);
+ uint64_t MaxVL = Subtarget.getRealMaxVLen() / SEW;
+ MaxVL = (Fractional) ? MaxVL / LMul : MaxVL * LMul;
+
+ // Result of vsetvli must be not larger than AVL.
+ if (HasAVL && isa<ConstantSDNode>(Op.getOperand(1)))
+ MaxVL = std::min(MaxVL, Op.getConstantOperandVal(1));
+
+ unsigned KnownZeroFirstBit = Log2_32(MaxVL) + 1;
+ if (BitWidth > KnownZeroFirstBit)
+ Known.Zero.setBitsFrom(KnownZeroFirstBit);
break;
}
+ }
break;
}
}
@@ -18570,7 +18684,7 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(VNSRL_VL)
NODE_NAME_CASE(SETCC_VL)
NODE_NAME_CASE(VSELECT_VL)
- NODE_NAME_CASE(VP_MERGE_VL)
+ NODE_NAME_CASE(VMERGE_VL)
NODE_NAME_CASE(VMAND_VL)
NODE_NAME_CASE(VMOR_VL)
NODE_NAME_CASE(VMXOR_VL)
@@ -18632,7 +18746,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
// TODO: Support fixed vectors up to XLen for P extension?
if (VT.isVector())
break;
- if (VT == MVT::f16 && Subtarget.hasStdExtZhinxOrZhinxmin())
+ if (VT == MVT::f16 && Subtarget.hasStdExtZhinxmin())
return std::make_pair(0U, &RISCV::GPRF16RegClass);
if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
return std::make_pair(0U, &RISCV::GPRF32RegClass);
@@ -18640,7 +18754,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
return std::make_pair(0U, &RISCV::GPRPF64RegClass);
return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
case 'f':
- if (Subtarget.hasStdExtZfhOrZfhmin() && VT == MVT::f16)
+ if (Subtarget.hasStdExtZfhmin() && VT == MVT::f16)
return std::make_pair(0U, &RISCV::FPR16RegClass);
if (Subtarget.hasStdExtF() && VT == MVT::f32)
return std::make_pair(0U, &RISCV::FPR32RegClass);
@@ -18753,7 +18867,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
}
if (VT == MVT::f32 || VT == MVT::Other)
return std::make_pair(FReg, &RISCV::FPR32RegClass);
- if (Subtarget.hasStdExtZfhOrZfhmin() && VT == MVT::f16) {
+ if (Subtarget.hasStdExtZfhmin() && VT == MVT::f16) {
unsigned RegNo = FReg - RISCV::F0_F;
unsigned HReg = RISCV::F0_H + RegNo;
return std::make_pair(HReg, &RISCV::FPR16RegClass);
@@ -19100,7 +19214,7 @@ bool RISCVTargetLowering::shouldConvertFpToSat(unsigned Op, EVT FPVT,
switch (FPVT.getSimpleVT().SimpleTy) {
case MVT::f16:
- return Subtarget.hasStdExtZfhOrZfhmin();
+ return Subtarget.hasStdExtZfhmin();
case MVT::f32:
return Subtarget.hasStdExtF();
case MVT::f64:
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.h b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 41a2dc5771c8..58ed611efc83 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -332,10 +332,8 @@ enum NodeType : unsigned {
// Vector select with an additional VL operand. This operation is unmasked.
VSELECT_VL,
- // Vector select with operand #2 (the value when the condition is false) tied
- // to the destination and an additional VL operand. This operation is
- // unmasked.
- VP_MERGE_VL,
+ // General vmerge node with mask, true, false, passthru, and vl operands.
+ VMERGE_VL,
// Mask binary operators.
VMAND_VL,
@@ -910,6 +908,7 @@ private:
SDValue lowerLogicVPOp(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVPExtMaskOp(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVPSetCCMaskOp(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerVPSpliceExperimental(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVPReverseExperimental(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVPFPIntConvOp(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVPStridedLoad(SDValue Op, SelectionDAG &DAG) const;
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrFormats.td
index e80ba26800a1..f56f49ae2457 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrFormats.td
@@ -212,6 +212,15 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
// to the correct CSR.
bit UsesVXRM = 0;
let TSFlags{20} = UsesVXRM;
+
+ // Indicates whther these instructions can partially overlap between source
+ // registers and destination registers according to the vector spec.
+ // 0 -> not a vector pseudo
+ // 1 -> default value for vector pseudos. not widening or narrowing.
+ // 2 -> narrowing case
+ // 3 -> widening case
+ bits<2> TargetOverlapConstraintType = 0;
+ let TSFlags{22-21} = TargetOverlapConstraintType;
}
class RVInst<dag outs, dag ins, string opcodestr, string argstr,
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
index 5e06422cf9ad..488ffa73f4e4 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
@@ -529,14 +529,6 @@ class RISCVVPseudo {
// SEW = 0 is used to denote that the Pseudo is not SEW specific (or unknown).
bits<8> SEW = 0;
bit NeedBeInPseudoTable = 1;
- // TargetOverlapConstraintType indicates that these instructions can
- // overlap between source operands and destination operands.
- // 1 -> default value, remain current constraint
- // 2 -> narrow case
- // 3 -> widen case
- // TODO: Add TargetOverlapConstraintType into PseudosTable for further
- // query.
- bits<2> TargetOverlapConstraintType = 1;
}
// The actual table.
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
index dc6b57fad321..33bdc3366aa3 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
@@ -344,7 +344,14 @@ def SDT_RISCVSelect_VL : SDTypeProfile<1, 4, [
]>;
def riscv_vselect_vl : SDNode<"RISCVISD::VSELECT_VL", SDT_RISCVSelect_VL>;
-def riscv_vp_merge_vl : SDNode<"RISCVISD::VP_MERGE_VL", SDT_RISCVSelect_VL>;
+
+def SDT_RISCVVMERGE_VL : SDTypeProfile<1, 5, [
+ SDTCisVec<0>, SDTCisVec<1>, SDTCisSameNumEltsAs<0, 1>, SDTCVecEltisVT<1, i1>,
+ SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameAs<0, 4>,
+ SDTCisVT<5, XLenVT>
+]>;
+
+def riscv_vmerge_vl : SDNode<"RISCVISD::VMERGE_VL", SDT_RISCVVMERGE_VL>;
def SDT_RISCVVMSETCLR_VL : SDTypeProfile<1, 1, [SDTCVecEltisVT<0, i1>,
SDTCisVT<1, XLenVT>]>;
@@ -675,14 +682,14 @@ multiclass VPatTiedBinaryNoMaskVL_V<SDNode vop,
op2_reg_class:$rs2,
GPR:$vl, sew, TAIL_AGNOSTIC)>;
// Tail undisturbed
- def : Pat<(riscv_vp_merge_vl true_mask,
+ def : Pat<(riscv_vmerge_vl true_mask,
(result_type (vop
result_reg_class:$rs1,
(op2_type op2_reg_class:$rs2),
srcvalue,
true_mask,
VLOpFrag)),
- result_reg_class:$rs1, VLOpFrag),
+ result_reg_class:$rs1, result_reg_class:$rs1, VLOpFrag),
(!cast<Instruction>(instruction_name#"_"#suffix#"_"# vlmul.MX#"_TIED")
result_reg_class:$rs1,
op2_reg_class:$rs2,
@@ -712,14 +719,14 @@ multiclass VPatTiedBinaryNoMaskVL_V_RM<SDNode vop,
FRM_DYN,
GPR:$vl, sew, TAIL_AGNOSTIC)>;
// Tail undisturbed
- def : Pat<(riscv_vp_merge_vl true_mask,
+ def : Pat<(riscv_vmerge_vl true_mask,
(result_type (vop
result_reg_class:$rs1,
(op2_type op2_reg_class:$rs2),
srcvalue,
true_mask,
VLOpFrag)),
- result_reg_class:$rs1, VLOpFrag),
+ result_reg_class:$rs1, result_reg_class:$rs1, VLOpFrag),
(!cast<Instruction>(instruction_name#"_"#suffix#"_"# vlmul.MX#"_TIED")
result_reg_class:$rs1,
op2_reg_class:$rs2,
@@ -1697,21 +1704,21 @@ multiclass VPatMultiplyAccVL_VV_VX<PatFrag op, string instruction_name> {
foreach vti = AllIntegerVectors in {
defvar suffix = vti.LMul.MX;
let Predicates = GetVTypePredicates<vti>.Predicates in {
- def : Pat<(riscv_vp_merge_vl (vti.Mask V0),
+ def : Pat<(riscv_vmerge_vl (vti.Mask V0),
(vti.Vector (op vti.RegClass:$rd,
(riscv_mul_vl_oneuse vti.RegClass:$rs1, vti.RegClass:$rs2,
srcvalue, (vti.Mask true_mask), VLOpFrag),
srcvalue, (vti.Mask true_mask), VLOpFrag)),
- vti.RegClass:$rd, VLOpFrag),
+ vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag),
(!cast<Instruction>(instruction_name#"_VV_"# suffix #"_MASK")
vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
(vti.Mask V0), GPR:$vl, vti.Log2SEW, TU_MU)>;
- def : Pat<(riscv_vp_merge_vl (vti.Mask V0),
+ def : Pat<(riscv_vmerge_vl (vti.Mask V0),
(vti.Vector (op vti.RegClass:$rd,
(riscv_mul_vl_oneuse (SplatPat XLenVT:$rs1), vti.RegClass:$rs2,
srcvalue, (vti.Mask true_mask), VLOpFrag),
srcvalue, (vti.Mask true_mask), VLOpFrag)),
- vti.RegClass:$rd, VLOpFrag),
+ vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag),
(!cast<Instruction>(instruction_name#"_VX_"# suffix #"_MASK")
vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
(vti.Mask V0), GPR:$vl, vti.Log2SEW, TU_MU)>;
@@ -1840,17 +1847,17 @@ multiclass VPatFPMulAccVL_VV_VF<PatFrag vop, string instruction_name> {
foreach vti = AllFloatVectors in {
defvar suffix = vti.LMul.MX;
let Predicates = GetVTypePredicates<vti>.Predicates in {
- def : Pat<(riscv_vp_merge_vl (vti.Mask V0),
+ def : Pat<(riscv_vmerge_vl (vti.Mask V0),
(vti.Vector (vop vti.RegClass:$rs1, vti.RegClass:$rs2,
vti.RegClass:$rd, (vti.Mask true_mask), VLOpFrag)),
- vti.RegClass:$rd, VLOpFrag),
+ vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag),
(!cast<Instruction>(instruction_name#"_VV_"# suffix #"_MASK")
vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
(vti.Mask V0), GPR:$vl, vti.Log2SEW, TU_MU)>;
- def : Pat<(riscv_vp_merge_vl (vti.Mask V0),
+ def : Pat<(riscv_vmerge_vl (vti.Mask V0),
(vti.Vector (vop (SplatFPOp vti.ScalarRegClass:$rs1), vti.RegClass:$rs2,
vti.RegClass:$rd, (vti.Mask true_mask), VLOpFrag)),
- vti.RegClass:$rd, VLOpFrag),
+ vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag),
(!cast<Instruction>(instruction_name#"_V" # vti.ScalarSuffix # "_" # suffix # "_MASK")
vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
(vti.Mask V0), GPR:$vl, vti.Log2SEW, TU_MU)>;
@@ -1876,10 +1883,10 @@ multiclass VPatFPMulAccVL_VV_VF_RM<PatFrag vop, string instruction_name> {
foreach vti = AllFloatVectors in {
defvar suffix = vti.LMul.MX;
let Predicates = GetVTypePredicates<vti>.Predicates in {
- def : Pat<(riscv_vp_merge_vl (vti.Mask V0),
+ def : Pat<(riscv_vmerge_vl (vti.Mask V0),
(vti.Vector (vop vti.RegClass:$rs1, vti.RegClass:$rs2,
vti.RegClass:$rd, (vti.Mask true_mask), VLOpFrag)),
- vti.RegClass:$rd, VLOpFrag),
+ vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag),
(!cast<Instruction>(instruction_name#"_VV_"# suffix #"_MASK")
vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
(vti.Mask V0),
@@ -1887,10 +1894,10 @@ multiclass VPatFPMulAccVL_VV_VF_RM<PatFrag vop, string instruction_name> {
// RISCVInsertReadWriteCSR
FRM_DYN,
GPR:$vl, vti.Log2SEW, TU_MU)>;
- def : Pat<(riscv_vp_merge_vl (vti.Mask V0),
+ def : Pat<(riscv_vmerge_vl (vti.Mask V0),
(vti.Vector (vop (SplatFPOp vti.ScalarRegClass:$rs1), vti.RegClass:$rs2,
vti.RegClass:$rd, (vti.Mask true_mask), VLOpFrag)),
- vti.RegClass:$rd, VLOpFrag),
+ vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag),
(!cast<Instruction>(instruction_name#"_V" # vti.ScalarSuffix # "_" # suffix # "_MASK")
vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
(vti.Mask V0),
@@ -2273,29 +2280,32 @@ foreach vti = AllIntegerVectors in {
(vti.Vector (IMPLICIT_DEF)),
vti.RegClass:$rs2, simm5:$rs1, (vti.Mask V0), GPR:$vl, vti.Log2SEW)>;
- def : Pat<(vti.Vector (riscv_vp_merge_vl (vti.Mask V0),
- vti.RegClass:$rs1,
- vti.RegClass:$rs2,
- VLOpFrag)),
+ def : Pat<(vti.Vector (riscv_vmerge_vl (vti.Mask V0),
+ vti.RegClass:$rs1,
+ vti.RegClass:$rs2,
+ vti.RegClass:$merge,
+ VLOpFrag)),
(!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX)
- vti.RegClass:$rs2, vti.RegClass:$rs2, vti.RegClass:$rs1,
- (vti.Mask V0), GPR:$vl, vti.Log2SEW)>;
+ vti.RegClass:$merge, vti.RegClass:$rs2, vti.RegClass:$rs1,
+ (vti.Mask V0), GPR:$vl, vti.Log2SEW)>;
- def : Pat<(vti.Vector (riscv_vp_merge_vl (vti.Mask V0),
- (SplatPat XLenVT:$rs1),
- vti.RegClass:$rs2,
- VLOpFrag)),
+ def : Pat<(vti.Vector (riscv_vmerge_vl (vti.Mask V0),
+ (SplatPat XLenVT:$rs1),
+ vti.RegClass:$rs2,
+ vti.RegClass:$merge,
+ VLOpFrag)),
(!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX)
- vti.RegClass:$rs2, vti.RegClass:$rs2, GPR:$rs1,
- (vti.Mask V0), GPR:$vl, vti.Log2SEW)>;
-
- def : Pat<(vti.Vector (riscv_vp_merge_vl (vti.Mask V0),
- (SplatPat_simm5 simm5:$rs1),
- vti.RegClass:$rs2,
- VLOpFrag)),
+ vti.RegClass:$merge, vti.RegClass:$rs2, GPR:$rs1,
+ (vti.Mask V0), GPR:$vl, vti.Log2SEW)>;
+
+ def : Pat<(vti.Vector (riscv_vmerge_vl (vti.Mask V0),
+ (SplatPat_simm5 simm5:$rs1),
+ vti.RegClass:$rs2,
+ vti.RegClass:$merge,
+ VLOpFrag)),
(!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX)
- vti.RegClass:$rs2, vti.RegClass:$rs2, simm5:$rs1,
- (vti.Mask V0), GPR:$vl, vti.Log2SEW)>;
+ vti.RegClass:$merge, vti.RegClass:$rs2, simm5:$rs1,
+ (vti.Mask V0), GPR:$vl, vti.Log2SEW)>;
}
}
@@ -2493,21 +2503,23 @@ foreach fvti = AllFloatVectors in {
(fvti.Vector (IMPLICIT_DEF)),
fvti.RegClass:$rs2, 0, (fvti.Mask V0), GPR:$vl, fvti.Log2SEW)>;
- def : Pat<(fvti.Vector (riscv_vp_merge_vl (fvti.Mask V0),
- fvti.RegClass:$rs1,
- fvti.RegClass:$rs2,
- VLOpFrag)),
- (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX)
- fvti.RegClass:$rs2, fvti.RegClass:$rs2, fvti.RegClass:$rs1, (fvti.Mask V0),
- GPR:$vl, fvti.Log2SEW)>;
-
- def : Pat<(fvti.Vector (riscv_vp_merge_vl (fvti.Mask V0),
- (SplatFPOp (fvti.Scalar fpimm0)),
- fvti.RegClass:$rs2,
- VLOpFrag)),
- (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX)
- fvti.RegClass:$rs2, fvti.RegClass:$rs2, 0, (fvti.Mask V0),
- GPR:$vl, fvti.Log2SEW)>;
+ def : Pat<(fvti.Vector (riscv_vmerge_vl (fvti.Mask V0),
+ fvti.RegClass:$rs1,
+ fvti.RegClass:$rs2,
+ fvti.RegClass:$merge,
+ VLOpFrag)),
+ (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX)
+ fvti.RegClass:$merge, fvti.RegClass:$rs2, fvti.RegClass:$rs1, (fvti.Mask V0),
+ GPR:$vl, fvti.Log2SEW)>;
+
+ def : Pat<(fvti.Vector (riscv_vmerge_vl (fvti.Mask V0),
+ (SplatFPOp (fvti.Scalar fpimm0)),
+ fvti.RegClass:$rs2,
+ fvti.RegClass:$merge,
+ VLOpFrag)),
+ (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX)
+ fvti.RegClass:$merge, fvti.RegClass:$rs2, 0, (fvti.Mask V0),
+ GPR:$vl, fvti.Log2SEW)>;
}
let Predicates = GetVTypePredicates<fvti>.Predicates in {
@@ -2521,12 +2533,13 @@ foreach fvti = AllFloatVectors in {
(fvti.Scalar fvti.ScalarRegClass:$rs1),
(fvti.Mask V0), GPR:$vl, fvti.Log2SEW)>;
- def : Pat<(fvti.Vector (riscv_vp_merge_vl (fvti.Mask V0),
- (SplatFPOp fvti.ScalarRegClass:$rs1),
- fvti.RegClass:$rs2,
- VLOpFrag)),
+ def : Pat<(fvti.Vector (riscv_vmerge_vl (fvti.Mask V0),
+ (SplatFPOp fvti.ScalarRegClass:$rs1),
+ fvti.RegClass:$rs2,
+ fvti.RegClass:$merge,
+ VLOpFrag)),
(!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX)
- fvti.RegClass:$rs2, fvti.RegClass:$rs2,
+ fvti.RegClass:$merge, fvti.RegClass:$rs2,
(fvti.Scalar fvti.ScalarRegClass:$rs1),
(fvti.Mask V0), GPR:$vl, fvti.Log2SEW)>;
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td
index fa618b437ce7..0b1d5b664df9 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td
@@ -351,20 +351,22 @@ multiclass VPseudoSiFiveVMACC<string mx, VReg vd_type, VReg vs2_type,
multiclass VPseudoSiFiveVQMACC<string Constraint = ""> {
foreach m = MxListVF8 in
+ let VLMul = m.value in
defm NAME : VPseudoSiFiveVMACC<m.MX, m.vrclass, m.vrclass, Constraint>;
}
multiclass VPseudoSiFiveVFWMACC<string Constraint = ""> {
foreach m = MxListFW in
+ let VLMul = m.value in
defm NAME : VPseudoSiFiveVMACC<m.MX, m.wvrclass, m.vrclass, Constraint>;
}
multiclass VPseudoSiFiveVFNRCLIP<string Constraint = "@earlyclobber $rd"> {
- foreach m = MxListVF4 in
+ foreach i = [0, 1, 2, 3, 4] in
let hasSideEffects = 0 in
- defm "Pseudo" # NAME : VPseudoBinaryRoundingMode<!if(!eq(m.vrclass, VRM8),
- VRM2, VR),
- m.vrclass, FPR32, m,
+ defm "Pseudo" # NAME : VPseudoBinaryRoundingMode<MxListW[i].vrclass,
+ MxListVF4[i].vrclass,
+ FPR32, MxListW[i],
Constraint, /*sew*/0,
UsesVXRM=0>;
}
@@ -592,7 +594,7 @@ multiclass VPatVFNRCLIP<string intrinsic, string instruction> {
defvar Vti = pair.Vti;
defvar Wti = pair.Wti;
defm : VPatBinaryRoundingMode<"int_riscv_sf_" # intrinsic,
- "Pseudo" # instruction # "_" # Wti.LMul.MX,
+ "Pseudo" # instruction # "_" # Vti.LMul.MX,
Vti.Vector, Wti.Vector, Wti.Scalar, Vti.Mask,
Vti.Log2SEW, Vti.RegClass,
Wti.RegClass, Wti.ScalarRegClass>;
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td
index 1ffa78a28d09..7c21fb4bcc1e 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
//
// This file describes the RISC-V instructions from the standard 'Zvk',
-// Vector Cryptography Instructions extension, version 1.0.0-rc1.
+// Vector Cryptography Instructions extension, version Release 1.0.0.
//
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVMacroFusion.cpp b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVMacroFusion.cpp
index 02ea5270823d..f948f05b22f7 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVMacroFusion.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVMacroFusion.cpp
@@ -58,18 +58,66 @@ static bool isLDADD(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
}
-// Fuse these patterns:
-//
-// slli rd, rs1, 32
-// srli rd, rd, x
-// where 0 <= x <= 32
-//
-// and
-//
+// Fuse zero extension of halfword:
// slli rd, rs1, 48
+// srli rd, rd, 48
+static bool isZExtH(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
+ if (SecondMI.getOpcode() != RISCV::SRLI)
+ return false;
+
+ if (!SecondMI.getOperand(2).isImm())
+ return false;
+
+ if (SecondMI.getOperand(2).getImm() != 48)
+ return false;
+
+ // Given SecondMI, when FirstMI is unspecified, we must return
+ // if SecondMI may be part of a fused pair at all.
+ if (!FirstMI)
+ return true;
+
+ if (FirstMI->getOpcode() != RISCV::SLLI)
+ return false;
+
+ if (FirstMI->getOperand(2).getImm() != 48)
+ return false;
+
+ return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
+}
+
+// Fuse zero extension of word:
+// slli rd, rs1, 32
+// srli rd, rd, 32
+static bool isZExtW(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
+ if (SecondMI.getOpcode() != RISCV::SRLI)
+ return false;
+
+ if (!SecondMI.getOperand(2).isImm())
+ return false;
+
+ if (SecondMI.getOperand(2).getImm() != 32)
+ return false;
+
+ // Given SecondMI, when FirstMI is unspecified, we must return
+ // if SecondMI may be part of a fused pair at all.
+ if (!FirstMI)
+ return true;
+
+ if (FirstMI->getOpcode() != RISCV::SLLI)
+ return false;
+
+ if (FirstMI->getOperand(2).getImm() != 32)
+ return false;
+
+ return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
+}
+
+// Fuse shifted zero extension of word:
+// slli rd, rs1, 32
// srli rd, rd, x
-static bool isShiftedZExt(const MachineInstr *FirstMI,
- const MachineInstr &SecondMI) {
+// where 0 <= x < 32
+static bool isShiftedZExtW(const MachineInstr *FirstMI,
+ const MachineInstr &SecondMI) {
if (SecondMI.getOpcode() != RISCV::SRLI)
return false;
@@ -77,8 +125,7 @@ static bool isShiftedZExt(const MachineInstr *FirstMI,
return false;
unsigned SRLIImm = SecondMI.getOperand(2).getImm();
- bool IsShiftBy48 = SRLIImm == 48;
- if (SRLIImm > 32 && !IsShiftBy48)
+ if (SRLIImm >= 32)
return false;
// Given SecondMI, when FirstMI is unspecified, we must return
@@ -89,8 +136,7 @@ static bool isShiftedZExt(const MachineInstr *FirstMI,
if (FirstMI->getOpcode() != RISCV::SLLI)
return false;
- unsigned SLLIImm = FirstMI->getOperand(2).getImm();
- if (IsShiftBy48 ? (SLLIImm != 48) : (SLLIImm != 32))
+ if (FirstMI->getOperand(2).getImm() != 32)
return false;
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
@@ -144,7 +190,13 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
if (ST.hasAUIPCADDIFusion() && isAUIPCADDI(FirstMI, SecondMI))
return true;
- if (ST.hasShiftedZExtFusion() && isShiftedZExt(FirstMI, SecondMI))
+ if (ST.hasZExtHFusion() && isZExtH(FirstMI, SecondMI))
+ return true;
+
+ if (ST.hasZExtWFusion() && isZExtW(FirstMI, SecondMI))
+ return true;
+
+ if (ST.hasShiftedZExtWFusion() && isShiftedZExtW(FirstMI, SecondMI))
return true;
if (ST.hasLDADDFusion() && isLDADD(FirstMI, SecondMI))
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVProcessors.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVProcessors.td
index 58989fd716fa..6362a3bef6f2 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -216,6 +216,25 @@ def SIFIVE_X280 : RISCVProcessorModel<"sifive-x280", SiFive7Model,
[TuneSiFive7,
TuneDLenFactor2]>;
+def SIFIVE_P450 : RISCVProcessorModel<"sifive-p450", NoSchedModel,
+ [Feature64Bit,
+ FeatureStdExtZifencei,
+ FeatureStdExtM,
+ FeatureStdExtA,
+ FeatureStdExtF,
+ FeatureStdExtD,
+ FeatureStdExtC,
+ FeatureStdExtZicbop,
+ FeatureStdExtZicbom,
+ FeatureStdExtZicboz,
+ FeatureStdExtZihintntl,
+ FeatureStdExtZihintpause,
+ FeatureStdExtZihpm,
+ FeatureStdExtZba,
+ FeatureStdExtZbb,
+ FeatureStdExtZbs,
+ FeatureStdExtZfhmin]>;
+
def SYNTACORE_SCR1_BASE : RISCVProcessorModel<"syntacore-scr1-base",
SyntacoreSCR1Model,
[Feature32Bit,
@@ -254,7 +273,13 @@ def VENTANA_VEYRON_V1 : RISCVProcessorModel<"veyron-v1",
FeatureStdExtZicbop,
FeatureStdExtZicboz,
FeatureVendorXVentanaCondOps],
- [TuneVeyronFusions]>;
+ [TuneVentanaVeyron,
+ TuneLUIADDIFusion,
+ TuneAUIPCADDIFusion,
+ TuneZExtHFusion,
+ TuneZExtWFusion,
+ TuneShiftedZExtWFusion,
+ TuneLDADDFusion]>;
def XIANGSHAN_NANHU : RISCVProcessorModel<"xiangshan-nanhu",
NoSchedModel,
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
index 45783d482f3b..f531ab2fac8f 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
@@ -198,6 +198,7 @@ def SiFive7Model : SchedMachineModel {
let LoadLatency = 3;
let MispredictPenalty = 3;
let CompleteModel = 0;
+ let EnableIntervals = true;
let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx,
HasStdExtZcmt, HasStdExtZknd, HasStdExtZkne,
HasStdExtZknh, HasStdExtZksed, HasStdExtZksh,
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSubtarget.h b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSubtarget.h
index 23d56cfa6e4e..26320b05d9be 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -143,16 +143,12 @@ public:
bool hasStdExtZvl() const { return ZvlLen != 0; }
bool hasStdExtFOrZfinx() const { return HasStdExtF || HasStdExtZfinx; }
bool hasStdExtDOrZdinx() const { return HasStdExtD || HasStdExtZdinx; }
- bool hasStdExtZfhOrZfhmin() const { return HasStdExtZfh || HasStdExtZfhmin; }
bool hasStdExtZfhOrZhinx() const { return HasStdExtZfh || HasStdExtZhinx; }
- bool hasStdExtZhinxOrZhinxmin() const {
- return HasStdExtZhinx || HasStdExtZhinxmin;
- }
- bool hasStdExtZfhOrZfhminOrZhinxOrZhinxmin() const {
- return hasStdExtZfhOrZfhmin() || hasStdExtZhinxOrZhinxmin();
+ bool hasStdExtZfhminOrZhinxmin() const {
+ return HasStdExtZfhmin || HasStdExtZhinxmin;
}
bool hasHalfFPLoadStoreMove() const {
- return hasStdExtZfhOrZfhmin() || HasStdExtZfbfmin;
+ return HasStdExtZfhmin || HasStdExtZfbfmin;
}
bool is64Bit() const { return IsRV64; }
MVT getXLenVT() const {
@@ -194,16 +190,14 @@ public:
}
bool hasMacroFusion() const {
- return hasLUIADDIFusion() || hasAUIPCADDIFusion() ||
- hasShiftedZExtFusion() || hasLDADDFusion();
+ return hasLUIADDIFusion() || hasAUIPCADDIFusion() || hasZExtHFusion() ||
+ hasZExtWFusion() || hasShiftedZExtWFusion() || hasLDADDFusion();
}
// Vector codegen related methods.
bool hasVInstructions() const { return HasStdExtZve32x; }
bool hasVInstructionsI64() const { return HasStdExtZve64x; }
- bool hasVInstructionsF16Minimal() const {
- return HasStdExtZvfhmin || HasStdExtZvfh;
- }
+ bool hasVInstructionsF16Minimal() const { return HasStdExtZvfhmin; }
bool hasVInstructionsF16() const { return HasStdExtZvfh; }
bool hasVInstructionsBF16() const { return HasStdExtZvfbfmin; }
bool hasVInstructionsF32() const { return HasStdExtZve32f; }
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
index efc8350064a6..96ecc771863e 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
@@ -334,7 +334,7 @@ public:
return RISCVRegisterClass::GPRRC;
Type *ScalarTy = Ty->getScalarType();
- if ((ScalarTy->isHalfTy() && ST->hasStdExtZfhOrZfhmin()) ||
+ if ((ScalarTy->isHalfTy() && ST->hasStdExtZfhmin()) ||
(ScalarTy->isFloatTy() && ST->hasStdExtF()) ||
(ScalarTy->isDoubleTy() && ST->hasStdExtD())) {
return RISCVRegisterClass::FPRRC;