Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/Support/FormatVariadic.h"

#define GET_GICOMBINER_DEPS
#include "RISCVGenPostLegalizeGICombiner.inc"
Expand All @@ -42,6 +43,56 @@ namespace {
#include "RISCVGenPostLegalizeGICombiner.inc"
#undef GET_GICOMBINER_TYPES

/// Match: G_STORE (G_FCONSTANT +0.0), addr
/// Return the source vreg in MatchInfo if matched.
bool matchFoldFPZeroStore(MachineInstr &MI, MachineRegisterInfo &MRI,
const RISCVSubtarget &STI, Register &MatchInfo) {
if (MI.getOpcode() != TargetOpcode::G_STORE)
return false;

Register SrcReg = MI.getOperand(0).getReg();
if (!SrcReg.isVirtual())
return false;

MachineInstr *Def = MRI.getVRegDef(SrcReg);
if (!Def || Def->getOpcode() != TargetOpcode::G_FCONSTANT)
return false;

auto *CFP = Def->getOperand(1).getFPImm();
if (!CFP || !CFP->getValueAPF().isPosZero())
return false;

unsigned ValBits = MRI.getType(SrcReg).getSizeInBits();
if ((ValBits == 16 && !STI.hasStdExtZfh()) ||
(ValBits == 32 && !STI.hasStdExtF()) ||
(ValBits == 64 && (!STI.hasStdExtD() || !STI.is64Bit())))
return false;

MatchInfo = SrcReg;
return true;
}

/// Apply: rewrite to G_STORE (G_CONSTANT 0 [XLEN]), addr
void applyFoldFPZeroStore(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &B, const RISCVSubtarget &STI,
Register &MatchInfo) {
const unsigned XLen = STI.getXLen();

auto Zero = B.buildConstant(LLT::scalar(XLen), 0);
MI.getOperand(0).setReg(Zero.getReg(0));

MachineInstr *Def = MRI.getVRegDef(MatchInfo);
if (Def && MRI.use_nodbg_empty(MatchInfo))
Def->eraseFromParent();

#ifndef NDEBUG
unsigned ValBits = MRI.getType(MatchInfo).getSizeInBits();
LLVM_DEBUG(dbgs() << formatv("[{0}] Fold FP zero store -> int zero "
"(XLEN={1}, ValBits={2}):\n {3}\n",
DEBUG_TYPE, XLen, ValBits, MI));
#endif
}

class RISCVPostLegalizerCombinerImpl : public Combiner {
protected:
const CombinerHelper Helper;
Expand Down
11 changes: 10 additions & 1 deletion llvm/lib/Target/RISCV/RISCVCombine.td
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,20 @@ def RISCVO0PreLegalizerCombiner: GICombiner<
"RISCVO0PreLegalizerCombinerImpl", [optnone_combines]> {
}

// Rule: fold store (fp +0.0) -> store (int zero [XLEN])
def fp_zero_store_matchdata : GIDefMatchData<"Register">;
def fold_fp_zero_store : GICombineRule<
(defs root:$root, fp_zero_store_matchdata:$matchinfo),
(match (G_STORE $src, $addr):$root,
[{ return matchFoldFPZeroStore(*${root}, MRI, STI, ${matchinfo}); }]),
(apply [{ applyFoldFPZeroStore(*${root}, MRI, B, STI, ${matchinfo}); }])>;

// Post-legalization combines which are primarily optimizations.
// TODO: Add more combines.
def RISCVPostLegalizerCombiner
: GICombiner<"RISCVPostLegalizerCombinerImpl",
[sub_to_add, combines_for_extload, redundant_and,
identity_combines, shift_immed_chain,
commute_constant_to_rhs, simplify_neg_minmax]> {
commute_constant_to_rhs, simplify_neg_minmax,
fold_fp_zero_store]> {
}
Loading