Skip to content

Commit

Permalink
[LoongArch] Optimize *W Instructions at MI level (#90463)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
heiher committed May 6, 2024
1 parent 9a521e2 commit e9bcd2b
Show file tree
Hide file tree
Showing 21 changed files with 1,797 additions and 627 deletions.
1 change: 1 addition & 0 deletions llvm/lib/Target/LoongArch/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ add_llvm_target(LoongArchCodeGen
LoongArchISelDAGToDAG.cpp
LoongArchISelLowering.cpp
LoongArchMCInstLower.cpp
LoongArchOptWInstrs.cpp
LoongArchRegisterInfo.cpp
LoongArchSubtarget.cpp
LoongArchTargetMachine.cpp
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArch.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ bool lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,

FunctionPass *createLoongArchExpandAtomicPseudoPass();
FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM);
FunctionPass *createLoongArchOptWInstrsPass();
FunctionPass *createLoongArchPreRAExpandPseudoPass();
FunctionPass *createLoongArchExpandPseudoPass();
void initializeLoongArchDAGToDAGISelPass(PassRegistry &);
void initializeLoongArchExpandAtomicPseudoPass(PassRegistry &);
void initializeLoongArchOptWInstrsPass(PassRegistry &);
void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &);
void initializeLoongArchExpandPseudoPass(PassRegistry &);
} // end namespace llvm
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArch.td
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ def FeatureFrecipe
"Support frecipe.{s/d} and frsqrte.{s/d} instructions.">;
def HasFrecipe : Predicate<"Subtarget->hasFrecipe()">;

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

//===----------------------------------------------------------------------===//
// Registers, instruction descriptions ...
Expand Down
18 changes: 17 additions & 1 deletion llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3768,6 +3768,7 @@ static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,

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

// If input is sign extended from 32 bits, note it for the OptW pass.
if (In.isOrigArg()) {
Argument *OrigArg = MF.getFunction().getArg(In.getOrigArgIndex());
if (OrigArg->getType()->isIntegerTy()) {
unsigned BitWidth = OrigArg->getType()->getIntegerBitWidth();
// An input zero extended from i31 can also be considered sign extended.
if ((BitWidth <= 32 && In.Flags.isSExt()) ||
(BitWidth < 32 && In.Flags.isZExt())) {
LoongArchMachineFunctionInfo *LAFI =
MF.getInfo<LoongArchMachineFunctionInfo>();
LAFI->addSExt32Register(VReg);
}
}
}

return convertLocVTToValVT(DAG, Val, VA, DL);
}

Expand Down Expand Up @@ -3909,7 +3925,7 @@ SDValue LoongArchTargetLowering::LowerFormalArguments(
CCValAssign &VA = ArgLocs[i];
SDValue ArgValue;
if (VA.isRegLoc())
ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, *this);
ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, Ins[i], *this);
else
ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
if (VA.getLocInfo() == CCValAssign::Indirect) {
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,3 +540,9 @@ LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
{MO_GD_PC_HI, "loongarch-gd-pc-hi"}};
return ArrayRef(TargetFlags);
}

// Returns true if this is the sext.w pattern, addi.w rd, rs, 0.
bool LoongArch::isSEXT_W(const MachineInstr &MI) {
return MI.getOpcode() == LoongArch::ADDI_W && MI.getOperand(1).isReg() &&
MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0;
}
3 changes: 3 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class LoongArchInstrInfo : public LoongArchGenInstrInfo {

namespace LoongArch {

// Returns true if this is the sext.w pattern, addi.w rd, rs, 0.
bool isSEXT_W(const MachineInstr &MI);

// Mask assignments for floating-point.
static constexpr unsigned FClassMaskSignalingNaN = 0x001;
static constexpr unsigned FClassMaskQuietNaN = 0x002;
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
/// insertIndirectBranch.
int BranchRelaxationSpillFrameIndex = -1;

/// Registers that have been sign extended from i32.
SmallVector<Register, 8> SExt32Registers;

public:
LoongArchMachineFunctionInfo(const Function &F,
const TargetSubtargetInfo *STI) {}
Expand All @@ -62,6 +65,12 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
void setBranchRelaxationSpillFrameIndex(int Index) {
BranchRelaxationSpillFrameIndex = Index;
}

void addSExt32Register(Register Reg) { SExt32Registers.push_back(Reg); }

bool isSExt32Register(Register Reg) const {
return is_contained(SExt32Registers, Reg);
}
};

} // end namespace llvm
Expand Down
Loading

0 comments on commit e9bcd2b

Please sign in to comment.