From 0586f048d794673867f7307898114a111f6e80ba Mon Sep 17 00:00:00 2001 From: Nandor Licker Date: Wed, 25 Nov 2020 14:01:19 +0000 Subject: [PATCH] [RISCV] Basic jump table lowering This patch enables jump table lowering in the RISC-V backend. In addition to the test case included, the new lowering was tested by compiling the OCaml runtime and running it under qemu. Differential Revision: https://reviews.llvm.org/D92097 --- llvm/include/llvm/CodeGen/MachineInstrBuilder.h | 3 + llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 18 +- llvm/lib/Target/RISCV/RISCVISelLowering.h | 1 + llvm/lib/Target/RISCV/RISCVMCInstLower.cpp | 3 + llvm/test/CodeGen/RISCV/jumptable.ll | 349 +++++++++++++++++++++--- 5 files changed, 338 insertions(+), 36 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h index b31e9cd..115c501 100644 --- a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h @@ -305,6 +305,9 @@ public: case MachineOperand::MO_BlockAddress: return addBlockAddress(Disp.getBlockAddress(), Disp.getOffset() + off, TargetFlags); + case MachineOperand::MO_JumpTableIndex: + assert(off == 0 && "cannot create offset into jump tables"); + return addJumpTableIndex(Disp.getIndex(), TargetFlags); } } diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 5334666..22fe368 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -323,6 +323,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, setOperationAction(ISD::GlobalAddress, XLenVT, Custom); setOperationAction(ISD::BlockAddress, XLenVT, Custom); setOperationAction(ISD::ConstantPool, XLenVT, Custom); + setOperationAction(ISD::JumpTable, XLenVT, Custom); setOperationAction(ISD::GlobalTLSAddress, XLenVT, Custom); @@ -367,8 +368,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, setMinFunctionAlignment(FunctionAlignment); setPrefFunctionAlignment(FunctionAlignment); - // Effectively disable jump table generation. - setMinimumJumpTableEntries(INT_MAX); + setMinimumJumpTableEntries(5); // Jumps are expensive, compared to logic setJumpIsExpensive(); @@ -565,6 +565,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op, return lowerBlockAddress(Op, DAG); case ISD::ConstantPool: return lowerConstantPool(Op, DAG); + case ISD::JumpTable: + return lowerJumpTable(Op, DAG); case ISD::GlobalTLSAddress: return lowerGlobalTLSAddress(Op, DAG); case ISD::SELECT: @@ -643,6 +645,11 @@ static SDValue getTargetNode(ConstantPoolSDNode *N, SDLoc DL, EVT Ty, N->getOffset(), Flags); } +static SDValue getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty, + SelectionDAG &DAG, unsigned Flags) { + return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags); +} + template SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal) const { @@ -720,6 +727,13 @@ SDValue RISCVTargetLowering::lowerConstantPool(SDValue Op, return getAddr(N, DAG); } +SDValue RISCVTargetLowering::lowerJumpTable(SDValue Op, + SelectionDAG &DAG) const { + JumpTableSDNode *N = cast(Op); + + return getAddr(N, DAG); +} + SDValue RISCVTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, bool UseGOT) const { diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index 28ce459..dabf2b1 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -257,6 +257,7 @@ private: SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const; SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; diff --git a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp index 4fd060a..a93a1e3 100644 --- a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp +++ b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp @@ -122,6 +122,9 @@ bool llvm::LowerRISCVMachineOperandToMCOperand(const MachineOperand &MO, case MachineOperand::MO_ConstantPoolIndex: MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP); break; + case MachineOperand::MO_JumpTableIndex: + MCOp = lowerSymbolOperand(MO, AP.GetJTISymbol(MO.getIndex()), AP); + break; } return true; } diff --git a/llvm/test/CodeGen/RISCV/jumptable.ll b/llvm/test/CodeGen/RISCV/jumptable.ll index 5a5f5b6..0eebc69 100644 --- a/llvm/test/CodeGen/RISCV/jumptable.ll +++ b/llvm/test/CodeGen/RISCV/jumptable.ll @@ -1,39 +1,145 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ -; RUN: | FileCheck %s -check-prefix=RV32I +; RUN: llc -mtriple=riscv32 -code-model=small -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32I-SMALL +; RUN: llc -mtriple=riscv32 -code-model=medium -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32I-MEDIUM +; RUN: llc -mtriple=riscv64 -code-model=small -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64I-SMALL +; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64I-MEDIUM -define void @jt(i32 %in, i32* %out) nounwind { -; RV32I-LABEL: jt: -; RV32I: # %bb.0: # %entry -; RV32I-NEXT: addi a2, zero, 2 -; RV32I-NEXT: blt a2, a0, .LBB0_4 -; RV32I-NEXT: # %bb.1: # %entry -; RV32I-NEXT: addi a2, zero, 1 -; RV32I-NEXT: beq a0, a2, .LBB0_7 -; RV32I-NEXT: # %bb.2: # %entry -; RV32I-NEXT: addi a2, zero, 2 -; RV32I-NEXT: bne a0, a2, .LBB0_10 -; RV32I-NEXT: # %bb.3: # %bb2 -; RV32I-NEXT: addi a0, zero, 3 -; RV32I-NEXT: j .LBB0_9 -; RV32I-NEXT: .LBB0_4: # %entry -; RV32I-NEXT: addi a2, zero, 3 -; RV32I-NEXT: beq a0, a2, .LBB0_8 -; RV32I-NEXT: # %bb.5: # %entry -; RV32I-NEXT: addi a2, zero, 4 -; RV32I-NEXT: bne a0, a2, .LBB0_10 -; RV32I-NEXT: # %bb.6: # %bb4 -; RV32I-NEXT: addi a0, zero, 1 -; RV32I-NEXT: j .LBB0_9 -; RV32I-NEXT: .LBB0_7: # %bb1 -; RV32I-NEXT: addi a0, zero, 4 -; RV32I-NEXT: j .LBB0_9 -; RV32I-NEXT: .LBB0_8: # %bb3 -; RV32I-NEXT: addi a0, zero, 2 -; RV32I-NEXT: .LBB0_9: # %exit -; RV32I-NEXT: sw a0, 0(a1) -; RV32I-NEXT: .LBB0_10: # %exit -; RV32I-NEXT: ret +define void @below_threshold(i32 %in, i32* %out) nounwind { +; RV32I-SMALL-LABEL: below_threshold: +; RV32I-SMALL: # %bb.0: # %entry +; RV32I-SMALL-NEXT: addi a2, zero, 2 +; RV32I-SMALL-NEXT: blt a2, a0, .LBB0_4 +; RV32I-SMALL-NEXT: # %bb.1: # %entry +; RV32I-SMALL-NEXT: addi a2, zero, 1 +; RV32I-SMALL-NEXT: beq a0, a2, .LBB0_7 +; RV32I-SMALL-NEXT: # %bb.2: # %entry +; RV32I-SMALL-NEXT: addi a2, zero, 2 +; RV32I-SMALL-NEXT: bne a0, a2, .LBB0_10 +; RV32I-SMALL-NEXT: # %bb.3: # %bb2 +; RV32I-SMALL-NEXT: addi a0, zero, 3 +; RV32I-SMALL-NEXT: j .LBB0_9 +; RV32I-SMALL-NEXT: .LBB0_4: # %entry +; RV32I-SMALL-NEXT: addi a2, zero, 3 +; RV32I-SMALL-NEXT: beq a0, a2, .LBB0_8 +; RV32I-SMALL-NEXT: # %bb.5: # %entry +; RV32I-SMALL-NEXT: addi a2, zero, 4 +; RV32I-SMALL-NEXT: bne a0, a2, .LBB0_10 +; RV32I-SMALL-NEXT: # %bb.6: # %bb4 +; RV32I-SMALL-NEXT: addi a0, zero, 1 +; RV32I-SMALL-NEXT: j .LBB0_9 +; RV32I-SMALL-NEXT: .LBB0_7: # %bb1 +; RV32I-SMALL-NEXT: addi a0, zero, 4 +; RV32I-SMALL-NEXT: j .LBB0_9 +; RV32I-SMALL-NEXT: .LBB0_8: # %bb3 +; RV32I-SMALL-NEXT: addi a0, zero, 2 +; RV32I-SMALL-NEXT: .LBB0_9: # %exit +; RV32I-SMALL-NEXT: sw a0, 0(a1) +; RV32I-SMALL-NEXT: .LBB0_10: # %exit +; RV32I-SMALL-NEXT: ret +; +; RV32I-MEDIUM-LABEL: below_threshold: +; RV32I-MEDIUM: # %bb.0: # %entry +; RV32I-MEDIUM-NEXT: addi a2, zero, 2 +; RV32I-MEDIUM-NEXT: blt a2, a0, .LBB0_4 +; RV32I-MEDIUM-NEXT: # %bb.1: # %entry +; RV32I-MEDIUM-NEXT: addi a2, zero, 1 +; RV32I-MEDIUM-NEXT: beq a0, a2, .LBB0_7 +; RV32I-MEDIUM-NEXT: # %bb.2: # %entry +; RV32I-MEDIUM-NEXT: addi a2, zero, 2 +; RV32I-MEDIUM-NEXT: bne a0, a2, .LBB0_10 +; RV32I-MEDIUM-NEXT: # %bb.3: # %bb2 +; RV32I-MEDIUM-NEXT: addi a0, zero, 3 +; RV32I-MEDIUM-NEXT: j .LBB0_9 +; RV32I-MEDIUM-NEXT: .LBB0_4: # %entry +; RV32I-MEDIUM-NEXT: addi a2, zero, 3 +; RV32I-MEDIUM-NEXT: beq a0, a2, .LBB0_8 +; RV32I-MEDIUM-NEXT: # %bb.5: # %entry +; RV32I-MEDIUM-NEXT: addi a2, zero, 4 +; RV32I-MEDIUM-NEXT: bne a0, a2, .LBB0_10 +; RV32I-MEDIUM-NEXT: # %bb.6: # %bb4 +; RV32I-MEDIUM-NEXT: addi a0, zero, 1 +; RV32I-MEDIUM-NEXT: j .LBB0_9 +; RV32I-MEDIUM-NEXT: .LBB0_7: # %bb1 +; RV32I-MEDIUM-NEXT: addi a0, zero, 4 +; RV32I-MEDIUM-NEXT: j .LBB0_9 +; RV32I-MEDIUM-NEXT: .LBB0_8: # %bb3 +; RV32I-MEDIUM-NEXT: addi a0, zero, 2 +; RV32I-MEDIUM-NEXT: .LBB0_9: # %exit +; RV32I-MEDIUM-NEXT: sw a0, 0(a1) +; RV32I-MEDIUM-NEXT: .LBB0_10: # %exit +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-SMALL-LABEL: below_threshold: +; RV64I-SMALL: # %bb.0: # %entry +; RV64I-SMALL-NEXT: slli a0, a0, 32 +; RV64I-SMALL-NEXT: srli a0, a0, 32 +; RV64I-SMALL-NEXT: addi a2, zero, 2 +; RV64I-SMALL-NEXT: blt a2, a0, .LBB0_4 +; RV64I-SMALL-NEXT: # %bb.1: # %entry +; RV64I-SMALL-NEXT: addi a2, zero, 1 +; RV64I-SMALL-NEXT: beq a0, a2, .LBB0_7 +; RV64I-SMALL-NEXT: # %bb.2: # %entry +; RV64I-SMALL-NEXT: addi a2, zero, 2 +; RV64I-SMALL-NEXT: bne a0, a2, .LBB0_10 +; RV64I-SMALL-NEXT: # %bb.3: # %bb2 +; RV64I-SMALL-NEXT: addi a0, zero, 3 +; RV64I-SMALL-NEXT: j .LBB0_9 +; RV64I-SMALL-NEXT: .LBB0_4: # %entry +; RV64I-SMALL-NEXT: addi a2, zero, 3 +; RV64I-SMALL-NEXT: beq a0, a2, .LBB0_8 +; RV64I-SMALL-NEXT: # %bb.5: # %entry +; RV64I-SMALL-NEXT: addi a2, zero, 4 +; RV64I-SMALL-NEXT: bne a0, a2, .LBB0_10 +; RV64I-SMALL-NEXT: # %bb.6: # %bb4 +; RV64I-SMALL-NEXT: addi a0, zero, 1 +; RV64I-SMALL-NEXT: j .LBB0_9 +; RV64I-SMALL-NEXT: .LBB0_7: # %bb1 +; RV64I-SMALL-NEXT: addi a0, zero, 4 +; RV64I-SMALL-NEXT: j .LBB0_9 +; RV64I-SMALL-NEXT: .LBB0_8: # %bb3 +; RV64I-SMALL-NEXT: addi a0, zero, 2 +; RV64I-SMALL-NEXT: .LBB0_9: # %exit +; RV64I-SMALL-NEXT: sw a0, 0(a1) +; RV64I-SMALL-NEXT: .LBB0_10: # %exit +; RV64I-SMALL-NEXT: ret +; +; RV64I-MEDIUM-LABEL: below_threshold: +; RV64I-MEDIUM: # %bb.0: # %entry +; RV64I-MEDIUM-NEXT: slli a0, a0, 32 +; RV64I-MEDIUM-NEXT: srli a0, a0, 32 +; RV64I-MEDIUM-NEXT: addi a2, zero, 2 +; RV64I-MEDIUM-NEXT: blt a2, a0, .LBB0_4 +; RV64I-MEDIUM-NEXT: # %bb.1: # %entry +; RV64I-MEDIUM-NEXT: addi a2, zero, 1 +; RV64I-MEDIUM-NEXT: beq a0, a2, .LBB0_7 +; RV64I-MEDIUM-NEXT: # %bb.2: # %entry +; RV64I-MEDIUM-NEXT: addi a2, zero, 2 +; RV64I-MEDIUM-NEXT: bne a0, a2, .LBB0_10 +; RV64I-MEDIUM-NEXT: # %bb.3: # %bb2 +; RV64I-MEDIUM-NEXT: addi a0, zero, 3 +; RV64I-MEDIUM-NEXT: j .LBB0_9 +; RV64I-MEDIUM-NEXT: .LBB0_4: # %entry +; RV64I-MEDIUM-NEXT: addi a2, zero, 3 +; RV64I-MEDIUM-NEXT: beq a0, a2, .LBB0_8 +; RV64I-MEDIUM-NEXT: # %bb.5: # %entry +; RV64I-MEDIUM-NEXT: addi a2, zero, 4 +; RV64I-MEDIUM-NEXT: bne a0, a2, .LBB0_10 +; RV64I-MEDIUM-NEXT: # %bb.6: # %bb4 +; RV64I-MEDIUM-NEXT: addi a0, zero, 1 +; RV64I-MEDIUM-NEXT: j .LBB0_9 +; RV64I-MEDIUM-NEXT: .LBB0_7: # %bb1 +; RV64I-MEDIUM-NEXT: addi a0, zero, 4 +; RV64I-MEDIUM-NEXT: j .LBB0_9 +; RV64I-MEDIUM-NEXT: .LBB0_8: # %bb3 +; RV64I-MEDIUM-NEXT: addi a0, zero, 2 +; RV64I-MEDIUM-NEXT: .LBB0_9: # %exit +; RV64I-MEDIUM-NEXT: sw a0, 0(a1) +; RV64I-MEDIUM-NEXT: .LBB0_10: # %exit +; RV64I-MEDIUM-NEXT: ret entry: switch i32 %in, label %exit [ i32 1, label %bb1 @@ -56,3 +162,178 @@ bb4: exit: ret void } + +define void @above_threshold(i32 %in, i32* %out) nounwind { +; RV32I-SMALL-LABEL: above_threshold: +; RV32I-SMALL: # %bb.0: # %entry +; RV32I-SMALL-NEXT: addi a0, a0, -1 +; RV32I-SMALL-NEXT: addi a2, zero, 5 +; RV32I-SMALL-NEXT: bltu a2, a0, .LBB1_9 +; RV32I-SMALL-NEXT: # %bb.1: # %entry +; RV32I-SMALL-NEXT: slli a0, a0, 2 +; RV32I-SMALL-NEXT: lui a2, %hi(.LJTI1_0) +; RV32I-SMALL-NEXT: addi a2, a2, %lo(.LJTI1_0) +; RV32I-SMALL-NEXT: add a0, a0, a2 +; RV32I-SMALL-NEXT: lw a0, 0(a0) +; RV32I-SMALL-NEXT: jr a0 +; RV32I-SMALL-NEXT: .LBB1_2: # %bb1 +; RV32I-SMALL-NEXT: addi a0, zero, 4 +; RV32I-SMALL-NEXT: j .LBB1_8 +; RV32I-SMALL-NEXT: .LBB1_3: # %bb2 +; RV32I-SMALL-NEXT: addi a0, zero, 3 +; RV32I-SMALL-NEXT: j .LBB1_8 +; RV32I-SMALL-NEXT: .LBB1_4: # %bb3 +; RV32I-SMALL-NEXT: addi a0, zero, 2 +; RV32I-SMALL-NEXT: j .LBB1_8 +; RV32I-SMALL-NEXT: .LBB1_5: # %bb4 +; RV32I-SMALL-NEXT: addi a0, zero, 1 +; RV32I-SMALL-NEXT: j .LBB1_8 +; RV32I-SMALL-NEXT: .LBB1_6: # %bb5 +; RV32I-SMALL-NEXT: addi a0, zero, 100 +; RV32I-SMALL-NEXT: j .LBB1_8 +; RV32I-SMALL-NEXT: .LBB1_7: # %bb6 +; RV32I-SMALL-NEXT: addi a0, zero, 200 +; RV32I-SMALL-NEXT: .LBB1_8: # %exit +; RV32I-SMALL-NEXT: sw a0, 0(a1) +; RV32I-SMALL-NEXT: .LBB1_9: # %exit +; RV32I-SMALL-NEXT: ret +; +; RV32I-MEDIUM-LABEL: above_threshold: +; RV32I-MEDIUM: # %bb.0: # %entry +; RV32I-MEDIUM-NEXT: addi a0, a0, -1 +; RV32I-MEDIUM-NEXT: addi a2, zero, 5 +; RV32I-MEDIUM-NEXT: bltu a2, a0, .LBB1_9 +; RV32I-MEDIUM-NEXT: # %bb.1: # %entry +; RV32I-MEDIUM-NEXT: slli a0, a0, 2 +; RV32I-MEDIUM-NEXT: .LBB1_10: # %entry +; RV32I-MEDIUM-NEXT: # Label of block must be emitted +; RV32I-MEDIUM-NEXT: auipc a2, %pcrel_hi(.LJTI1_0) +; RV32I-MEDIUM-NEXT: addi a2, a2, %pcrel_lo(.LBB1_10) +; RV32I-MEDIUM-NEXT: add a0, a0, a2 +; RV32I-MEDIUM-NEXT: lw a0, 0(a0) +; RV32I-MEDIUM-NEXT: jr a0 +; RV32I-MEDIUM-NEXT: .LBB1_2: # %bb1 +; RV32I-MEDIUM-NEXT: addi a0, zero, 4 +; RV32I-MEDIUM-NEXT: j .LBB1_8 +; RV32I-MEDIUM-NEXT: .LBB1_3: # %bb2 +; RV32I-MEDIUM-NEXT: addi a0, zero, 3 +; RV32I-MEDIUM-NEXT: j .LBB1_8 +; RV32I-MEDIUM-NEXT: .LBB1_4: # %bb3 +; RV32I-MEDIUM-NEXT: addi a0, zero, 2 +; RV32I-MEDIUM-NEXT: j .LBB1_8 +; RV32I-MEDIUM-NEXT: .LBB1_5: # %bb4 +; RV32I-MEDIUM-NEXT: addi a0, zero, 1 +; RV32I-MEDIUM-NEXT: j .LBB1_8 +; RV32I-MEDIUM-NEXT: .LBB1_6: # %bb5 +; RV32I-MEDIUM-NEXT: addi a0, zero, 100 +; RV32I-MEDIUM-NEXT: j .LBB1_8 +; RV32I-MEDIUM-NEXT: .LBB1_7: # %bb6 +; RV32I-MEDIUM-NEXT: addi a0, zero, 200 +; RV32I-MEDIUM-NEXT: .LBB1_8: # %exit +; RV32I-MEDIUM-NEXT: sw a0, 0(a1) +; RV32I-MEDIUM-NEXT: .LBB1_9: # %exit +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-SMALL-LABEL: above_threshold: +; RV64I-SMALL: # %bb.0: # %entry +; RV64I-SMALL-NEXT: slli a0, a0, 32 +; RV64I-SMALL-NEXT: srli a0, a0, 32 +; RV64I-SMALL-NEXT: addi a0, a0, -1 +; RV64I-SMALL-NEXT: addi a2, zero, 5 +; RV64I-SMALL-NEXT: bltu a2, a0, .LBB1_9 +; RV64I-SMALL-NEXT: # %bb.1: # %entry +; RV64I-SMALL-NEXT: slli a0, a0, 3 +; RV64I-SMALL-NEXT: lui a2, %hi(.LJTI1_0) +; RV64I-SMALL-NEXT: addi a2, a2, %lo(.LJTI1_0) +; RV64I-SMALL-NEXT: add a0, a0, a2 +; RV64I-SMALL-NEXT: ld a0, 0(a0) +; RV64I-SMALL-NEXT: jr a0 +; RV64I-SMALL-NEXT: .LBB1_2: # %bb1 +; RV64I-SMALL-NEXT: addi a0, zero, 4 +; RV64I-SMALL-NEXT: j .LBB1_8 +; RV64I-SMALL-NEXT: .LBB1_3: # %bb2 +; RV64I-SMALL-NEXT: addi a0, zero, 3 +; RV64I-SMALL-NEXT: j .LBB1_8 +; RV64I-SMALL-NEXT: .LBB1_4: # %bb3 +; RV64I-SMALL-NEXT: addi a0, zero, 2 +; RV64I-SMALL-NEXT: j .LBB1_8 +; RV64I-SMALL-NEXT: .LBB1_5: # %bb4 +; RV64I-SMALL-NEXT: addi a0, zero, 1 +; RV64I-SMALL-NEXT: j .LBB1_8 +; RV64I-SMALL-NEXT: .LBB1_6: # %bb5 +; RV64I-SMALL-NEXT: addi a0, zero, 100 +; RV64I-SMALL-NEXT: j .LBB1_8 +; RV64I-SMALL-NEXT: .LBB1_7: # %bb6 +; RV64I-SMALL-NEXT: addi a0, zero, 200 +; RV64I-SMALL-NEXT: .LBB1_8: # %exit +; RV64I-SMALL-NEXT: sw a0, 0(a1) +; RV64I-SMALL-NEXT: .LBB1_9: # %exit +; RV64I-SMALL-NEXT: ret +; +; RV64I-MEDIUM-LABEL: above_threshold: +; RV64I-MEDIUM: # %bb.0: # %entry +; RV64I-MEDIUM-NEXT: slli a0, a0, 32 +; RV64I-MEDIUM-NEXT: srli a0, a0, 32 +; RV64I-MEDIUM-NEXT: addi a0, a0, -1 +; RV64I-MEDIUM-NEXT: addi a2, zero, 5 +; RV64I-MEDIUM-NEXT: bltu a2, a0, .LBB1_9 +; RV64I-MEDIUM-NEXT: # %bb.1: # %entry +; RV64I-MEDIUM-NEXT: slli a0, a0, 3 +; RV64I-MEDIUM-NEXT: .LBB1_10: # %entry +; RV64I-MEDIUM-NEXT: # Label of block must be emitted +; RV64I-MEDIUM-NEXT: auipc a2, %pcrel_hi(.LJTI1_0) +; RV64I-MEDIUM-NEXT: addi a2, a2, %pcrel_lo(.LBB1_10) +; RV64I-MEDIUM-NEXT: add a0, a0, a2 +; RV64I-MEDIUM-NEXT: ld a0, 0(a0) +; RV64I-MEDIUM-NEXT: jr a0 +; RV64I-MEDIUM-NEXT: .LBB1_2: # %bb1 +; RV64I-MEDIUM-NEXT: addi a0, zero, 4 +; RV64I-MEDIUM-NEXT: j .LBB1_8 +; RV64I-MEDIUM-NEXT: .LBB1_3: # %bb2 +; RV64I-MEDIUM-NEXT: addi a0, zero, 3 +; RV64I-MEDIUM-NEXT: j .LBB1_8 +; RV64I-MEDIUM-NEXT: .LBB1_4: # %bb3 +; RV64I-MEDIUM-NEXT: addi a0, zero, 2 +; RV64I-MEDIUM-NEXT: j .LBB1_8 +; RV64I-MEDIUM-NEXT: .LBB1_5: # %bb4 +; RV64I-MEDIUM-NEXT: addi a0, zero, 1 +; RV64I-MEDIUM-NEXT: j .LBB1_8 +; RV64I-MEDIUM-NEXT: .LBB1_6: # %bb5 +; RV64I-MEDIUM-NEXT: addi a0, zero, 100 +; RV64I-MEDIUM-NEXT: j .LBB1_8 +; RV64I-MEDIUM-NEXT: .LBB1_7: # %bb6 +; RV64I-MEDIUM-NEXT: addi a0, zero, 200 +; RV64I-MEDIUM-NEXT: .LBB1_8: # %exit +; RV64I-MEDIUM-NEXT: sw a0, 0(a1) +; RV64I-MEDIUM-NEXT: .LBB1_9: # %exit +; RV64I-MEDIUM-NEXT: ret +entry: + switch i32 %in, label %exit [ + i32 1, label %bb1 + i32 2, label %bb2 + i32 3, label %bb3 + i32 4, label %bb4 + i32 5, label %bb5 + i32 6, label %bb6 + ] +bb1: + store i32 4, i32* %out + br label %exit +bb2: + store i32 3, i32* %out + br label %exit +bb3: + store i32 2, i32* %out + br label %exit +bb4: + store i32 1, i32* %out + br label %exit +bb5: + store i32 100, i32* %out + br label %exit +bb6: + store i32 200, i32* %out + br label %exit +exit: + ret void +} -- 2.7.4