From 6a0905d11ede27f2ac52338dc9d4bcd5c6e8a2f5 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 15 Nov 2024 17:23:46 -0800 Subject: [PATCH] [RISCV][GISel] Add isel patterns for i16 load/store (#116293) In order to support f16 load/store we need to make load/stores with s16 register type legal. If regbank selection doesn't pick the FPR bank, we'll be left with a GPR load or store which we don't have isel patterns for from SelectionDAG. In order to add the patterns we need to make i16 a legal type for the GPR register class. Tests are currently disabling the legality check because I haven't update the legalizer yet. --- llvm/lib/Target/RISCV/RISCVGISel.td | 17 ++++++++----- llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 2 +- .../instruction-select/load-rv32.mir | 25 ++++++++++++++++++- .../instruction-select/load-rv64.mir | 25 ++++++++++++++++++- .../instruction-select/store-rv32.mir | 25 ++++++++++++++++++- .../instruction-select/store-rv64.mir | 25 ++++++++++++++++++- 6 files changed, 108 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td index 58eb28927251..5130bb4c28cc 100644 --- a/llvm/lib/Target/RISCV/RISCVGISel.td +++ b/llvm/lib/Target/RISCV/RISCVGISel.td @@ -169,6 +169,11 @@ def : LdPat; def : StPat; } +// Load and store patterns for i16, needed because Zfh makes s16 load/store +// legal and regbank select may not constrain registers to FP. +def : LdPat; +def : StPat; + //===----------------------------------------------------------------------===// // RV64 i32 patterns not used by SelectionDAG //===----------------------------------------------------------------------===// @@ -187,16 +192,16 @@ def : LdPat; def : StPat; def : StPat; -def : Pat<(anyext GPR:$src), (COPY GPR:$src)>; -def : Pat<(sext GPR:$src), (ADDIW GPR:$src, 0)>; -def : Pat<(trunc GPR:$src), (COPY GPR:$src)>; +def : Pat<(anyext (i32 GPR:$src)), (COPY GPR:$src)>; +def : Pat<(sext (i32 GPR:$src)), (ADDIW GPR:$src, 0)>; +def : Pat<(i32 (trunc GPR:$src)), (COPY GPR:$src)>; // Use sext if the sign bit of the input is 0. -def : Pat<(zext_is_sext GPR:$src), (ADDIW GPR:$src, 0)>; +def : Pat<(zext_is_sext (i32 GPR:$src)), (ADDIW GPR:$src, 0)>; } let Predicates = [IsRV64, NotHasStdExtZba] in { -def : Pat<(zext GPR:$src), (SRLI (i64 (SLLI GPR:$src, 32)), 32)>; +def : Pat<(zext (i32 GPR:$src)), (SRLI (i64 (SLLI GPR:$src, 32)), 32)>; } //===----------------------------------------------------------------------===// @@ -204,5 +209,5 @@ def : Pat<(zext GPR:$src), (SRLI (i64 (SLLI GPR:$src, 32)), 32)>; //===----------------------------------------------------------------------===// let Predicates = [HasStdExtZba, IsRV64] in { -def : Pat<(zext GPR:$src), (ADD_UW GPR:$src, (XLenVT X0))>; +def : Pat<(zext (i32 GPR:$src)), (ADD_UW GPR:$src, (XLenVT X0))>; } diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td index 8a722baae89c..803c3ec19510 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -231,7 +231,7 @@ class RISCVRegisterClass regTypes, int align, dag regList> } class GPRRegisterClass - : RISCVRegisterClass<[XLenVT, XLenFVT, i32], 32, regList> { + : RISCVRegisterClass<[XLenVT, XLenFVT, i32, i16], 32, regList> { let RegInfos = XLenRI; } diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv32.mir index 36c604d4f5c5..3964fd1a918a 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv32.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv32.mir @@ -1,6 +1,6 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -mtriple=riscv32 -run-pass=instruction-select %s -o - \ -# RUN: | FileCheck %s +# RUN: -disable-gisel-legality-check | FileCheck %s --- name: load_i8 @@ -45,6 +45,29 @@ body: | $x10 = COPY %1(s32) PseudoRET implicit $x10 +... +--- +name: load_i16_i16 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: load_i16_i16 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[LH:%[0-9]+]]:gpr = LH [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: $x10 = COPY [[LH]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = COPY $x10 + %1:gprb(s16) = G_LOAD %0(p0) :: (load (s16)) + %2:gprb(s32) = G_ANYEXT %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + ... --- name: load_i32 diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv64.mir index 647e1e5287a8..70dd2bfee28b 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv64.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/load-rv64.mir @@ -1,6 +1,6 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -mtriple=riscv64 -run-pass=instruction-select %s -o - \ -# RUN: | FileCheck %s +# RUN: -disable-gisel-legality-check | FileCheck %s --- name: load_i8_i64 @@ -45,6 +45,29 @@ body: | $x10 = COPY %1(s64) PseudoRET implicit $x10 +... +--- +name: load_i16_i16 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: load_i16_i16 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[LH:%[0-9]+]]:gpr = LH [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: $x10 = COPY [[LH]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = COPY $x10 + %1:gprb(s16) = G_LOAD %0(p0) :: (load (s16)) + %2:gprb(s64) = G_ANYEXT %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + ... --- name: load_i32_i64 diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv32.mir index e4111417ece6..f1cc69517cf8 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv32.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv32.mir @@ -1,6 +1,6 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -mtriple=riscv32 -run-pass=instruction-select %s -o - \ -# RUN: | FileCheck %s +# RUN: -disable-gisel-legality-check | FileCheck %s # --- name: store_i8 @@ -45,6 +45,29 @@ body: | G_STORE %0(s32), %1(p0) :: (store (s16)) PseudoRET +... +--- +name: store_i16_i16 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10, $x11 + + ; CHECK-LABEL: name: store_i16_i16 + ; CHECK: liveins: $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: SH [[COPY]], [[COPY1]], 0 :: (store (s16)) + ; CHECK-NEXT: PseudoRET + %0:gprb(s32) = COPY $x10 + %1:gprb(p0) = COPY $x11 + %2:gprb(s16) = G_TRUNC %0 + G_STORE %2(s16), %1(p0) :: (store (s16)) + PseudoRET + ... --- name: store_i32 diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv64.mir index 385a330a97a1..69f590c1df59 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv64.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/store-rv64.mir @@ -1,6 +1,6 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -mtriple=riscv64 -run-pass=instruction-select %s -o - \ -# RUN: | FileCheck %s +# RUN: -disable-gisel-legality-check | FileCheck %s --- name: store_i8_i64 @@ -45,6 +45,29 @@ body: | G_STORE %0(s64), %1(p0) :: (store (s16)) PseudoRET +... +--- +name: store_i16_i16 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10, $x11 + + ; CHECK-LABEL: name: store_i16_i16 + ; CHECK: liveins: $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: SH [[COPY]], [[COPY1]], 0 :: (store (s16)) + ; CHECK-NEXT: PseudoRET + %0:gprb(s64) = COPY $x10 + %1:gprb(p0) = COPY $x11 + %2:gprb(s16) = G_TRUNC %0 + G_STORE %2(s16), %1(p0) :: (store (s16)) + PseudoRET + ... --- name: store_i32_i64