diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 3c72269d1e00c..e15225eb0ba11 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -550,6 +550,10 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) { MI.eraseFromParent(); return true; } + case TargetOpcode::G_BRINDIRECT: + MI.setDesc(TII.get(RISCV::PseudoBRIND)); + MI.addOperand(MachineOperand::CreateImm(0)); + return constrainSelectedInstRegOperands(MI, TII, TRI, RBI); case TargetOpcode::G_SEXT_INREG: return selectSExtInreg(MI, MIB); case TargetOpcode::G_FRAME_INDEX: { diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 9eb5812e024b9..b1567db6ab615 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -159,6 +159,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) { getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}}); + getActionDefinitionsBuilder(G_BRINDIRECT).legalFor({p0}); + getActionDefinitionsBuilder(G_PHI) .legalFor({p0, sXLen}) .widenScalarToNextPow2(0) diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/brindirect-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/brindirect-rv32.mir new file mode 100644 index 0000000000000..79b9a352a8ead --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/brindirect-rv32.mir @@ -0,0 +1,45 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=riscv32 -run-pass=instruction-select -simplify-mir \ +# RUN: -verify-machineinstrs %s -o - | FileCheck -check-prefix=RV32I %s + +--- +name: indirectbr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + ; RV32I-LABEL: name: indirectbr + ; RV32I: bb.0: + ; RV32I-NEXT: successors: %bb.1, %bb.2 + ; RV32I-NEXT: liveins: $x10 + ; RV32I-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprjalr = COPY $x10 + ; RV32I-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 1 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0 + ; RV32I-NEXT: PseudoBRIND [[COPY]], 0 + ; RV32I-NEXT: {{ $}} + ; RV32I-NEXT: bb.1: + ; RV32I-NEXT: $x10 = COPY [[COPY1]] + ; RV32I-NEXT: PseudoRET implicit $x10 + ; RV32I-NEXT: {{ $}} + ; RV32I-NEXT: bb.2: + ; RV32I-NEXT: $x10 = COPY [[ADDI]] + ; RV32I-NEXT: PseudoRET implicit $x10 + bb.1: + successors: %bb.2, %bb.3 + liveins: $x10 + + %0:gprb(p0) = COPY $x10 + %1:gprb(s32) = G_CONSTANT i32 1 + %2:gprb(s32) = G_CONSTANT i32 0 + G_BRINDIRECT %0(p0) + + bb.2: + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + + bb.3: + $x10 = COPY %1(s32) + PseudoRET implicit $x10 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/brindirect-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/brindirect-rv64.mir new file mode 100644 index 0000000000000..eb1bf20b82cd2 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/brindirect-rv64.mir @@ -0,0 +1,45 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -simplify-mir \ +# RUN: -verify-machineinstrs %s -o - | FileCheck -check-prefix=RV64I %s + +--- +name: indirectbr +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + ; RV64I-LABEL: name: indirectbr + ; RV64I: bb.0: + ; RV64I-NEXT: successors: %bb.1, %bb.2 + ; RV64I-NEXT: liveins: $x10 + ; RV64I-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gprjalr = COPY $x10 + ; RV64I-NEXT: PseudoBRIND [[COPY]], 0 + ; RV64I-NEXT: {{ $}} + ; RV64I-NEXT: bb.1: + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0 + ; RV64I-NEXT: $x10 = COPY [[COPY1]] + ; RV64I-NEXT: PseudoRET implicit $x10 + ; RV64I-NEXT: {{ $}} + ; RV64I-NEXT: bb.2: + ; RV64I-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 1 + ; RV64I-NEXT: $x10 = COPY [[ADDI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + bb.1: + successors: %bb.2, %bb.3 + liveins: $x10 + + %0:gprb(p0) = COPY $x10 + G_BRINDIRECT %0(p0) + + bb.2: + %4:gprb(s64) = G_CONSTANT i64 0 + $x10 = COPY %4(s64) + PseudoRET implicit $x10 + + bb.3: + %2:gprb(s64) = G_CONSTANT i64 1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-brindirect-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-brindirect-rv32.mir new file mode 100644 index 0000000000000..271989eac18a1 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-brindirect-rv32.mir @@ -0,0 +1,42 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - \ +# RUN: | FileCheck %s + +--- +name: indirectbr +body: | + ; CHECK-LABEL: name: indirectbr + ; CHECK: bb.0: + ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; CHECK-NEXT: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 + ; CHECK-NEXT: G_BRINDIRECT [[COPY]](p0) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.1: + ; CHECK-NEXT: $x10 = COPY [[C1]](s32) + ; CHECK-NEXT: PseudoRET implicit $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2: + ; CHECK-NEXT: $x10 = COPY [[C]](s32) + ; CHECK-NEXT: PseudoRET implicit $x10 + bb.1: + successors: %bb.2, %bb.3 + liveins: $x10 + + %0:_(p0) = COPY $x10 + %1:_(s32) = G_CONSTANT i32 1 + %2:_(s32) = G_CONSTANT i32 0 + G_BRINDIRECT %0(p0) + + bb.2: + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + + bb.3: + $x10 = COPY %1(s32) + PseudoRET implicit $x10 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-brindirect-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-brindirect-rv64.mir new file mode 100644 index 0000000000000..e997323046bc2 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-brindirect-rv64.mir @@ -0,0 +1,42 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=riscv64 -run-pass=legalizer %s -o - \ +# RUN: | FileCheck %s + +--- +name: indirectbr +body: | + ; CHECK-LABEL: name: indirectbr + ; CHECK: bb.0: + ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; CHECK-NEXT: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; CHECK-NEXT: G_BRINDIRECT [[COPY]](p0) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.1: + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 + ; CHECK-NEXT: $x10 = COPY [[C]](s64) + ; CHECK-NEXT: PseudoRET implicit $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2: + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 + ; CHECK-NEXT: $x10 = COPY [[C1]](s64) + ; CHECK-NEXT: PseudoRET implicit $x10 + bb.1: + successors: %bb.2, %bb.3 + liveins: $x10 + + %0:_(p0) = COPY $x10 + G_BRINDIRECT %0(p0) + + bb.2: + %4:_(s64) = G_CONSTANT i64 0 + $x10 = COPY %4(s64) + PseudoRET implicit $x10 + + bb.3: + %2:_(s64) = G_CONSTANT i64 1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +...