Skip to content

Commit 495f096

Browse files
committed
[LoongArch] Optimize *W Instructions at MI level
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 ec6c0a2 commit 495f096

19 files changed

+1604
-464
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
@@ -3746,6 +3746,7 @@ static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
37463746

37473747
static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain,
37483748
const CCValAssign &VA, const SDLoc &DL,
3749+
const ISD::InputArg &In,
37493750
const LoongArchTargetLowering &TLI) {
37503751
MachineFunction &MF = DAG.getMachineFunction();
37513752
MachineRegisterInfo &RegInfo = MF.getRegInfo();
@@ -3756,6 +3757,21 @@ static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain,
37563757
RegInfo.addLiveIn(VA.getLocReg(), VReg);
37573758
Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
37583759

3760+
// If input is sign extended from 32 bits, note it for the OptW pass.
3761+
if (In.isOrigArg()) {
3762+
Argument *OrigArg = MF.getFunction().getArg(In.getOrigArgIndex());
3763+
if (OrigArg->getType()->isIntegerTy()) {
3764+
unsigned BitWidth = OrigArg->getType()->getIntegerBitWidth();
3765+
// An input zero extended from i31 can also be considered sign extended.
3766+
if ((BitWidth <= 32 && In.Flags.isSExt()) ||
3767+
(BitWidth < 32 && In.Flags.isZExt())) {
3768+
LoongArchMachineFunctionInfo *LAFI =
3769+
MF.getInfo<LoongArchMachineFunctionInfo>();
3770+
LAFI->addSExt32Register(VReg);
3771+
}
3772+
}
3773+
}
3774+
37593775
return convertLocVTToValVT(DAG, Val, VA, DL);
37603776
}
37613777

@@ -3887,7 +3903,7 @@ SDValue LoongArchTargetLowering::LowerFormalArguments(
38873903
CCValAssign &VA = ArgLocs[i];
38883904
SDValue ArgValue;
38893905
if (VA.isRegLoc())
3890-
ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, *this);
3906+
ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, Ins[i], *this);
38913907
else
38923908
ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
38933909
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
@@ -534,3 +534,9 @@ LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
534534
{MO_GD_PC_HI, "loongarch-gd-pc-hi"}};
535535
return ArrayRef(TargetFlags);
536536
}
537+
538+
// Returns true if this is the sext.w pattern, addi.w rd, rs, 0.
539+
bool LoongArch::isSEXT_W(const MachineInstr &MI) {
540+
return MI.getOpcode() == LoongArch::ADDI_W && MI.getOperand(1).isReg() &&
541+
MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0;
542+
}

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)