[llvm] [RISCV][GISel] Add isel patterns for i16 load/store (PR #116293)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 14 14:39:41 PST 2024


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/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.

>From 738318a82e9a80bcf936d5a242b5e14d5d51772f Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 14 Nov 2024 14:13:18 -0800
Subject: [PATCH] [RISCV][GISel] Add isel patterns for i16 load/store

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 58eb28927251eb..5130bb4c28ccc8 100644
--- a/llvm/lib/Target/RISCV/RISCVGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVGISel.td
@@ -169,6 +169,11 @@ def : LdPat<load, LD, PtrVT>;
 def : StPat<store, SD, GPR, PtrVT>;
 }
 
+// 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<load, LH, i16>;
+def : StPat<store, SH, GPR, i16>;
+
 //===----------------------------------------------------------------------===//
 // RV64 i32 patterns not used by SelectionDAG
 //===----------------------------------------------------------------------===//
@@ -187,16 +192,16 @@ def : LdPat<extloadi16, LH, i32>;
 def : StPat<truncstorei8, SB, GPR, i32>;
 def : StPat<truncstorei16, SH, GPR, i32>;
 
-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 8a722baae89c90..803c3ec1951060 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -231,7 +231,7 @@ class RISCVRegisterClass<list<ValueType> regTypes, int align, dag regList>
 }
 
 class GPRRegisterClass<dag regList>
-    : 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 36c604d4f5c529..3964fd1a918aa4 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 647e1e5287a80b..70dd2bfee28ba1 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 e4111417ece672..f1cc69517cf8f7 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 385a330a97a175..69f590c1df5970 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



More information about the llvm-commits mailing list