Skip to content

Commit e9bcd2b

Browse files
authored
[LoongArch] Optimize *W Instructions at MI level (#90463)
Referring to RISC-V, adding an MI level pass to optimize *W instructions for LoongArch. First it removes unneeded sext(addi.w rd, rs, 0) instructions. Either because the sign extended bits aren't consumed or because the input was already sign extended by an earlier instruction. Then: 1. Unless explicit disabled or the target prefers instructions with W suffix, it removes the -w suffix from opw instructions whenever all users are dependent only on the lower word of the result of the instruction. The cases handled are: * addi.w because it helps reduce test differences between LA32 and LA64 w/o being a pessimization. 2. Or if explicit enabled or the target prefers instructions with W suffix, it adds the W suffix to the instruction whenever all users are dependent only on the lower word of the result of the instruction. The cases handled are: * add.d/addi.d/sub.d/mul.d. * slli.d with imm < 32. * ld.d/ld.wu.
1 parent 9a521e2 commit e9bcd2b

21 files changed

+1797
-627
lines changed

llvm/lib/Target/LoongArch/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ add_llvm_target(LoongArchCodeGen
2323
LoongArchISelDAGToDAG.cpp
2424
LoongArchISelLowering.cpp
2525
LoongArchMCInstLower.cpp
26+
LoongArchOptWInstrs.cpp
2627
LoongArchRegisterInfo.cpp
2728
LoongArchSubtarget.cpp
2829
LoongArchTargetMachine.cpp

llvm/lib/Target/LoongArch/LoongArch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ bool lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
3535

3636
FunctionPass *createLoongArchExpandAtomicPseudoPass();
3737
FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM);
38+
FunctionPass *createLoongArchOptWInstrsPass();
3839
FunctionPass *createLoongArchPreRAExpandPseudoPass();
3940
FunctionPass *createLoongArchExpandPseudoPass();
4041
void initializeLoongArchDAGToDAGISelPass(PassRegistry &);
4142
void initializeLoongArchExpandAtomicPseudoPass(PassRegistry &);
43+
void initializeLoongArchOptWInstrsPass(PassRegistry &);
4244
void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &);
4345
void initializeLoongArchExpandPseudoPass(PassRegistry &);
4446
} // end namespace llvm

llvm/lib/Target/LoongArch/LoongArch.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ def FeatureFrecipe
117117
"Support frecipe.{s/d} and frsqrte.{s/d} instructions.">;
118118
def HasFrecipe : Predicate<"Subtarget->hasFrecipe()">;
119119

120+
def TunePreferWInst
121+
: SubtargetFeature<"prefer-w-inst", "PreferWInst", "true",
122+
"Prefer instructions with W suffix">;
120123

121124
//===----------------------------------------------------------------------===//
122125
// Registers, instruction descriptions ...

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3768,6 +3768,7 @@ static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
37683768

37693769
static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain,
37703770
const CCValAssign &VA, const SDLoc &DL,
3771+
const ISD::InputArg &In,
37713772
const LoongArchTargetLowering &TLI) {
37723773
MachineFunction &MF = DAG.getMachineFunction();
37733774
MachineRegisterInfo &RegInfo = MF.getRegInfo();
@@ -3778,6 +3779,21 @@ static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain,
37783779
RegInfo.addLiveIn(VA.getLocReg(), VReg);
37793780
Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
37803781

3782+
// If input is sign extended from 32 bits, note it for the OptW pass.
3783+
if (In.isOrigArg()) {
3784+
Argument *OrigArg = MF.getFunction().getArg(In.getOrigArgIndex());
3785+
if (OrigArg->getType()->isIntegerTy()) {
3786+
unsigned BitWidth = OrigArg->getType()->getIntegerBitWidth();
3787+
// An input zero extended from i31 can also be considered sign extended.
3788+
if ((BitWidth <= 32 && In.Flags.isSExt()) ||
3789+
(BitWidth < 32 && In.Flags.isZExt())) {
3790+
LoongArchMachineFunctionInfo *LAFI =
3791+
MF.getInfo<LoongArchMachineFunctionInfo>();
3792+
LAFI->addSExt32Register(VReg);
3793+
}
3794+
}
3795+
}
3796+
37813797
return convertLocVTToValVT(DAG, Val, VA, DL);
37823798
}
37833799

@@ -3909,7 +3925,7 @@ SDValue LoongArchTargetLowering::LowerFormalArguments(
39093925
CCValAssign &VA = ArgLocs[i];
39103926
SDValue ArgValue;
39113927
if (VA.isRegLoc())
3912-
ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, *this);
3928+
ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, Ins[i], *this);
39133929
else
39143930
ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
39153931
if (VA.getLocInfo() == CCValAssign::Indirect) {

llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,3 +540,9 @@ LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
540540
{MO_GD_PC_HI, "loongarch-gd-pc-hi"}};
541541
return ArrayRef(TargetFlags);
542542
}
543+
544+
// Returns true if this is the sext.w pattern, addi.w rd, rs, 0.
545+
bool LoongArch::isSEXT_W(const MachineInstr &MI) {
546+
return MI.getOpcode() == LoongArch::ADDI_W && MI.getOperand(1).isReg() &&
547+
MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0;
548+
}

llvm/lib/Target/LoongArch/LoongArchInstrInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ class LoongArchInstrInfo : public LoongArchGenInstrInfo {
9090

9191
namespace LoongArch {
9292

93+
// Returns true if this is the sext.w pattern, addi.w rd, rs, 0.
94+
bool isSEXT_W(const MachineInstr &MI);
95+
9396
// Mask assignments for floating-point.
9497
static constexpr unsigned FClassMaskSignalingNaN = 0x001;
9598
static constexpr unsigned FClassMaskQuietNaN = 0x002;

llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
3636
/// insertIndirectBranch.
3737
int BranchRelaxationSpillFrameIndex = -1;
3838

39+
/// Registers that have been sign extended from i32.
40+
SmallVector<Register, 8> SExt32Registers;
41+
3942
public:
4043
LoongArchMachineFunctionInfo(const Function &F,
4144
const TargetSubtargetInfo *STI) {}
@@ -62,6 +65,12 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
6265
void setBranchRelaxationSpillFrameIndex(int Index) {
6366
BranchRelaxationSpillFrameIndex = Index;
6467
}
68+
69+
void addSExt32Register(Register Reg) { SExt32Registers.push_back(Reg); }
70+
71+
bool isSExt32Register(Register Reg) const {
72+
return is_contained(SExt32Registers, Reg);
73+
}
6574
};
6675

6776
} // end namespace llvm

0 commit comments

Comments
 (0)