diff options
author | Craig Topper <craig.topper@sifive.com> | 2024-11-17 11:25:33 -0800 |
---|---|---|
committer | Craig Topper <craig.topper@sifive.com> | 2024-11-17 11:39:59 -0800 |
commit | eed9af95e6133e94449c7be585bc3b5fad8ad769 (patch) | |
tree | eea474811a25882235c3a5fd02ea400437ef6e92 /llvm/lib | |
parent | a8538b9138574142b9338ad0fce0f8ba1065fcbc (diff) | |
download | llvm-eed9af95e6133e94449c7be585bc3b5fad8ad769.zip llvm-eed9af95e6133e94449c7be585bc3b5fad8ad769.tar.gz llvm-eed9af95e6133e94449c7be585bc3b5fad8ad769.tar.bz2 |
[RISCV][GISel] Make loads/stores with s16 register type and s16 memory type legal.
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.
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVFeatures.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVGISel.td | 34 |
3 files changed, 50 insertions, 7 deletions
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 82b6dcd..f8a1343 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -154,9 +154,10 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) .clampScalar(0, sXLen, sXLen); getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT}) + .legalFor({{sXLen, s16}}) + .legalFor(ST.is64Bit(), {{s64, s32}}) .legalIf(all(typeIsLegalIntOrFPVec(0, IntOrFPVecTys, ST), typeIsLegalIntOrFPVec(1, IntOrFPVecTys, ST))) - .legalFor(ST.is64Bit(), {{sXLen, s32}}) .customIf(typeIsLegalBoolVec(1, BoolVecTys, ST)) .maxScalar(0, sXLen); @@ -234,8 +235,18 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) .clampScalar(0, sXLen, sXLen); // TODO: transform illegal vector types into legal vector type + getActionDefinitionsBuilder(G_FREEZE) + .legalFor({s16, s32, p0}) + .legalFor(ST.is64Bit(), {s64}) + .legalIf(typeIsLegalBoolVec(0, BoolVecTys, ST)) + .legalIf(typeIsLegalIntOrFPVec(0, IntOrFPVecTys, ST)) + .widenScalarToNextPow2(0) + .clampScalar(0, s16, sXLen); + + // TODO: transform illegal vector types into legal vector type + // TODO: Merge with G_FREEZE? getActionDefinitionsBuilder( - {G_IMPLICIT_DEF, G_CONSTANT_FOLD_BARRIER, G_FREEZE}) + {G_IMPLICIT_DEF, G_CONSTANT_FOLD_BARRIER}) .legalFor({s32, sXLen, p0}) .legalIf(typeIsLegalBoolVec(0, BoolVecTys, ST)) .legalIf(typeIsLegalIntOrFPVec(0, IntOrFPVecTys, ST)) @@ -271,12 +282,14 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) }; LoadActions.legalForTypesWithMemDesc( - {{s32, p0, s8, getScalarMemAlign(8)}, + {{s16, p0, s16, getScalarMemAlign(16)}, + {s32, p0, s8, getScalarMemAlign(8)}, {s32, p0, s16, getScalarMemAlign(16)}, {s32, p0, s32, getScalarMemAlign(32)}, {p0, p0, sXLen, getScalarMemAlign(XLen)}}); StoreActions.legalForTypesWithMemDesc( - {{s32, p0, s8, getScalarMemAlign(8)}, + {{s16, p0, s16, getScalarMemAlign(16)}, + {s32, p0, s8, getScalarMemAlign(8)}, {s32, p0, s16, getScalarMemAlign(16)}, {s32, p0, s32, getScalarMemAlign(32)}, {p0, p0, sXLen, getScalarMemAlign(XLen)}}); diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 6ec7f9a..3977816 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -523,6 +523,8 @@ def FeatureStdExtZbkb def HasStdExtZbkb : Predicate<"Subtarget->hasStdExtZbkb()">, AssemblerPredicate<(all_of FeatureStdExtZbkb), "'Zbkb' (Bitmanip instructions for Cryptography)">; +def NoStdExtZbkb : Predicate<"!Subtarget->hasStdExtZbkb()">, + AssemblerPredicate<(all_of (not FeatureStdExtZbkb))>; def FeatureStdExtZbkx : RISCVExtension<"zbkx", 1, 0, diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td index 5130bb4..8d1196c 100644 --- a/llvm/lib/Target/RISCV/RISCVGISel.td +++ b/llvm/lib/Target/RISCV/RISCVGISel.td @@ -200,14 +200,42 @@ def : Pat<(i32 (trunc GPR:$src)), (COPY GPR:$src)>; def : Pat<(zext_is_sext (i32 GPR:$src)), (ADDIW GPR:$src, 0)>; } -let Predicates = [IsRV64, NotHasStdExtZba] in { +let Predicates = [IsRV64, NotHasStdExtZba] in def : Pat<(zext (i32 GPR:$src)), (SRLI (i64 (SLLI GPR:$src, 32)), 32)>; -} + +let Predicates = [IsRV32, NoStdExtZbb, NoStdExtZbkb] in +def : Pat<(XLenVT (zext (i16 GPR:$src))), + (SRLI (XLenVT (SLLI GPR:$src, 16)), 16)>; + +let Predicates = [IsRV64, NoStdExtZbb, NoStdExtZbkb] in +def : Pat<(i64 (zext (i16 GPR:$src))), + (SRLI (XLenVT (SLLI GPR:$src, 48)), 48)>; + +let Predicates = [IsRV32, NoStdExtZbb] in +def : Pat<(XLenVT (sext (i16 GPR:$src))), + (SRAI (XLenVT (SLLI GPR:$src, 16)), 16)>; + +let Predicates = [IsRV64, NoStdExtZbb] in +def : Pat<(i64 (sext (i16 GPR:$src))), + (SRAI (XLenVT (SLLI GPR:$src, 48)), 48)>; //===----------------------------------------------------------------------===// -// Zb* RV64 i32 patterns not used by SelectionDAG. +// Zb* RV64 patterns not used by SelectionDAG. //===----------------------------------------------------------------------===// let Predicates = [HasStdExtZba, IsRV64] in { def : Pat<(zext (i32 GPR:$src)), (ADD_UW GPR:$src, (XLenVT X0))>; } + +let Predicates= [HasStdExtZbb] in +def : Pat<(XLenVT (sext (i16 GPR:$rs))), (SEXT_H GPR:$rs)>; + +let Predicates = [HasStdExtZbb, IsRV32] in +def : Pat<(i32 (zext (i16 GPR:$rs))), (ZEXT_H_RV32 GPR:$rs)>; +let Predicates = [HasStdExtZbb, IsRV64] in +def : Pat<(i64 (zext (i16 GPR:$rs))), (ZEXT_H_RV64 GPR:$rs)>; + +let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32] in +def : Pat<(i32 (zext (i16 GPR:$rs))), (PACK GPR:$rs, (XLenVT X0))>; +let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in +def : Pat<(i64 (zext (i16 GPR:$rs))), (PACKW GPR:$rs, (XLenVT X0))>; |