Skip to content

Commit

Permalink
[RISCV] Add support predicating for ANDN/ORN/XNOR with short-forward-…
Browse files Browse the repository at this point in the history
…branch-opt. (llvm#77077)

ANDN/ORN/XNOR are like other ALU instructions. It should be able to be
predicated by the cpu that supports short-forward-branch.
  • Loading branch information
tclin914 authored Jan 9, 2024
1 parent af1fdcc commit 96c4f10
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 10 deletions.
6 changes: 6 additions & 0 deletions llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,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:
Expand Down Expand Up @@ -227,6 +230,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))
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,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<DAGOperand valty, ValueType vt> {
Expand Down
162 changes: 152 additions & 10 deletions llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
}

0 comments on commit 96c4f10

Please sign in to comment.