Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RISCV][GISel] Legalizer and register bank selection for G_JUMP_TABLE and G_BRJT #71970

Merged
merged 4 commits into from
Nov 10, 2023

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Nov 10, 2023

Testing together since they should come paired.

Instruction selection will be a separate PR.

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 10, 2023

@llvm/pr-subscribers-llvm-globalisel

Author: Craig Topper (topperc)

Changes

Testing together since they should come paired.

Instruction selection will be a separate PR.


Patch is 23.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/71970.diff

6 Files Affected:

  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+3-1)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp (+5)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir (+121)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir (+130)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir (+129)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir (+136)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 1aba6b78d8a9d9b..f7f3a4ba923fcce 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -131,12 +131,14 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
 
   getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);
 
+  getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}});
+
   getActionDefinitionsBuilder(G_PHI)
       .legalFor({p0, sXLen})
       .widenScalarToNextPow2(0)
       .clampScalar(0, sXLen, sXLen);
 
-  getActionDefinitionsBuilder(G_GLOBAL_VALUE)
+  getActionDefinitionsBuilder({G_GLOBAL_VALUE, G_JUMP_TABLE})
       .legalFor({p0});
 
   if (ST.hasStdExtM() || ST.hasStdExtZmmul()) {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index 60b6de0a760dcbb..3cdee17be8d1d88 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -166,12 +166,17 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
   case TargetOpcode::G_CONSTANT:
   case TargetOpcode::G_FRAME_INDEX:
   case TargetOpcode::G_GLOBAL_VALUE:
+  case TargetOpcode::G_JUMP_TABLE:
   case TargetOpcode::G_BRCOND:
     OperandsMapping = getOperandsMapping({GPRValueMapping, nullptr});
     break;
   case TargetOpcode::G_BR:
     OperandsMapping = getOperandsMapping({nullptr});
     break;
+  case TargetOpcode::G_BRJT:
+    OperandsMapping =
+        getOperandsMapping({GPRValueMapping, nullptr, GPRValueMapping});
+    break;
   case TargetOpcode::G_ICMP:
     OperandsMapping = getOperandsMapping(
         {GPRValueMapping, nullptr, GPRValueMapping, GPRValueMapping});
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir
new file mode 100644
index 000000000000000..c9c5411f1ffad18
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir
@@ -0,0 +1,121 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+--- |
+  define i32 @jt_test(i32 %x) {
+  entry:
+    switch i32 %x, label %return [
+      i32 75, label %sw.bb
+      i32 34, label %sw.bb
+      i32 56, label %sw.bb
+      i32 35, label %sw.bb
+      i32 40, label %sw.bb
+      i32 4, label %sw.bb1
+      i32 5, label %sw.bb1
+      i32 6, label %sw.bb1
+    ]
+
+  sw.bb:                                            ; preds = %entry, %entry, %entry, %entry, %entry
+    %add = add nsw i32 %x, 42
+    br label %return
+
+  sw.bb1:                                           ; preds = %entry, %entry, %entry
+    %mul = mul nsw i32 %x, 3
+    br label %return
+
+  return:                                           ; preds = %sw.bb1, %sw.bb, %entry
+    %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+    ret i32 %retval.0
+  }
+
+...
+---
+name:            jt_test
+tracksRegLiveness: true
+jumpTable:
+  kind:            block-address
+  entries:
+    - id:              0
+      blocks:          [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body:             |
+  ; CHECK-LABEL: name: jt_test
+  ; CHECK: bb.0.entry:
+  ; CHECK-NEXT:   successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+  ; CHECK-NEXT:   liveins: $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 71
+  ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+  ; CHECK-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+  ; CHECK-NEXT:   [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+  ; CHECK-NEXT:   [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+  ; CHECK-NEXT:   [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[C4]]
+  ; CHECK-NEXT:   [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[SUB]](s32), [[C]]
+  ; CHECK-NEXT:   G_BRCOND [[ICMP]](s32), %bb.4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1.entry:
+  ; CHECK-NEXT:   successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
+  ; CHECK-NEXT:   G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s32)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2.sw.bb:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(s32) = nsw G_ADD [[COPY]], [[C2]]
+  ; CHECK-NEXT:   G_BR %bb.4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3.sw.bb1:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[COPY]], [[C1]]
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4.return:
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:_(s32) = G_PHI [[MUL]](s32), %bb.3, [[ADD]](s32), %bb.2, [[C3]](s32), %bb.0, [[C3]](s32), %bb.1
+  ; CHECK-NEXT:   $x10 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  bb.1.entry:
+    successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+    liveins: $x10
+
+    %0:_(s32) = COPY $x10
+    %4:_(s32) = G_CONSTANT i32 71
+    %8:_(s32) = G_CONSTANT i32 3
+    %10:_(s32) = G_CONSTANT i32 42
+    %13:_(s32) = G_CONSTANT i32 0
+    %1:_(s32) = G_CONSTANT i32 4
+    %2:_(s32) = G_SUB %0, %1
+    %6:_(s1) = G_ICMP intpred(ugt), %2(s32), %4
+    G_BRCOND %6(s1), %bb.4
+
+  bb.5.entry:
+    successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+    %7:_(p0) = G_JUMP_TABLE %jump-table.0
+    G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+  bb.2.sw.bb:
+    %11:_(s32) = nsw G_ADD %0, %10
+    G_BR %bb.4
+
+  bb.3.sw.bb1:
+    %9:_(s32) = nsw G_MUL %0, %8
+
+  bb.4.return:
+    %12:_(s32) = G_PHI %9(s32), %bb.3, %11(s32), %bb.2, %13(s32), %bb.1, %13(s32), %bb.5
+    $x10 = COPY %12(s32)
+    PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir
new file mode 100644
index 000000000000000..22bcc9161b3e206
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir
@@ -0,0 +1,130 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+--- |
+  define i32 @jt_test(i32 %x) {
+  entry:
+    %0 = sext i32 %x to i64
+    switch i64 %0, label %return [
+      i64 75, label %sw.bb
+      i64 34, label %sw.bb
+      i64 56, label %sw.bb
+      i64 35, label %sw.bb
+      i64 40, label %sw.bb
+      i64 4, label %sw.bb1
+      i64 5, label %sw.bb1
+      i64 6, label %sw.bb1
+    ]
+
+  sw.bb:
+    %add = add nsw i32 %x, 42
+    br label %return
+
+  sw.bb1:
+    %mul = mul nsw i32 %x, 3
+    br label %return
+
+  return:
+    %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+    ret i32 %retval.0
+  }
+
+...
+---
+name:            jt_test
+tracksRegLiveness: true
+jumpTable:
+  kind:            custom32
+  entries:
+    - id:              0
+      blocks:          [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body:             |
+  ; CHECK-LABEL: name: jt_test
+  ; CHECK: bb.0.entry:
+  ; CHECK-NEXT:   successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+  ; CHECK-NEXT:   liveins: $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 71
+  ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+  ; CHECK-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+  ; CHECK-NEXT:   [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+  ; CHECK-NEXT:   [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+  ; CHECK-NEXT:   [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+  ; CHECK-NEXT:   [[SUB:%[0-9]+]]:_(s64) = G_SUB [[SEXT_INREG]], [[C4]]
+  ; CHECK-NEXT:   [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ugt), [[SUB]](s64), [[C]]
+  ; CHECK-NEXT:   G_BRCOND [[ICMP]](s64), %bb.4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1.entry:
+  ; CHECK-NEXT:   successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
+  ; CHECK-NEXT:   G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s64)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2.sw.bb:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(s32) = nsw G_ADD [[TRUNC]], [[C2]]
+  ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ADD]](s32)
+  ; CHECK-NEXT:   G_BR %bb.4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3.sw.bb1:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[TRUNC]], [[C1]]
+  ; CHECK-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[MUL]](s32)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4.return:
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:_(s64) = G_PHI [[ANYEXT1]](s64), %bb.3, [[ANYEXT]](s64), %bb.2, [[C3]](s64), %bb.0, [[C3]](s64), %bb.1
+  ; CHECK-NEXT:   $x10 = COPY [[PHI]](s64)
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  bb.1.entry:
+    successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+    liveins: $x10
+
+    %1:_(s64) = COPY $x10
+    %0:_(s32) = G_TRUNC %1(s64)
+    %6:_(s64) = G_CONSTANT i64 71
+    %10:_(s32) = G_CONSTANT i32 3
+    %12:_(s32) = G_CONSTANT i32 42
+    %19:_(s64) = G_CONSTANT i64 0
+    %2:_(s64) = G_SEXT %0(s32)
+    %3:_(s64) = G_CONSTANT i64 4
+    %4:_(s64) = G_SUB %2, %3
+    %8:_(s1) = G_ICMP intpred(ugt), %4(s64), %6
+    G_BRCOND %8(s1), %bb.4
+
+  bb.5.entry:
+    successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+    %9:_(p0) = G_JUMP_TABLE %jump-table.0
+    G_BRJT %9(p0), %jump-table.0, %4(s64)
+
+  bb.2.sw.bb:
+    %13:_(s32) = nsw G_ADD %0, %12
+    %18:_(s64) = G_ANYEXT %13(s32)
+    G_BR %bb.4
+
+  bb.3.sw.bb1:
+    %11:_(s32) = nsw G_MUL %0, %10
+    %17:_(s64) = G_ANYEXT %11(s32)
+
+  bb.4.return:
+    %15:_(s64) = G_PHI %17(s64), %bb.3, %18(s64), %bb.2, %19(s64), %bb.1, %19(s64), %bb.5
+    $x10 = COPY %15(s64)
+    PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir
new file mode 100644
index 000000000000000..24be1b754ae94c9
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir
@@ -0,0 +1,129 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=regbankselect \
+# RUN:   -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN:   -o - | FileCheck -check-prefix=RV32I %s
+
+--- |
+  define i32 @jt_test(i32 %x) {
+  entry:
+    switch i32 %x, label %return [
+      i32 75, label %sw.bb
+      i32 34, label %sw.bb
+      i32 56, label %sw.bb
+      i32 35, label %sw.bb
+      i32 40, label %sw.bb
+      i32 4, label %sw.bb1
+      i32 5, label %sw.bb1
+      i32 6, label %sw.bb1
+    ]
+
+  sw.bb:                                            ; preds = %entry, %entry, %entry, %entry, %entry
+    %add = add nsw i32 %x, 42
+    br label %return
+
+  sw.bb1:                                           ; preds = %entry, %entry, %entry
+    %mul = mul nsw i32 %x, 3
+    br label %return
+
+  return:                                           ; preds = %sw.bb1, %sw.bb, %entry
+    %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+    ret i32 %retval.0
+  }
+
+...
+---
+name:            jt_test
+legalized:       true
+tracksRegLiveness: true
+jumpTable:
+  kind:            block-address
+  entries:
+    - id:              0
+      blocks:          [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body:             |
+  ; RV32I-LABEL: name: jt_test
+  ; RV32I: bb.0.entry:
+  ; RV32I-NEXT:   successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+  ; RV32I-NEXT:   liveins: $x10
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
+  ; RV32I-NEXT:   [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 71
+  ; RV32I-NEXT:   [[C1:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 3
+  ; RV32I-NEXT:   [[C2:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 42
+  ; RV32I-NEXT:   [[C3:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 0
+  ; RV32I-NEXT:   [[C4:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 4
+  ; RV32I-NEXT:   [[SUB:%[0-9]+]]:gprb(s32) = G_SUB [[COPY]], [[C4]]
+  ; RV32I-NEXT:   [[ICMP:%[0-9]+]]:gprb(s32) = G_ICMP intpred(ugt), [[SUB]](s32), [[C]]
+  ; RV32I-NEXT:   G_BRCOND [[ICMP]](s32), %bb.4
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT: bb.1.entry:
+  ; RV32I-NEXT:   successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT:   [[JUMP_TABLE:%[0-9]+]]:gprb(p0) = G_JUMP_TABLE %jump-table.0
+  ; RV32I-NEXT:   G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s32)
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT: bb.2.sw.bb:
+  ; RV32I-NEXT:   [[ADD:%[0-9]+]]:gprb(s32) = nsw G_ADD [[COPY]], [[C2]]
+  ; RV32I-NEXT:   G_BR %bb.4
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT: bb.3.sw.bb1:
+  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+  ; RV32I-NEXT:   $x10 = COPY [[COPY]](s32)
+  ; RV32I-NEXT:   $x11 = COPY [[C1]](s32)
+  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) &__mulsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+  ; RV32I-NEXT:   [[COPY1:%[0-9]+]]:gprb(s32) = COPY $x10
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT: bb.4.return:
+  ; RV32I-NEXT:   [[PHI:%[0-9]+]]:gprb(s32) = G_PHI [[COPY1]](s32), %bb.3, [[ADD]](s32), %bb.2, [[C3]](s32), %bb.0, [[C3]](s32), %bb.1
+  ; RV32I-NEXT:   $x10 = COPY [[PHI]](s32)
+  ; RV32I-NEXT:   PseudoRET implicit $x10
+  bb.1.entry:
+    successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+    liveins: $x10
+
+    %0:_(s32) = COPY $x10
+    %4:_(s32) = G_CONSTANT i32 71
+    %8:_(s32) = G_CONSTANT i32 3
+    %10:_(s32) = G_CONSTANT i32 42
+    %13:_(s32) = G_CONSTANT i32 0
+    %1:_(s32) = G_CONSTANT i32 4
+    %2:_(s32) = G_SUB %0, %1
+    %15:_(s32) = G_ICMP intpred(ugt), %2(s32), %4
+    G_BRCOND %15(s32), %bb.4
+
+  bb.5.entry:
+    successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+    %7:_(p0) = G_JUMP_TABLE %jump-table.0
+    G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+  bb.2.sw.bb:
+    %11:_(s32) = nsw G_ADD %0, %10
+    G_BR %bb.4
+
+  bb.3.sw.bb1:
+    ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+    $x10 = COPY %0(s32)
+    $x11 = COPY %8(s32)
+    PseudoCALL target-flags(riscv-call) &__mulsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+    %9:_(s32) = COPY $x10
+
+  bb.4.return:
+    %12:_(s32) = G_PHI %9(s32), %bb.3, %11(s32), %bb.2, %13(s32), %bb.1, %13(s32), %bb.5
+    $x10 = COPY %12(s32)
+    PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir
new file mode 100644
index 000000000000000..6dbabeec8f6fd13
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir
@@ -0,0 +1,136 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=regbankselect \
+# RUN:   -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN:   -o - | FileCheck -check-prefix=RV64I %s
+
+--- |
+  define i32 @jt_test(i32 %x) {
+  entry:
+    %0 = sext i32 %x to i64
+    switch i64 %0, label %return [
+      i64 75, label %sw.bb
+      i64 34, label %sw.bb
+      i64 56, label %sw.bb
+      i64 35, label %sw.bb
+      i64 40, label %sw.bb
+      i64 4, label %sw.bb1
+      i64 5, label %sw.bb1
+      i64 6, label %sw.bb1
+    ]
+
+  sw.bb:                                            ; preds = %entry, %entry, %entry, %entry, %entry
+    %add = add nsw i32 %x, 42
+    br label %return
+
+  sw.bb1:                                           ; preds = %entry, %entry, %entry
+    %mul = mul nsw i32 %x, 3
+    br label %return
+
+  return:                                           ; preds = %sw.bb1, %sw.bb, %entry
+    %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+    ret i32 %retval.0
+  }
+
+...
+---
+name:            jt_test
+legalized:       true
+tracksRegLiveness: true
+jumpTable:
+  kind:            custom32
+  entries:
+    - id:              0
+      blocks:          [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb...
[truncated]

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 10, 2023

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

Changes

Testing together since they should come paired.

Instruction selection will be a separate PR.


Patch is 23.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/71970.diff

6 Files Affected:

  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+3-1)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp (+5)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir (+121)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir (+130)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir (+129)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir (+136)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 1aba6b78d8a9d9b..f7f3a4ba923fcce 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -131,12 +131,14 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
 
   getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);
 
+  getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}});
+
   getActionDefinitionsBuilder(G_PHI)
       .legalFor({p0, sXLen})
       .widenScalarToNextPow2(0)
       .clampScalar(0, sXLen, sXLen);
 
-  getActionDefinitionsBuilder(G_GLOBAL_VALUE)
+  getActionDefinitionsBuilder({G_GLOBAL_VALUE, G_JUMP_TABLE})
       .legalFor({p0});
 
   if (ST.hasStdExtM() || ST.hasStdExtZmmul()) {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index 60b6de0a760dcbb..3cdee17be8d1d88 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -166,12 +166,17 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
   case TargetOpcode::G_CONSTANT:
   case TargetOpcode::G_FRAME_INDEX:
   case TargetOpcode::G_GLOBAL_VALUE:
+  case TargetOpcode::G_JUMP_TABLE:
   case TargetOpcode::G_BRCOND:
     OperandsMapping = getOperandsMapping({GPRValueMapping, nullptr});
     break;
   case TargetOpcode::G_BR:
     OperandsMapping = getOperandsMapping({nullptr});
     break;
+  case TargetOpcode::G_BRJT:
+    OperandsMapping =
+        getOperandsMapping({GPRValueMapping, nullptr, GPRValueMapping});
+    break;
   case TargetOpcode::G_ICMP:
     OperandsMapping = getOperandsMapping(
         {GPRValueMapping, nullptr, GPRValueMapping, GPRValueMapping});
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir
new file mode 100644
index 000000000000000..c9c5411f1ffad18
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir
@@ -0,0 +1,121 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+--- |
+  define i32 @jt_test(i32 %x) {
+  entry:
+    switch i32 %x, label %return [
+      i32 75, label %sw.bb
+      i32 34, label %sw.bb
+      i32 56, label %sw.bb
+      i32 35, label %sw.bb
+      i32 40, label %sw.bb
+      i32 4, label %sw.bb1
+      i32 5, label %sw.bb1
+      i32 6, label %sw.bb1
+    ]
+
+  sw.bb:                                            ; preds = %entry, %entry, %entry, %entry, %entry
+    %add = add nsw i32 %x, 42
+    br label %return
+
+  sw.bb1:                                           ; preds = %entry, %entry, %entry
+    %mul = mul nsw i32 %x, 3
+    br label %return
+
+  return:                                           ; preds = %sw.bb1, %sw.bb, %entry
+    %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+    ret i32 %retval.0
+  }
+
+...
+---
+name:            jt_test
+tracksRegLiveness: true
+jumpTable:
+  kind:            block-address
+  entries:
+    - id:              0
+      blocks:          [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body:             |
+  ; CHECK-LABEL: name: jt_test
+  ; CHECK: bb.0.entry:
+  ; CHECK-NEXT:   successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+  ; CHECK-NEXT:   liveins: $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 71
+  ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+  ; CHECK-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+  ; CHECK-NEXT:   [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+  ; CHECK-NEXT:   [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+  ; CHECK-NEXT:   [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[C4]]
+  ; CHECK-NEXT:   [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[SUB]](s32), [[C]]
+  ; CHECK-NEXT:   G_BRCOND [[ICMP]](s32), %bb.4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1.entry:
+  ; CHECK-NEXT:   successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
+  ; CHECK-NEXT:   G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s32)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2.sw.bb:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(s32) = nsw G_ADD [[COPY]], [[C2]]
+  ; CHECK-NEXT:   G_BR %bb.4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3.sw.bb1:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[COPY]], [[C1]]
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4.return:
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:_(s32) = G_PHI [[MUL]](s32), %bb.3, [[ADD]](s32), %bb.2, [[C3]](s32), %bb.0, [[C3]](s32), %bb.1
+  ; CHECK-NEXT:   $x10 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  bb.1.entry:
+    successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+    liveins: $x10
+
+    %0:_(s32) = COPY $x10
+    %4:_(s32) = G_CONSTANT i32 71
+    %8:_(s32) = G_CONSTANT i32 3
+    %10:_(s32) = G_CONSTANT i32 42
+    %13:_(s32) = G_CONSTANT i32 0
+    %1:_(s32) = G_CONSTANT i32 4
+    %2:_(s32) = G_SUB %0, %1
+    %6:_(s1) = G_ICMP intpred(ugt), %2(s32), %4
+    G_BRCOND %6(s1), %bb.4
+
+  bb.5.entry:
+    successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+    %7:_(p0) = G_JUMP_TABLE %jump-table.0
+    G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+  bb.2.sw.bb:
+    %11:_(s32) = nsw G_ADD %0, %10
+    G_BR %bb.4
+
+  bb.3.sw.bb1:
+    %9:_(s32) = nsw G_MUL %0, %8
+
+  bb.4.return:
+    %12:_(s32) = G_PHI %9(s32), %bb.3, %11(s32), %bb.2, %13(s32), %bb.1, %13(s32), %bb.5
+    $x10 = COPY %12(s32)
+    PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir
new file mode 100644
index 000000000000000..22bcc9161b3e206
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir
@@ -0,0 +1,130 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+--- |
+  define i32 @jt_test(i32 %x) {
+  entry:
+    %0 = sext i32 %x to i64
+    switch i64 %0, label %return [
+      i64 75, label %sw.bb
+      i64 34, label %sw.bb
+      i64 56, label %sw.bb
+      i64 35, label %sw.bb
+      i64 40, label %sw.bb
+      i64 4, label %sw.bb1
+      i64 5, label %sw.bb1
+      i64 6, label %sw.bb1
+    ]
+
+  sw.bb:
+    %add = add nsw i32 %x, 42
+    br label %return
+
+  sw.bb1:
+    %mul = mul nsw i32 %x, 3
+    br label %return
+
+  return:
+    %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+    ret i32 %retval.0
+  }
+
+...
+---
+name:            jt_test
+tracksRegLiveness: true
+jumpTable:
+  kind:            custom32
+  entries:
+    - id:              0
+      blocks:          [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body:             |
+  ; CHECK-LABEL: name: jt_test
+  ; CHECK: bb.0.entry:
+  ; CHECK-NEXT:   successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+  ; CHECK-NEXT:   liveins: $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 71
+  ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+  ; CHECK-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+  ; CHECK-NEXT:   [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+  ; CHECK-NEXT:   [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+  ; CHECK-NEXT:   [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+  ; CHECK-NEXT:   [[SUB:%[0-9]+]]:_(s64) = G_SUB [[SEXT_INREG]], [[C4]]
+  ; CHECK-NEXT:   [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ugt), [[SUB]](s64), [[C]]
+  ; CHECK-NEXT:   G_BRCOND [[ICMP]](s64), %bb.4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1.entry:
+  ; CHECK-NEXT:   successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
+  ; CHECK-NEXT:   G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s64)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2.sw.bb:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(s32) = nsw G_ADD [[TRUNC]], [[C2]]
+  ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ADD]](s32)
+  ; CHECK-NEXT:   G_BR %bb.4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3.sw.bb1:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[TRUNC]], [[C1]]
+  ; CHECK-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[MUL]](s32)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4.return:
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:_(s64) = G_PHI [[ANYEXT1]](s64), %bb.3, [[ANYEXT]](s64), %bb.2, [[C3]](s64), %bb.0, [[C3]](s64), %bb.1
+  ; CHECK-NEXT:   $x10 = COPY [[PHI]](s64)
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  bb.1.entry:
+    successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+    liveins: $x10
+
+    %1:_(s64) = COPY $x10
+    %0:_(s32) = G_TRUNC %1(s64)
+    %6:_(s64) = G_CONSTANT i64 71
+    %10:_(s32) = G_CONSTANT i32 3
+    %12:_(s32) = G_CONSTANT i32 42
+    %19:_(s64) = G_CONSTANT i64 0
+    %2:_(s64) = G_SEXT %0(s32)
+    %3:_(s64) = G_CONSTANT i64 4
+    %4:_(s64) = G_SUB %2, %3
+    %8:_(s1) = G_ICMP intpred(ugt), %4(s64), %6
+    G_BRCOND %8(s1), %bb.4
+
+  bb.5.entry:
+    successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+    %9:_(p0) = G_JUMP_TABLE %jump-table.0
+    G_BRJT %9(p0), %jump-table.0, %4(s64)
+
+  bb.2.sw.bb:
+    %13:_(s32) = nsw G_ADD %0, %12
+    %18:_(s64) = G_ANYEXT %13(s32)
+    G_BR %bb.4
+
+  bb.3.sw.bb1:
+    %11:_(s32) = nsw G_MUL %0, %10
+    %17:_(s64) = G_ANYEXT %11(s32)
+
+  bb.4.return:
+    %15:_(s64) = G_PHI %17(s64), %bb.3, %18(s64), %bb.2, %19(s64), %bb.1, %19(s64), %bb.5
+    $x10 = COPY %15(s64)
+    PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir
new file mode 100644
index 000000000000000..24be1b754ae94c9
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir
@@ -0,0 +1,129 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=regbankselect \
+# RUN:   -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN:   -o - | FileCheck -check-prefix=RV32I %s
+
+--- |
+  define i32 @jt_test(i32 %x) {
+  entry:
+    switch i32 %x, label %return [
+      i32 75, label %sw.bb
+      i32 34, label %sw.bb
+      i32 56, label %sw.bb
+      i32 35, label %sw.bb
+      i32 40, label %sw.bb
+      i32 4, label %sw.bb1
+      i32 5, label %sw.bb1
+      i32 6, label %sw.bb1
+    ]
+
+  sw.bb:                                            ; preds = %entry, %entry, %entry, %entry, %entry
+    %add = add nsw i32 %x, 42
+    br label %return
+
+  sw.bb1:                                           ; preds = %entry, %entry, %entry
+    %mul = mul nsw i32 %x, 3
+    br label %return
+
+  return:                                           ; preds = %sw.bb1, %sw.bb, %entry
+    %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+    ret i32 %retval.0
+  }
+
+...
+---
+name:            jt_test
+legalized:       true
+tracksRegLiveness: true
+jumpTable:
+  kind:            block-address
+  entries:
+    - id:              0
+      blocks:          [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body:             |
+  ; RV32I-LABEL: name: jt_test
+  ; RV32I: bb.0.entry:
+  ; RV32I-NEXT:   successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+  ; RV32I-NEXT:   liveins: $x10
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
+  ; RV32I-NEXT:   [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 71
+  ; RV32I-NEXT:   [[C1:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 3
+  ; RV32I-NEXT:   [[C2:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 42
+  ; RV32I-NEXT:   [[C3:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 0
+  ; RV32I-NEXT:   [[C4:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 4
+  ; RV32I-NEXT:   [[SUB:%[0-9]+]]:gprb(s32) = G_SUB [[COPY]], [[C4]]
+  ; RV32I-NEXT:   [[ICMP:%[0-9]+]]:gprb(s32) = G_ICMP intpred(ugt), [[SUB]](s32), [[C]]
+  ; RV32I-NEXT:   G_BRCOND [[ICMP]](s32), %bb.4
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT: bb.1.entry:
+  ; RV32I-NEXT:   successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT:   [[JUMP_TABLE:%[0-9]+]]:gprb(p0) = G_JUMP_TABLE %jump-table.0
+  ; RV32I-NEXT:   G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s32)
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT: bb.2.sw.bb:
+  ; RV32I-NEXT:   [[ADD:%[0-9]+]]:gprb(s32) = nsw G_ADD [[COPY]], [[C2]]
+  ; RV32I-NEXT:   G_BR %bb.4
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT: bb.3.sw.bb1:
+  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+  ; RV32I-NEXT:   $x10 = COPY [[COPY]](s32)
+  ; RV32I-NEXT:   $x11 = COPY [[C1]](s32)
+  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) &__mulsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+  ; RV32I-NEXT:   [[COPY1:%[0-9]+]]:gprb(s32) = COPY $x10
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT: bb.4.return:
+  ; RV32I-NEXT:   [[PHI:%[0-9]+]]:gprb(s32) = G_PHI [[COPY1]](s32), %bb.3, [[ADD]](s32), %bb.2, [[C3]](s32), %bb.0, [[C3]](s32), %bb.1
+  ; RV32I-NEXT:   $x10 = COPY [[PHI]](s32)
+  ; RV32I-NEXT:   PseudoRET implicit $x10
+  bb.1.entry:
+    successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+    liveins: $x10
+
+    %0:_(s32) = COPY $x10
+    %4:_(s32) = G_CONSTANT i32 71
+    %8:_(s32) = G_CONSTANT i32 3
+    %10:_(s32) = G_CONSTANT i32 42
+    %13:_(s32) = G_CONSTANT i32 0
+    %1:_(s32) = G_CONSTANT i32 4
+    %2:_(s32) = G_SUB %0, %1
+    %15:_(s32) = G_ICMP intpred(ugt), %2(s32), %4
+    G_BRCOND %15(s32), %bb.4
+
+  bb.5.entry:
+    successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+    %7:_(p0) = G_JUMP_TABLE %jump-table.0
+    G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+  bb.2.sw.bb:
+    %11:_(s32) = nsw G_ADD %0, %10
+    G_BR %bb.4
+
+  bb.3.sw.bb1:
+    ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+    $x10 = COPY %0(s32)
+    $x11 = COPY %8(s32)
+    PseudoCALL target-flags(riscv-call) &__mulsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+    ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+    %9:_(s32) = COPY $x10
+
+  bb.4.return:
+    %12:_(s32) = G_PHI %9(s32), %bb.3, %11(s32), %bb.2, %13(s32), %bb.1, %13(s32), %bb.5
+    $x10 = COPY %12(s32)
+    PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir
new file mode 100644
index 000000000000000..6dbabeec8f6fd13
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir
@@ -0,0 +1,136 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=regbankselect \
+# RUN:   -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN:   -o - | FileCheck -check-prefix=RV64I %s
+
+--- |
+  define i32 @jt_test(i32 %x) {
+  entry:
+    %0 = sext i32 %x to i64
+    switch i64 %0, label %return [
+      i64 75, label %sw.bb
+      i64 34, label %sw.bb
+      i64 56, label %sw.bb
+      i64 35, label %sw.bb
+      i64 40, label %sw.bb
+      i64 4, label %sw.bb1
+      i64 5, label %sw.bb1
+      i64 6, label %sw.bb1
+    ]
+
+  sw.bb:                                            ; preds = %entry, %entry, %entry, %entry, %entry
+    %add = add nsw i32 %x, 42
+    br label %return
+
+  sw.bb1:                                           ; preds = %entry, %entry, %entry
+    %mul = mul nsw i32 %x, 3
+    br label %return
+
+  return:                                           ; preds = %sw.bb1, %sw.bb, %entry
+    %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+    ret i32 %retval.0
+  }
+
+...
+---
+name:            jt_test
+legalized:       true
+tracksRegLiveness: true
+jumpTable:
+  kind:            custom32
+  entries:
+    - id:              0
+      blocks:          [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+                         '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb...
[truncated]

Copy link

github-actions bot commented Nov 10, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

; CHECK-NEXT: $x10 = COPY [[PHI]](s32)
; CHECK-NEXT: PseudoRET implicit $x10
bb.1.entry:
successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need the branch probability data? It may make the test easier to read without it?

]

sw.bb: ; preds = %entry, %entry, %entry, %entry, %entry
%add = add nsw i32 %x, 42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the add and mul here? Can we just return? Legalizer and regbank selection will never do any any optimizing of the jump table to the default label if jump targets only contain a branch to the default label.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just copied this test from AArch64's IR translator and selection test. I'll simplify it.

kind: block-address
entries:
- id: 0
blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be so big to convey the functionality in this test?

@@ -131,13 +131,14 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {

getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);

getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to respond to your comment from #71951

Does the s32 case ever occur? IRTranslator::emitJumpTableHeader seems to use the integer size of the pointer to create the type for that operand.

It would be fine to only support sXLen, although it definitely would be legal if we used s32 since it'll always generate a valid offset. I am okay to omit s32 as a legal type here to simplify. I don't have a strong opinion so you can decide.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it generated s32, the instruction selection code would have to insert an extend to use the index wouldn't it?

Copy link
Contributor

@michaelmaitland michaelmaitland Nov 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, sounds like it is better to not legalize it to avoid doing the extra work in selection to extend, and the code would be worse.

@@ -0,0 +1,159 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=riscv64 -mattr=+m -run-pass=legalizer %s -o - \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still need +m?

Copy link
Contributor

@michaelmaitland michaelmaitland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@topperc topperc merged commit ca60334 into llvm:main Nov 10, 2023
2 of 3 checks passed
@topperc topperc deleted the pr/jumptable branch November 10, 2023 21:09
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
… and G_BRJT (llvm#71970)

Testing together since they should come paired.

Instruction selection will be a separate PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants