[LoongArch] Support lowering br_jt
authorWANG Xuerui <git@xen0n.name>
Fri, 2 Sep 2022 09:57:29 +0000 (17:57 +0800)
committerWeining Lu <luweining@loongson.cn>
Fri, 2 Sep 2022 09:57:50 +0000 (17:57 +0800)
Jump tables cannot be generated yet, due to missing support for emitting
local addresses.

Differential Revision: https://reviews.llvm.org/D132653

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
llvm/test/CodeGen/LoongArch/jump-table.ll [new file with mode: 0644]

index d5efdf7..054ef3c 100644 (file)
@@ -114,6 +114,10 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
     setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
   }
 
+  // Effectively disable jump table generation.
+  setMinimumJumpTableEntries(INT_MAX);
+  setOperationAction(ISD::BR_JT, MVT::Other, Expand);
+
   setOperationAction(ISD::BR_CC, GRLenVT, Expand);
   setOperationAction(ISD::SELECT_CC, GRLenVT, Expand);
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
diff --git a/llvm/test/CodeGen/LoongArch/jump-table.ll b/llvm/test/CodeGen/LoongArch/jump-table.ll
new file mode 100644 (file)
index 0000000..db0fb05
--- /dev/null
@@ -0,0 +1,93 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \
+; RUN:   | FileCheck %s --check-prefix=LA32
+; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \
+; RUN:   | FileCheck %s --check-prefix=LA64
+
+define void @switch_4_arms(i32 %in, ptr %out) nounwind {
+; LA32-LABEL: switch_4_arms:
+; LA32:       # %bb.0: # %entry
+; LA32-NEXT:    ori $a2, $zero, 2
+; LA32-NEXT:    blt $a2, $a0, .LBB0_4
+; LA32-NEXT:  # %bb.1: # %entry
+; LA32-NEXT:    ori $a3, $zero, 1
+; LA32-NEXT:    beq $a0, $a3, .LBB0_8
+; LA32-NEXT:  # %bb.2: # %entry
+; LA32-NEXT:    bne $a0, $a2, .LBB0_10
+; LA32-NEXT:  # %bb.3: # %bb2
+; LA32-NEXT:    ori $a0, $zero, 3
+; LA32-NEXT:    st.w $a0, $a1, 0
+; LA32-NEXT:    ret
+; LA32-NEXT:  .LBB0_4: # %entry
+; LA32-NEXT:    ori $a3, $zero, 3
+; LA32-NEXT:    beq $a0, $a3, .LBB0_9
+; LA32-NEXT:  # %bb.5: # %entry
+; LA32-NEXT:    ori $a2, $zero, 4
+; LA32-NEXT:    bne $a0, $a2, .LBB0_10
+; LA32-NEXT:  # %bb.6: # %bb4
+; LA32-NEXT:    ori $a0, $zero, 1
+; LA32-NEXT:    st.w $a0, $a1, 0
+; LA32-NEXT:    ret
+; LA32-NEXT:  .LBB0_8: # %bb1
+; LA32-NEXT:    ori $a0, $zero, 4
+; LA32-NEXT:    st.w $a0, $a1, 0
+; LA32-NEXT:    ret
+; LA32-NEXT:  .LBB0_9: # %bb3
+; LA32-NEXT:    st.w $a2, $a1, 0
+; LA32-NEXT:  .LBB0_10: # %exit
+; LA32-NEXT:    ret
+;
+; LA64-LABEL: switch_4_arms:
+; LA64:       # %bb.0: # %entry
+; LA64-NEXT:    bstrpick.d $a0, $a0, 31, 0
+; LA64-NEXT:    ori $a2, $zero, 2
+; LA64-NEXT:    blt $a2, $a0, .LBB0_4
+; LA64-NEXT:  # %bb.1: # %entry
+; LA64-NEXT:    ori $a3, $zero, 1
+; LA64-NEXT:    beq $a0, $a3, .LBB0_8
+; LA64-NEXT:  # %bb.2: # %entry
+; LA64-NEXT:    bne $a0, $a2, .LBB0_10
+; LA64-NEXT:  # %bb.3: # %bb2
+; LA64-NEXT:    ori $a0, $zero, 3
+; LA64-NEXT:    st.w $a0, $a1, 0
+; LA64-NEXT:    ret
+; LA64-NEXT:  .LBB0_4: # %entry
+; LA64-NEXT:    ori $a3, $zero, 3
+; LA64-NEXT:    beq $a0, $a3, .LBB0_9
+; LA64-NEXT:  # %bb.5: # %entry
+; LA64-NEXT:    ori $a2, $zero, 4
+; LA64-NEXT:    bne $a0, $a2, .LBB0_10
+; LA64-NEXT:  # %bb.6: # %bb4
+; LA64-NEXT:    ori $a0, $zero, 1
+; LA64-NEXT:    st.w $a0, $a1, 0
+; LA64-NEXT:    ret
+; LA64-NEXT:  .LBB0_8: # %bb1
+; LA64-NEXT:    ori $a0, $zero, 4
+; LA64-NEXT:    st.w $a0, $a1, 0
+; LA64-NEXT:    ret
+; LA64-NEXT:  .LBB0_9: # %bb3
+; LA64-NEXT:    st.w $a2, $a1, 0
+; LA64-NEXT:  .LBB0_10: # %exit
+; LA64-NEXT:    ret
+entry:
+  switch i32 %in, label %exit [
+    i32 1, label %bb1
+    i32 2, label %bb2
+    i32 3, label %bb3
+    i32 4, label %bb4
+  ]
+bb1:
+  store i32 4, ptr %out
+  br label %exit
+bb2:
+  store i32 3, ptr %out
+  br label %exit
+bb3:
+  store i32 2, ptr %out
+  br label %exit
+bb4:
+  store i32 1, ptr %out
+  br label %exit
+exit:
+  ret void
+}