Skip to content

Commit 961c564

Browse files
sunshaoceLukacma
authored andcommitted
[RISCV][GISel] Fold G_FCONSTANT 0.0 store into G_CONSTANT x0 (llvm#163008)
1 parent 5c93184 commit 961c564

File tree

3 files changed

+381
-1
lines changed

3 files changed

+381
-1
lines changed

llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerCombiner.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/CodeGen/MachineDominators.h"
2828
#include "llvm/CodeGen/MachineFunctionPass.h"
2929
#include "llvm/CodeGen/TargetPassConfig.h"
30+
#include "llvm/Support/FormatVariadic.h"
3031

3132
#define GET_GICOMBINER_DEPS
3233
#include "RISCVGenPostLegalizeGICombiner.inc"
@@ -42,6 +43,56 @@ namespace {
4243
#include "RISCVGenPostLegalizeGICombiner.inc"
4344
#undef GET_GICOMBINER_TYPES
4445

46+
/// Match: G_STORE (G_FCONSTANT +0.0), addr
47+
/// Return the source vreg in MatchInfo if matched.
48+
bool matchFoldFPZeroStore(MachineInstr &MI, MachineRegisterInfo &MRI,
49+
const RISCVSubtarget &STI, Register &MatchInfo) {
50+
if (MI.getOpcode() != TargetOpcode::G_STORE)
51+
return false;
52+
53+
Register SrcReg = MI.getOperand(0).getReg();
54+
if (!SrcReg.isVirtual())
55+
return false;
56+
57+
MachineInstr *Def = MRI.getVRegDef(SrcReg);
58+
if (!Def || Def->getOpcode() != TargetOpcode::G_FCONSTANT)
59+
return false;
60+
61+
auto *CFP = Def->getOperand(1).getFPImm();
62+
if (!CFP || !CFP->getValueAPF().isPosZero())
63+
return false;
64+
65+
unsigned ValBits = MRI.getType(SrcReg).getSizeInBits();
66+
if ((ValBits == 16 && !STI.hasStdExtZfh()) ||
67+
(ValBits == 32 && !STI.hasStdExtF()) ||
68+
(ValBits == 64 && (!STI.hasStdExtD() || !STI.is64Bit())))
69+
return false;
70+
71+
MatchInfo = SrcReg;
72+
return true;
73+
}
74+
75+
/// Apply: rewrite to G_STORE (G_CONSTANT 0 [XLEN]), addr
76+
void applyFoldFPZeroStore(MachineInstr &MI, MachineRegisterInfo &MRI,
77+
MachineIRBuilder &B, const RISCVSubtarget &STI,
78+
Register &MatchInfo) {
79+
const unsigned XLen = STI.getXLen();
80+
81+
auto Zero = B.buildConstant(LLT::scalar(XLen), 0);
82+
MI.getOperand(0).setReg(Zero.getReg(0));
83+
84+
MachineInstr *Def = MRI.getVRegDef(MatchInfo);
85+
if (Def && MRI.use_nodbg_empty(MatchInfo))
86+
Def->eraseFromParent();
87+
88+
#ifndef NDEBUG
89+
unsigned ValBits = MRI.getType(MatchInfo).getSizeInBits();
90+
LLVM_DEBUG(dbgs() << formatv("[{0}] Fold FP zero store -> int zero "
91+
"(XLEN={1}, ValBits={2}):\n {3}\n",
92+
DEBUG_TYPE, XLen, ValBits, MI));
93+
#endif
94+
}
95+
4596
class RISCVPostLegalizerCombinerImpl : public Combiner {
4697
protected:
4798
const CombinerHelper Helper;

llvm/lib/Target/RISCV/RISCVCombine.td

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,20 @@ def RISCVO0PreLegalizerCombiner: GICombiner<
1919
"RISCVO0PreLegalizerCombinerImpl", [optnone_combines]> {
2020
}
2121

22+
// Rule: fold store (fp +0.0) -> store (int zero [XLEN])
23+
def fp_zero_store_matchdata : GIDefMatchData<"Register">;
24+
def fold_fp_zero_store : GICombineRule<
25+
(defs root:$root, fp_zero_store_matchdata:$matchinfo),
26+
(match (G_STORE $src, $addr):$root,
27+
[{ return matchFoldFPZeroStore(*${root}, MRI, STI, ${matchinfo}); }]),
28+
(apply [{ applyFoldFPZeroStore(*${root}, MRI, B, STI, ${matchinfo}); }])>;
29+
2230
// Post-legalization combines which are primarily optimizations.
2331
// TODO: Add more combines.
2432
def RISCVPostLegalizerCombiner
2533
: GICombiner<"RISCVPostLegalizerCombinerImpl",
2634
[sub_to_add, combines_for_extload, redundant_and,
2735
identity_combines, shift_immed_chain,
28-
commute_constant_to_rhs, simplify_neg_minmax]> {
36+
commute_constant_to_rhs, simplify_neg_minmax,
37+
fold_fp_zero_store]> {
2938
}

0 commit comments

Comments
 (0)