From c262c4a6d4d99a3dba84e22b0bbdecda368becc6 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Fri, 5 Jan 2024 17:42:14 +0800 Subject: [PATCH 1/4] [RISCV] Pre-commit testcase --- .../CodeGen/RISCV/short-forward-branch-opt.ll | 162 ++++++++++++++++-- 1 file changed, 152 insertions(+), 10 deletions(-) diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll index 725b8fd6eeea6..8f5186561715e 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: andn a0, a0, a1 +; RV64SFB-NEXT: beqz a3, .LBB36_2 +; RV64SFB-NEXT: # %bb.1: # %entry +; RV64SFB-NEXT: mv a0, a2 +; RV64SFB-NEXT: .LBB36_2: # %entry +; RV64SFB-NEXT: ret +; +; ZICOND-LABEL: select_andn: +; ZICOND: # %bb.0: # %entry +; ZICOND-NEXT: andn a0, a0, a1 +; ZICOND-NEXT: beqz a3, .LBB36_2 +; ZICOND-NEXT: # %bb.1: # %entry +; ZICOND-NEXT: mv a0, a2 +; ZICOND-NEXT: .LBB36_2: # %entry +; ZICOND-NEXT: ret +; +; RV32SFB-LABEL: select_andn: +; RV32SFB: # %bb.0: # %entry +; RV32SFB-NEXT: andn a0, a0, a2 +; RV32SFB-NEXT: andn a1, a1, a3 +; RV32SFB-NEXT: beqz a6, .LBB36_2 +; RV32SFB-NEXT: # %bb.1: # %entry +; RV32SFB-NEXT: mv a0, a4 +; RV32SFB-NEXT: .LBB36_2: # %entry +; RV32SFB-NEXT: beqz a6, .LBB36_4 +; RV32SFB-NEXT: # %bb.3: # %entry +; RV32SFB-NEXT: mv a1, a5 +; RV32SFB-NEXT: .LBB36_4: # %entry +; 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: orn a0, a0, a1 +; RV64SFB-NEXT: beqz a3, .LBB37_2 +; RV64SFB-NEXT: # %bb.1: # %entry +; RV64SFB-NEXT: mv a0, a2 +; RV64SFB-NEXT: .LBB37_2: # %entry +; RV64SFB-NEXT: ret +; +; ZICOND-LABEL: select_orn: +; ZICOND: # %bb.0: # %entry +; ZICOND-NEXT: orn a0, a0, a1 +; ZICOND-NEXT: beqz a3, .LBB37_2 +; ZICOND-NEXT: # %bb.1: # %entry +; ZICOND-NEXT: mv a0, a2 +; ZICOND-NEXT: .LBB37_2: # %entry +; ZICOND-NEXT: ret +; +; RV32SFB-LABEL: select_orn: +; RV32SFB: # %bb.0: # %entry +; RV32SFB-NEXT: orn a0, a0, a2 +; RV32SFB-NEXT: orn a1, a1, a3 +; RV32SFB-NEXT: beqz a6, .LBB37_2 +; RV32SFB-NEXT: # %bb.1: # %entry +; RV32SFB-NEXT: mv a0, a4 +; RV32SFB-NEXT: .LBB37_2: # %entry +; RV32SFB-NEXT: beqz a6, .LBB37_4 +; RV32SFB-NEXT: # %bb.3: # %entry +; RV32SFB-NEXT: mv a1, a5 +; RV32SFB-NEXT: .LBB37_4: # %entry +; 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: xnor a0, a0, a1 +; RV64SFB-NEXT: beqz a3, .LBB38_2 +; RV64SFB-NEXT: # %bb.1: # %entry +; RV64SFB-NEXT: mv a0, a2 +; RV64SFB-NEXT: .LBB38_2: # %entry +; RV64SFB-NEXT: ret +; +; ZICOND-LABEL: select_xnor: +; ZICOND: # %bb.0: # %entry +; ZICOND-NEXT: xnor a0, a0, a1 +; ZICOND-NEXT: beqz a3, .LBB38_2 +; ZICOND-NEXT: # %bb.1: # %entry +; ZICOND-NEXT: mv a0, a2 +; ZICOND-NEXT: .LBB38_2: # %entry +; ZICOND-NEXT: ret +; +; RV32SFB-LABEL: select_xnor: +; RV32SFB: # %bb.0: # %entry +; RV32SFB-NEXT: xnor a0, a0, a2 +; RV32SFB-NEXT: xnor a1, a1, a3 +; RV32SFB-NEXT: beqz a6, .LBB38_2 +; RV32SFB-NEXT: # %bb.1: # %entry +; RV32SFB-NEXT: mv a0, a4 +; RV32SFB-NEXT: .LBB38_2: # %entry +; RV32SFB-NEXT: beqz a6, .LBB38_4 +; RV32SFB-NEXT: # %bb.3: # %entry +; RV32SFB-NEXT: mv a1, a5 +; RV32SFB-NEXT: .LBB38_4: # %entry +; 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 +} From 131f462064ba088e23cee62b05f191486681f973 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Fri, 5 Jan 2024 17:49:58 +0800 Subject: [PATCH 2/4] [RISCV] Add support predicating for ANDN/ORN/XNOR with short-forward-branch-opt. ANDN/ORN/XNOR are like other ALU instructions. It should be able to be predicated by the cpu that supports short-forward-branch. --- .../Target/RISCV/RISCVExpandPseudoInsts.cpp | 6 ++ llvm/lib/Target/RISCV/RISCVFeatures.td | 3 +- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 15 +++- llvm/lib/Target/RISCV/RISCVInstrInfo.td | 17 +++++ llvm/lib/Target/RISCV/RISCVSubtarget.h | 1 + .../CodeGen/RISCV/short-forward-branch-opt.ll | 72 +++++++++---------- 6 files changed, 73 insertions(+), 41 deletions(-) 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/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 59b202606dada..0121a073e6e1c 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -216,8 +216,7 @@ def HasStdExtZbkx : Predicate<"Subtarget->hasStdExtZbkx()">, AssemblerPredicate<(all_of FeatureStdExtZbkx), "'Zbkx' (Crossbar permutation instructions)">; -def HasStdExtZbbOrZbkb - : Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbkb()">, +def HasStdExtZbbOrZbkb : Predicate<"Subtarget->hasStdExtZbbOrZbkb()">, AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtZbkb), "'Zbb' (Basic Bit-Manipulation) or " "'Zbkb' (Bitmanip instructions for Cryptography)">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index cd98438eed882..d25b6534e4721 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1317,7 +1317,7 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp, // If the operation has a predicated pseudo instruction, return the pseudo // instruction opcode. Otherwise, return RISCV::INSTRUCTION_LIST_END. // TODO: Support more operations. -unsigned getPredicatedOpcode(unsigned Opcode) { +unsigned getPredicatedOpcode(const RISCVSubtarget &STI, unsigned Opcode) { switch (Opcode) { case RISCV::ADD: return RISCV::PseudoCCADD; break; case RISCV::SUB: return RISCV::PseudoCCSUB; break; @@ -1348,6 +1348,14 @@ unsigned getPredicatedOpcode(unsigned Opcode) { case RISCV::SRAIW: return RISCV::PseudoCCSRAIW; break; } + if (STI.hasStdExtZbbOrZbkb()) { + switch (Opcode) { + 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; } @@ -1364,7 +1372,8 @@ static MachineInstr *canFoldAsPredicatedOp(Register Reg, if (!MI) return nullptr; // Check if MI can be predicated and folded into the CCMOV. - if (getPredicatedOpcode(MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END) + if (getPredicatedOpcode(MI->getMF()->getSubtarget(), + MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END) return nullptr; // Don't predicate li idiom. if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() && @@ -1440,7 +1449,7 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI, if (!MRI.constrainRegClass(DestReg, PreviousClass)) return nullptr; - unsigned PredOpc = getPredicatedOpcode(DefMI->getOpcode()); + unsigned PredOpc = getPredicatedOpcode(STI, DefMI->getOpcode()); assert(PredOpc != RISCV::INSTRUCTION_LIST_END && "Unexpected opcode!"); // Create a new predicated version of DefMI. 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/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h index 26320b05d9be2..2aab3b715a4eb 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -150,6 +150,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { bool hasHalfFPLoadStoreMove() const { return HasStdExtZfhmin || HasStdExtZfbfmin; } + bool hasStdExtZbbOrZbkb() const { return HasStdExtZbb || HasStdExtZbkb; } bool is64Bit() const { return IsRV64; } MVT getXLenVT() const { return is64Bit() ? MVT::i64 : MVT::i32; diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll index 8f5186561715e..02dd94df68bf0 100644 --- a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll +++ b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll @@ -1547,34 +1547,34 @@ define i64 @select_andn(i64 %A, i64 %B, i64 %C, i1 zeroext %cond) { ; ; RV64SFB-LABEL: select_andn: ; RV64SFB: # %bb.0: # %entry -; RV64SFB-NEXT: andn a0, a0, a1 -; RV64SFB-NEXT: beqz a3, .LBB36_2 +; RV64SFB-NEXT: bnez a3, .LBB36_2 ; RV64SFB-NEXT: # %bb.1: # %entry -; RV64SFB-NEXT: mv a0, a2 +; 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: andn a0, a0, a1 -; ZICOND-NEXT: beqz a3, .LBB36_2 +; ZICOND-NEXT: bnez a3, .LBB36_2 ; ZICOND-NEXT: # %bb.1: # %entry -; ZICOND-NEXT: mv a0, a2 +; 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: andn a0, a0, a2 -; RV32SFB-NEXT: andn a1, a1, a3 -; RV32SFB-NEXT: beqz a6, .LBB36_2 +; RV32SFB-NEXT: bnez a6, .LBB36_2 ; RV32SFB-NEXT: # %bb.1: # %entry -; RV32SFB-NEXT: mv a0, a4 +; RV32SFB-NEXT: andn a4, a0, a2 ; RV32SFB-NEXT: .LBB36_2: # %entry -; RV32SFB-NEXT: beqz a6, .LBB36_4 +; RV32SFB-NEXT: bnez a6, .LBB36_4 ; RV32SFB-NEXT: # %bb.3: # %entry -; RV32SFB-NEXT: mv a1, a5 +; 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 @@ -1595,34 +1595,34 @@ define i64 @select_orn(i64 %A, i64 %B, i64 %C, i1 zeroext %cond) { ; ; RV64SFB-LABEL: select_orn: ; RV64SFB: # %bb.0: # %entry -; RV64SFB-NEXT: orn a0, a0, a1 -; RV64SFB-NEXT: beqz a3, .LBB37_2 +; RV64SFB-NEXT: bnez a3, .LBB37_2 ; RV64SFB-NEXT: # %bb.1: # %entry -; RV64SFB-NEXT: mv a0, a2 +; 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: orn a0, a0, a1 -; ZICOND-NEXT: beqz a3, .LBB37_2 +; ZICOND-NEXT: bnez a3, .LBB37_2 ; ZICOND-NEXT: # %bb.1: # %entry -; ZICOND-NEXT: mv a0, a2 +; 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: orn a0, a0, a2 -; RV32SFB-NEXT: orn a1, a1, a3 -; RV32SFB-NEXT: beqz a6, .LBB37_2 +; RV32SFB-NEXT: bnez a6, .LBB37_2 ; RV32SFB-NEXT: # %bb.1: # %entry -; RV32SFB-NEXT: mv a0, a4 +; RV32SFB-NEXT: orn a4, a0, a2 ; RV32SFB-NEXT: .LBB37_2: # %entry -; RV32SFB-NEXT: beqz a6, .LBB37_4 +; RV32SFB-NEXT: bnez a6, .LBB37_4 ; RV32SFB-NEXT: # %bb.3: # %entry -; RV32SFB-NEXT: mv a1, a5 +; 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 @@ -1643,34 +1643,34 @@ define i64 @select_xnor(i64 %A, i64 %B, i64 %C, i1 zeroext %cond) { ; ; RV64SFB-LABEL: select_xnor: ; RV64SFB: # %bb.0: # %entry -; RV64SFB-NEXT: xnor a0, a0, a1 -; RV64SFB-NEXT: beqz a3, .LBB38_2 +; RV64SFB-NEXT: bnez a3, .LBB38_2 ; RV64SFB-NEXT: # %bb.1: # %entry -; RV64SFB-NEXT: mv a0, a2 +; 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: xnor a0, a0, a1 -; ZICOND-NEXT: beqz a3, .LBB38_2 +; ZICOND-NEXT: bnez a3, .LBB38_2 ; ZICOND-NEXT: # %bb.1: # %entry -; ZICOND-NEXT: mv a0, a2 +; 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: xnor a0, a0, a2 -; RV32SFB-NEXT: xnor a1, a1, a3 -; RV32SFB-NEXT: beqz a6, .LBB38_2 +; RV32SFB-NEXT: bnez a6, .LBB38_2 ; RV32SFB-NEXT: # %bb.1: # %entry -; RV32SFB-NEXT: mv a0, a4 +; RV32SFB-NEXT: xnor a4, a0, a2 ; RV32SFB-NEXT: .LBB38_2: # %entry -; RV32SFB-NEXT: beqz a6, .LBB38_4 +; RV32SFB-NEXT: bnez a6, .LBB38_4 ; RV32SFB-NEXT: # %bb.3: # %entry -; RV32SFB-NEXT: mv a1, a5 +; 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 From 061224cc551c0a5f15e228cc6e86ae22162ad045 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Mon, 8 Jan 2024 09:14:37 +0800 Subject: [PATCH 3/4] Remove constraint STI.hasStdExtZbbOrZbkb() --- llvm/lib/Target/RISCV/RISCVFeatures.td | 3 ++- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 17 ++++++----------- llvm/lib/Target/RISCV/RISCVSubtarget.h | 1 - 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 0121a073e6e1c..59b202606dada 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -216,7 +216,8 @@ def HasStdExtZbkx : Predicate<"Subtarget->hasStdExtZbkx()">, AssemblerPredicate<(all_of FeatureStdExtZbkx), "'Zbkx' (Crossbar permutation instructions)">; -def HasStdExtZbbOrZbkb : Predicate<"Subtarget->hasStdExtZbbOrZbkb()">, +def HasStdExtZbbOrZbkb + : Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbkb()">, AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtZbkb), "'Zbb' (Basic Bit-Manipulation) or " "'Zbkb' (Bitmanip instructions for Cryptography)">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index d25b6534e4721..7676b49346912 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1317,7 +1317,7 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp, // If the operation has a predicated pseudo instruction, return the pseudo // instruction opcode. Otherwise, return RISCV::INSTRUCTION_LIST_END. // TODO: Support more operations. -unsigned getPredicatedOpcode(const RISCVSubtarget &STI, unsigned Opcode) { +unsigned getPredicatedOpcode(unsigned Opcode) { switch (Opcode) { case RISCV::ADD: return RISCV::PseudoCCADD; break; case RISCV::SUB: return RISCV::PseudoCCSUB; break; @@ -1346,14 +1346,10 @@ unsigned getPredicatedOpcode(const RISCVSubtarget &STI, unsigned Opcode) { case RISCV::SLLIW: return RISCV::PseudoCCSLLIW; break; case RISCV::SRLIW: return RISCV::PseudoCCSRLIW; break; case RISCV::SRAIW: return RISCV::PseudoCCSRAIW; break; - } - if (STI.hasStdExtZbbOrZbkb()) { - switch (Opcode) { - case RISCV::ANDN: return RISCV::PseudoCCANDN; break; - case RISCV::ORN: return RISCV::PseudoCCORN; break; - case RISCV::XNOR: return RISCV::PseudoCCXNOR; 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; @@ -1372,8 +1368,7 @@ static MachineInstr *canFoldAsPredicatedOp(Register Reg, if (!MI) return nullptr; // Check if MI can be predicated and folded into the CCMOV. - if (getPredicatedOpcode(MI->getMF()->getSubtarget(), - MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END) + if (getPredicatedOpcode(MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END) return nullptr; // Don't predicate li idiom. if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() && @@ -1449,7 +1444,7 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI, if (!MRI.constrainRegClass(DestReg, PreviousClass)) return nullptr; - unsigned PredOpc = getPredicatedOpcode(STI, DefMI->getOpcode()); + unsigned PredOpc = getPredicatedOpcode(DefMI->getOpcode()); assert(PredOpc != RISCV::INSTRUCTION_LIST_END && "Unexpected opcode!"); // Create a new predicated version of DefMI. diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h index 2aab3b715a4eb..26320b05d9be2 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -150,7 +150,6 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { bool hasHalfFPLoadStoreMove() const { return HasStdExtZfhmin || HasStdExtZfbfmin; } - bool hasStdExtZbbOrZbkb() const { return HasStdExtZbb || HasStdExtZbkb; } bool is64Bit() const { return IsRV64; } MVT getXLenVT() const { return is64Bit() ? MVT::i64 : MVT::i32; From 2ccd1baf41f5173bba2216b20db77845ba2e20df Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Tue, 9 Jan 2024 09:09:04 +0800 Subject: [PATCH 4/4] Adjust format --- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 7676b49346912..8fa23c6175f5b 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1347,9 +1347,9 @@ unsigned getPredicatedOpcode(unsigned Opcode) { 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; + 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;