diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp index 24a13f93af880..e4be90afc4c6e 100644 --- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp @@ -134,6 +134,9 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB, case RISCV::PseudoCCSLLIW: case RISCV::PseudoCCSRLIW: case RISCV::PseudoCCSRAIW: + case RISCV::PseudoCCANDN: + case RISCV::PseudoCCORN: + case RISCV::PseudoCCXNOR: return expandCCOp(MBB, MBBI, NextMBBI); case RISCV::PseudoVSETVLI: case RISCV::PseudoVSETVLIX0: @@ -225,6 +228,9 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB, case RISCV::PseudoCCSLLIW: NewOpc = RISCV::SLLIW; break; case RISCV::PseudoCCSRLIW: NewOpc = RISCV::SRLIW; break; case RISCV::PseudoCCSRAIW: NewOpc = RISCV::SRAIW; break; + case RISCV::PseudoCCANDN: NewOpc = RISCV::ANDN; break; + case RISCV::PseudoCCORN: NewOpc = RISCV::ORN; break; + case RISCV::PseudoCCXNOR: NewOpc = RISCV::XNOR; break; } 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 cd98438eed882..8fa23c6175f5b 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1346,6 +1346,10 @@ unsigned getPredicatedOpcode(unsigned Opcode) { case RISCV::SLLIW: return RISCV::PseudoCCSLLIW; break; case RISCV::SRLIW: return RISCV::PseudoCCSRLIW; break; case RISCV::SRAIW: return RISCV::PseudoCCSRAIW; break; + + case RISCV::ANDN: return RISCV::PseudoCCANDN; break; + case RISCV::ORN: return RISCV::PseudoCCORN; break; + case RISCV::XNOR: return RISCV::PseudoCCXNOR; break; } return RISCV::INSTRUCTION_LIST_END; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 35e8edf5d2fa7..463f42b861fde 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1517,6 +1517,23 @@ def PseudoCCSRAIW : Pseudo<(outs GPR:$dst), GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]>; + +// Zbb/Zbkb instructions +def PseudoCCANDN : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, + GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, + Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, + ReadSFBALU, ReadSFBALU, ReadSFBALU]>; +def PseudoCCORN : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, + GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, + Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, + ReadSFBALU, ReadSFBALU, ReadSFBALU]>; +def PseudoCCXNOR : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, + GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, + Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, + ReadSFBALU, ReadSFBALU, ReadSFBALU]>; } multiclass SelectCC_GPR_rrirr { diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll index 725b8fd6eeea6..02dd94df68bf0 100644 --- a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll +++ b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll @@ -1,11 +1,11 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=riscv64 -mattr=+c -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mattr=+c,+zbb -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefix=NOSFB %s -; RUN: llc -mtriple=riscv64 -mcpu=sifive-u74 -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mcpu=sifive-u74 -mattr=+zbb -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=SFB,NOZICOND,RV64SFB %s -; RUN: llc -mtriple=riscv64 -mcpu=sifive-u74 -mattr=+experimental-zicond \ +; RUN: llc -mtriple=riscv64 -mcpu=sifive-u74 -mattr=+experimental-zicond,+zbb \ ; RUN: -verify-machineinstrs < %s | FileCheck -check-prefixes=SFB,ZICOND %s -; RUN: llc -mtriple=riscv32 -mcpu=sifive-e76 -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv32 -mcpu=sifive-e76 -mattr=+zbb -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=SFB,NOZICOND,RV32SFB %s ; The sifive-7-series can predicate a mv. @@ -1462,9 +1462,8 @@ entry: define signext i32 @abs_i32(i32 signext %x) { ; NOSFB-LABEL: abs_i32: ; NOSFB: # %bb.0: -; NOSFB-NEXT: sraiw a1, a0, 31 -; NOSFB-NEXT: xor a0, a0, a1 -; NOSFB-NEXT: subw a0, a0, a1 +; NOSFB-NEXT: negw a1, a0 +; NOSFB-NEXT: max a0, a0, a1 ; NOSFB-NEXT: ret ; ; RV64SFB-LABEL: abs_i32: @@ -1498,9 +1497,8 @@ declare i32 @llvm.abs.i32(i32, i1) define i64 @abs_i64(i64 %x) { ; NOSFB-LABEL: abs_i64: ; NOSFB: # %bb.0: -; NOSFB-NEXT: srai a1, a0, 63 -; NOSFB-NEXT: xor a0, a0, a1 -; NOSFB-NEXT: sub a0, a0, a1 +; NOSFB-NEXT: neg a1, a0 +; NOSFB-NEXT: max a0, a0, a1 ; NOSFB-NEXT: ret ; ; RV64SFB-LABEL: abs_i64: @@ -1536,3 +1534,147 @@ define i64 @abs_i64(i64 %x) { ret i64 %a } declare i64 @llvm.abs.i64(i64, i1) + +define i64 @select_andn(i64 %A, i64 %B, i64 %C, i1 zeroext %cond) { +; NOSFB-LABEL: select_andn: +; NOSFB: # %bb.0: # %entry +; NOSFB-NEXT: bnez a3, .LBB36_2 +; NOSFB-NEXT: # %bb.1: # %entry +; NOSFB-NEXT: andn a2, a0, a1 +; NOSFB-NEXT: .LBB36_2: # %entry +; NOSFB-NEXT: mv a0, a2 +; NOSFB-NEXT: ret +; +; RV64SFB-LABEL: select_andn: +; RV64SFB: # %bb.0: # %entry +; RV64SFB-NEXT: bnez a3, .LBB36_2 +; RV64SFB-NEXT: # %bb.1: # %entry +; RV64SFB-NEXT: andn a2, a0, a1 +; RV64SFB-NEXT: .LBB36_2: # %entry +; RV64SFB-NEXT: mv a0, a2 +; RV64SFB-NEXT: ret +; +; ZICOND-LABEL: select_andn: +; ZICOND: # %bb.0: # %entry +; ZICOND-NEXT: bnez a3, .LBB36_2 +; ZICOND-NEXT: # %bb.1: # %entry +; ZICOND-NEXT: andn a2, a0, a1 +; ZICOND-NEXT: .LBB36_2: # %entry +; ZICOND-NEXT: mv a0, a2 +; ZICOND-NEXT: ret +; +; RV32SFB-LABEL: select_andn: +; RV32SFB: # %bb.0: # %entry +; RV32SFB-NEXT: bnez a6, .LBB36_2 +; RV32SFB-NEXT: # %bb.1: # %entry +; RV32SFB-NEXT: andn a4, a0, a2 +; RV32SFB-NEXT: .LBB36_2: # %entry +; RV32SFB-NEXT: bnez a6, .LBB36_4 +; RV32SFB-NEXT: # %bb.3: # %entry +; RV32SFB-NEXT: andn a5, a1, a3 +; RV32SFB-NEXT: .LBB36_4: # %entry +; RV32SFB-NEXT: mv a0, a4 +; RV32SFB-NEXT: mv a1, a5 +; RV32SFB-NEXT: ret +entry: + %0 = xor i64 %B, -1 + %1 = and i64 %A, %0 + %2 = select i1 %cond, i64 %C, i64 %1 + ret i64 %2 +} + +define i64 @select_orn(i64 %A, i64 %B, i64 %C, i1 zeroext %cond) { +; NOSFB-LABEL: select_orn: +; NOSFB: # %bb.0: # %entry +; NOSFB-NEXT: bnez a3, .LBB37_2 +; NOSFB-NEXT: # %bb.1: # %entry +; NOSFB-NEXT: orn a2, a0, a1 +; NOSFB-NEXT: .LBB37_2: # %entry +; NOSFB-NEXT: mv a0, a2 +; NOSFB-NEXT: ret +; +; RV64SFB-LABEL: select_orn: +; RV64SFB: # %bb.0: # %entry +; RV64SFB-NEXT: bnez a3, .LBB37_2 +; RV64SFB-NEXT: # %bb.1: # %entry +; RV64SFB-NEXT: orn a2, a0, a1 +; RV64SFB-NEXT: .LBB37_2: # %entry +; RV64SFB-NEXT: mv a0, a2 +; RV64SFB-NEXT: ret +; +; ZICOND-LABEL: select_orn: +; ZICOND: # %bb.0: # %entry +; ZICOND-NEXT: bnez a3, .LBB37_2 +; ZICOND-NEXT: # %bb.1: # %entry +; ZICOND-NEXT: orn a2, a0, a1 +; ZICOND-NEXT: .LBB37_2: # %entry +; ZICOND-NEXT: mv a0, a2 +; ZICOND-NEXT: ret +; +; RV32SFB-LABEL: select_orn: +; RV32SFB: # %bb.0: # %entry +; RV32SFB-NEXT: bnez a6, .LBB37_2 +; RV32SFB-NEXT: # %bb.1: # %entry +; RV32SFB-NEXT: orn a4, a0, a2 +; RV32SFB-NEXT: .LBB37_2: # %entry +; RV32SFB-NEXT: bnez a6, .LBB37_4 +; RV32SFB-NEXT: # %bb.3: # %entry +; RV32SFB-NEXT: orn a5, a1, a3 +; RV32SFB-NEXT: .LBB37_4: # %entry +; RV32SFB-NEXT: mv a0, a4 +; RV32SFB-NEXT: mv a1, a5 +; RV32SFB-NEXT: ret +entry: + %0 = xor i64 %B, -1 + %1 = or i64 %A, %0 + %2 = select i1 %cond, i64 %C, i64 %1 + ret i64 %2 +} + +define i64 @select_xnor(i64 %A, i64 %B, i64 %C, i1 zeroext %cond) { +; NOSFB-LABEL: select_xnor: +; NOSFB: # %bb.0: # %entry +; NOSFB-NEXT: bnez a3, .LBB38_2 +; NOSFB-NEXT: # %bb.1: # %entry +; NOSFB-NEXT: xnor a2, a0, a1 +; NOSFB-NEXT: .LBB38_2: # %entry +; NOSFB-NEXT: mv a0, a2 +; NOSFB-NEXT: ret +; +; RV64SFB-LABEL: select_xnor: +; RV64SFB: # %bb.0: # %entry +; RV64SFB-NEXT: bnez a3, .LBB38_2 +; RV64SFB-NEXT: # %bb.1: # %entry +; RV64SFB-NEXT: xnor a2, a0, a1 +; RV64SFB-NEXT: .LBB38_2: # %entry +; RV64SFB-NEXT: mv a0, a2 +; RV64SFB-NEXT: ret +; +; ZICOND-LABEL: select_xnor: +; ZICOND: # %bb.0: # %entry +; ZICOND-NEXT: bnez a3, .LBB38_2 +; ZICOND-NEXT: # %bb.1: # %entry +; ZICOND-NEXT: xnor a2, a0, a1 +; ZICOND-NEXT: .LBB38_2: # %entry +; ZICOND-NEXT: mv a0, a2 +; ZICOND-NEXT: ret +; +; RV32SFB-LABEL: select_xnor: +; RV32SFB: # %bb.0: # %entry +; RV32SFB-NEXT: bnez a6, .LBB38_2 +; RV32SFB-NEXT: # %bb.1: # %entry +; RV32SFB-NEXT: xnor a4, a0, a2 +; RV32SFB-NEXT: .LBB38_2: # %entry +; RV32SFB-NEXT: bnez a6, .LBB38_4 +; RV32SFB-NEXT: # %bb.3: # %entry +; RV32SFB-NEXT: xnor a5, a1, a3 +; RV32SFB-NEXT: .LBB38_4: # %entry +; RV32SFB-NEXT: mv a0, a4 +; RV32SFB-NEXT: mv a1, a5 +; RV32SFB-NEXT: ret +entry: + %0 = xor i64 %A, %B + %1 = xor i64 %0, -1 + %2 = select i1 %cond, i64 %C, i64 %1 + ret i64 %2 +}