diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp index b0453fc57c053..60e0afdd99912 100644 --- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp @@ -132,6 +132,9 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB, case RISCV::PseudoCCMIN: case RISCV::PseudoCCMINU: case RISCV::PseudoCCMUL: + case RISCV::PseudoCCLUI: + case RISCV::PseudoCCQC_LI: + case RISCV::PseudoCCQC_E_LI: case RISCV::PseudoCCADDW: case RISCV::PseudoCCSUBW: case RISCV::PseudoCCSLL: @@ -239,6 +242,9 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB, case RISCV::PseudoCCMAXU: NewOpc = RISCV::MAXU; break; case RISCV::PseudoCCMINU: NewOpc = RISCV::MINU; break; case RISCV::PseudoCCMUL: NewOpc = RISCV::MUL; break; + case RISCV::PseudoCCLUI: NewOpc = RISCV::LUI; break; + case RISCV::PseudoCCQC_LI: NewOpc = RISCV::QC_LI; break; + case RISCV::PseudoCCQC_E_LI: NewOpc = RISCV::QC_E_LI; break; case RISCV::PseudoCCADDI: NewOpc = RISCV::ADDI; break; case RISCV::PseudoCCSLLI: NewOpc = RISCV::SLLI; break; case RISCV::PseudoCCSRLI: NewOpc = RISCV::SRLI; break; @@ -268,6 +274,9 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB, .add(MI.getOperand(5)) .add(MI.getOperand(6)) .add(MI.getOperand(7)); + } else if (NewOpc == RISCV::LUI || NewOpc == RISCV::QC_LI || + NewOpc == RISCV::QC_E_LI) { + BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg).add(MI.getOperand(5)); } else { BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg) .add(MI.getOperand(5)) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index b8ab70bd9e386..b1c73438fe984 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1704,6 +1704,9 @@ unsigned getPredicatedOpcode(unsigned Opcode) { case RISCV::MIN: return RISCV::PseudoCCMIN; case RISCV::MINU: return RISCV::PseudoCCMINU; case RISCV::MUL: return RISCV::PseudoCCMUL; + case RISCV::LUI: return RISCV::PseudoCCLUI; + case RISCV::QC_LI: return RISCV::PseudoCCQC_LI; + case RISCV::QC_E_LI: return RISCV::PseudoCCQC_E_LI; case RISCV::ADDI: return RISCV::PseudoCCADDI; case RISCV::SLLI: return RISCV::PseudoCCSLLI; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td index 494b1c9f98839..5b1c13493bbf2 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td @@ -69,6 +69,17 @@ class SFBALU_ri let Constraints = "$dst = $falsev"; } +class SFBLUI + : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, + uimm20_lui:$imm), []> { + let hasSideEffects = 0; + let mayLoad = 0; + let mayStore = 0; + let Size = 8; + let Constraints = "$dst = $falsev"; +} + class SFBShift_ri : Pseudo<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1, @@ -117,6 +128,8 @@ def PseudoCCANDI : SFBALU_ri; def PseudoCCORI : SFBALU_ri; def PseudoCCXORI : SFBALU_ri; +def PseudoCCLUI : SFBLUI; + def PseudoCCSLLI : SFBShift_ri; def PseudoCCSRLI : SFBShift_ri; def PseudoCCSRAI : SFBShift_ri; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 8376da52be53e..8a38fe2f5ae16 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -817,6 +817,28 @@ class QCIRVInst48EJ func2, string opcodestr> let Inst{6-0} = 0b0011111; } +class SFBQC_LI + : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, + simm20_li:$imm), []> { + let hasSideEffects = 0; + let mayLoad = 0; + let mayStore = 0; + let Size = 8; + let Constraints = "$dst = $falsev"; +} + +class SFBQC_E_LI + : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, + bare_simm32:$imm), []> { + let hasSideEffects = 0; + let mayLoad = 0; + let mayStore = 0; + let Size = 10; + let Constraints = "$dst = $falsev"; +} + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -1308,6 +1330,11 @@ def PseudoQC_E_SH : PseudoStore<"qc.e.sh">; def PseudoQC_E_SW : PseudoStore<"qc.e.sw">; } // Predicates = [HasVendorXqcilo, IsRV32] +let Predicates = [HasShortForwardBranchOpt] in { +def PseudoCCQC_LI : SFBQC_LI; +def PseudoCCQC_E_LI : SFBQC_E_LI; +} + //===----------------------------------------------------------------------===// // Code Gen Patterns //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/RISCV/select-const.ll b/llvm/test/CodeGen/RISCV/select-const.ll index dfac6e1630d25..f2924bb364adb 100644 --- a/llvm/test/CodeGen/RISCV/select-const.ll +++ b/llvm/test/CodeGen/RISCV/select-const.ll @@ -177,9 +177,11 @@ define float @select_const_fp(i1 zeroext %a) nounwind { ; ; RV32IXQCI-LABEL: select_const_fp: ; RV32IXQCI: # %bb.0: -; RV32IXQCI-NEXT: lui a2, 263168 ; RV32IXQCI-NEXT: lui a1, 264192 -; RV32IXQCI-NEXT: qc.mvnei a1, a0, 0, a2 +; RV32IXQCI-NEXT: beqz a0, .LBB4_2 +; RV32IXQCI-NEXT: # %bb.1: +; RV32IXQCI-NEXT: lui a1, 263168 +; RV32IXQCI-NEXT: .LBB4_2: ; RV32IXQCI-NEXT: mv a0, a1 ; RV32IXQCI-NEXT: ret ; @@ -653,9 +655,11 @@ define i32 @select_nonnegative_lui_addi(i32 signext %x) { ; ; RV32IXQCI-LABEL: select_nonnegative_lui_addi: ; RV32IXQCI: # %bb.0: -; RV32IXQCI-NEXT: lui a2, 4 ; RV32IXQCI-NEXT: li a1, 25 -; RV32IXQCI-NEXT: qc.mvgei a1, a0, 0, a2 +; RV32IXQCI-NEXT: bltz a0, .LBB21_2 +; RV32IXQCI-NEXT: # %bb.1: +; RV32IXQCI-NEXT: lui a1, 4 +; RV32IXQCI-NEXT: .LBB21_2: ; RV32IXQCI-NEXT: mv a0, a1 ; RV32IXQCI-NEXT: ret ; @@ -724,9 +728,11 @@ define i32 @select_nonnegative_lui_addi_swapped(i32 signext %x) { ; ; RV32IXQCI-LABEL: select_nonnegative_lui_addi_swapped: ; RV32IXQCI: # %bb.0: -; RV32IXQCI-NEXT: li a2, 25 +; RV32IXQCI-NEXT: li a1, 25 +; RV32IXQCI-NEXT: bgez a0, .LBB22_2 +; RV32IXQCI-NEXT: # %bb.1: ; RV32IXQCI-NEXT: lui a1, 4 -; RV32IXQCI-NEXT: qc.mvgei a1, a0, 0, a2 +; RV32IXQCI-NEXT: .LBB22_2: ; RV32IXQCI-NEXT: mv a0, a1 ; RV32IXQCI-NEXT: ret ; diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-load-imm.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-load-imm.ll new file mode 100644 index 0000000000000..6aae6cd0e82ee --- /dev/null +++ b/llvm/test/CodeGen/RISCV/short-forward-branch-load-imm.ll @@ -0,0 +1,139 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -verify-machineinstrs -mtriple=riscv32 -mattr=+experimental-xqcili | FileCheck %s --check-prefixes=RV32I +; RUN: llc < %s -verify-machineinstrs -mtriple=riscv64 | FileCheck %s --check-prefixes=RV64I +; RUN: llc < %s -verify-machineinstrs -mtriple=riscv32 -mattr=+experimental-xqcili,+short-forward-branch-opt | \ +; RUN: FileCheck %s --check-prefixes=RV32I-SFB +; RUN: llc < %s -verify-machineinstrs -mtriple=riscv64 -mattr=+short-forward-branch-opt | \ +; RUN: FileCheck %s --check-prefixes=RV64I-SFB + +define i32 @select_example_1(i32 %a, i32 %b, i1 zeroext %x, i32 %y) { +; RV32I-LABEL: select_example_1: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, 16 +; RV32I-NEXT: bnez a2, .LBB0_2 +; RV32I-NEXT: # %bb.1: # %entry +; RV32I-NEXT: mv a0, a1 +; RV32I-NEXT: .LBB0_2: # %entry +; RV32I-NEXT: ret +; +; RV64I-LABEL: select_example_1: +; RV64I: # %bb.0: # %entry +; RV64I-NEXT: lui a0, 16 +; RV64I-NEXT: bnez a2, .LBB0_2 +; RV64I-NEXT: # %bb.1: # %entry +; RV64I-NEXT: mv a0, a1 +; RV64I-NEXT: .LBB0_2: # %entry +; RV64I-NEXT: ret +; +; RV32I-SFB-LABEL: select_example_1: +; RV32I-SFB: # %bb.0: # %entry +; RV32I-SFB-NEXT: mv a0, a1 +; RV32I-SFB-NEXT: beqz a2, .LBB0_2 +; RV32I-SFB-NEXT: # %bb.1: # %entry +; RV32I-SFB-NEXT: lui a0, 16 +; RV32I-SFB-NEXT: .LBB0_2: # %entry +; RV32I-SFB-NEXT: ret +; +; RV64I-SFB-LABEL: select_example_1: +; RV64I-SFB: # %bb.0: # %entry +; RV64I-SFB-NEXT: mv a0, a1 +; RV64I-SFB-NEXT: beqz a2, .LBB0_2 +; RV64I-SFB-NEXT: # %bb.1: # %entry +; RV64I-SFB-NEXT: lui a0, 16 +; RV64I-SFB-NEXT: .LBB0_2: # %entry +; RV64I-SFB-NEXT: ret +entry: + %sel = select i1 %x, i32 65536, i32 %b + ret i32 %sel +} + +define i32 @select_example_2(i32 %a, i32 %b, i1 zeroext %x, i32 %y) { +; RV32I-LABEL: select_example_2: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: bnez a2, .LBB1_2 +; RV32I-NEXT: # %bb.1: # %entry +; RV32I-NEXT: mv a0, a1 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB1_2: +; RV32I-NEXT: qc.li a0, 65543 +; RV32I-NEXT: ret +; +; RV64I-LABEL: select_example_2: +; RV64I: # %bb.0: # %entry +; RV64I-NEXT: bnez a2, .LBB1_2 +; RV64I-NEXT: # %bb.1: # %entry +; RV64I-NEXT: mv a0, a1 +; RV64I-NEXT: ret +; RV64I-NEXT: .LBB1_2: +; RV64I-NEXT: lui a0, 16 +; RV64I-NEXT: addi a0, a0, 7 +; RV64I-NEXT: ret +; +; RV32I-SFB-LABEL: select_example_2: +; RV32I-SFB: # %bb.0: # %entry +; RV32I-SFB-NEXT: mv a0, a1 +; RV32I-SFB-NEXT: beqz a2, .LBB1_2 +; RV32I-SFB-NEXT: # %bb.1: # %entry +; RV32I-SFB-NEXT: qc.li a0, 65543 +; RV32I-SFB-NEXT: .LBB1_2: # %entry +; RV32I-SFB-NEXT: ret +; +; RV64I-SFB-LABEL: select_example_2: +; RV64I-SFB: # %bb.0: # %entry +; RV64I-SFB-NEXT: mv a0, a1 +; RV64I-SFB-NEXT: lui a1, 16 +; RV64I-SFB-NEXT: beqz a2, .LBB1_2 +; RV64I-SFB-NEXT: # %bb.1: # %entry +; RV64I-SFB-NEXT: addi a0, a1, 7 +; RV64I-SFB-NEXT: .LBB1_2: # %entry +; RV64I-SFB-NEXT: ret +entry: + %sel = select i1 %x, i32 65543, i32 %b + ret i32 %sel +} + +define i32 @select_example_3(i32 %a, i32 %b, i1 zeroext %x, i32 %y) { +; RV32I-LABEL: select_example_3: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: bnez a2, .LBB2_2 +; RV32I-NEXT: # %bb.1: # %entry +; RV32I-NEXT: mv a0, a1 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB2_2: +; RV32I-NEXT: qc.e.li a0, 4198928 +; RV32I-NEXT: ret +; +; RV64I-LABEL: select_example_3: +; RV64I: # %bb.0: # %entry +; RV64I-NEXT: bnez a2, .LBB2_2 +; RV64I-NEXT: # %bb.1: # %entry +; RV64I-NEXT: mv a0, a1 +; RV64I-NEXT: ret +; RV64I-NEXT: .LBB2_2: +; RV64I-NEXT: lui a0, 1025 +; RV64I-NEXT: addi a0, a0, 528 +; RV64I-NEXT: ret +; +; RV32I-SFB-LABEL: select_example_3: +; RV32I-SFB: # %bb.0: # %entry +; RV32I-SFB-NEXT: mv a0, a1 +; RV32I-SFB-NEXT: beqz a2, .LBB2_2 +; RV32I-SFB-NEXT: # %bb.1: # %entry +; RV32I-SFB-NEXT: qc.e.li a0, 4198928 +; RV32I-SFB-NEXT: .LBB2_2: # %entry +; RV32I-SFB-NEXT: ret +; +; RV64I-SFB-LABEL: select_example_3: +; RV64I-SFB: # %bb.0: # %entry +; RV64I-SFB-NEXT: mv a0, a1 +; RV64I-SFB-NEXT: lui a1, 1025 +; RV64I-SFB-NEXT: beqz a2, .LBB2_2 +; RV64I-SFB-NEXT: # %bb.1: # %entry +; RV64I-SFB-NEXT: addi a0, a1, 528 +; RV64I-SFB-NEXT: .LBB2_2: # %entry +; RV64I-SFB-NEXT: ret +entry: + %sel = select i1 %x, i32 4198928, i32 %b + ret i32 %sel +} +