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
149 changes: 149 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,155 @@ LoongArchInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
return ArrayRef(TargetFlags);
}

bool LoongArchInstrInfo::canFoldIntoAddrMode(const MachineInstr &MemI,
Register Reg,
const MachineInstr &AddrI,
ExtAddrMode &AM) const {
enum MemIOffsetType {
Imm14Shift2,
Imm12,
Imm11Shift1,
Imm10Shift2,
Imm9Shift3,
Imm8,
Imm8Shift1,
Imm8Shift2,
Imm8Shift3
};

MemIOffsetType OT;
switch (MemI.getOpcode()) {
default:
return false;
case LoongArch::LDPTR_W:
case LoongArch::LDPTR_D:
case LoongArch::STPTR_W:
case LoongArch::STPTR_D:
OT = Imm14Shift2;
break;
case LoongArch::LD_B:
case LoongArch::LD_H:
case LoongArch::LD_W:
case LoongArch::LD_D:
case LoongArch::LD_BU:
case LoongArch::LD_HU:
case LoongArch::LD_WU:
case LoongArch::ST_B:
case LoongArch::ST_H:
case LoongArch::ST_W:
case LoongArch::ST_D:
case LoongArch::FLD_S:
case LoongArch::FLD_D:
case LoongArch::FST_S:
case LoongArch::FST_D:
case LoongArch::VLD:
case LoongArch::VST:
case LoongArch::XVLD:
case LoongArch::XVST:
case LoongArch::VLDREPL_B:
case LoongArch::XVLDREPL_B:
OT = Imm12;
break;
case LoongArch::VLDREPL_H:
case LoongArch::XVLDREPL_H:
OT = Imm11Shift1;
break;
case LoongArch::VLDREPL_W:
case LoongArch::XVLDREPL_W:
OT = Imm10Shift2;
break;
case LoongArch::VLDREPL_D:
case LoongArch::XVLDREPL_D:
OT = Imm9Shift3;
break;
case LoongArch::VSTELM_B:
case LoongArch::XVSTELM_B:
OT = Imm8;
break;
case LoongArch::VSTELM_H:
case LoongArch::XVSTELM_H:
OT = Imm8Shift1;
break;
case LoongArch::VSTELM_W:
case LoongArch::XVSTELM_W:
OT = Imm8Shift2;
break;
case LoongArch::VSTELM_D:
case LoongArch::XVSTELM_D:
OT = Imm8Shift3;
break;
}

if (MemI.getOperand(0).getReg() == Reg)
return false;

if ((AddrI.getOpcode() != LoongArch::ADDI_W &&
AddrI.getOpcode() != LoongArch::ADDI_D) ||
!AddrI.getOperand(1).isReg() || !AddrI.getOperand(2).isImm())
return false;

int64_t OldOffset = MemI.getOperand(2).getImm();
int64_t Disp = AddrI.getOperand(2).getImm();
int64_t NewOffset = OldOffset + Disp;
if (!STI.is64Bit())
NewOffset = SignExtend64<32>(NewOffset);

if (!(OT == Imm14Shift2 && isShiftedInt<14, 2>(NewOffset) && STI.hasUAL()) &&
!(OT == Imm12 && isInt<12>(NewOffset)) &&
!(OT == Imm11Shift1 && isShiftedInt<11, 1>(NewOffset)) &&
!(OT == Imm10Shift2 && isShiftedInt<10, 2>(NewOffset)) &&
!(OT == Imm9Shift3 && isShiftedInt<9, 3>(NewOffset)) &&
!(OT == Imm8 && isInt<8>(NewOffset)) &&
!(OT == Imm8Shift1 && isShiftedInt<8, 1>(NewOffset)) &&
!(OT == Imm8Shift2 && isShiftedInt<8, 2>(NewOffset)) &&
!(OT == Imm8Shift3 && isShiftedInt<8, 3>(NewOffset)))
return false;

AM.BaseReg = AddrI.getOperand(1).getReg();
AM.ScaledReg = 0;
AM.Scale = 0;
AM.Displacement = NewOffset;
AM.Form = ExtAddrMode::Formula::Basic;
return true;
}

MachineInstr *
LoongArchInstrInfo::emitLdStWithAddr(MachineInstr &MemI,
const ExtAddrMode &AM) const {
const DebugLoc &DL = MemI.getDebugLoc();
MachineBasicBlock &MBB = *MemI.getParent();

assert(AM.ScaledReg == 0 && AM.Scale == 0 &&
"Addressing mode not supported for folding");

unsigned MemIOp = MemI.getOpcode();
switch (MemIOp) {
default:
return BuildMI(MBB, MemI, DL, get(MemIOp))
.addReg(MemI.getOperand(0).getReg(),
MemI.mayLoad() ? RegState::Define : 0)
.addReg(AM.BaseReg)
.addImm(AM.Displacement)
.setMemRefs(MemI.memoperands())
.setMIFlags(MemI.getFlags());
case LoongArch::VSTELM_B:
case LoongArch::VSTELM_H:
case LoongArch::VSTELM_W:
case LoongArch::VSTELM_D:
case LoongArch::XVSTELM_B:
case LoongArch::XVSTELM_H:
case LoongArch::XVSTELM_W:
case LoongArch::XVSTELM_D:
return BuildMI(MBB, MemI, DL, get(MemIOp))
.addReg(MemI.getOperand(0).getReg(), 0)
.addReg(AM.BaseReg)
.addImm(AM.Displacement)
.addImm(MemI.getOperand(3).getImm())
.setMemRefs(MemI.memoperands())
.setMIFlags(MemI.getFlags());
}
}

// 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() &&
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ class LoongArchInstrInfo : public LoongArchGenInstrInfo {
ArrayRef<std::pair<unsigned, const char *>>
getSerializableBitmaskMachineOperandTargetFlags() const override;

bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg,
const MachineInstr &AddrI,
ExtAddrMode &AM) const override;
MachineInstr *emitLdStWithAddr(MachineInstr &MemI,
const ExtAddrMode &AM) const override;

protected:
const LoongArchSubtarget &STI;
};
Expand Down
9 changes: 8 additions & 1 deletion llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ static cl::opt<bool>
cl::desc("Enable the merge base offset pass"),
cl::init(true), cl::Hidden);

static cl::opt<bool>
EnableSinkFold("loongarch-enable-sink-fold",
cl::desc("Enable sinking and folding of instruction copies"),
cl::init(true), cl::Hidden);

static Reloc::Model getEffectiveRelocModel(const Triple &TT,
std::optional<Reloc::Model> RM) {
return RM.value_or(Reloc::Static);
Expand Down Expand Up @@ -147,7 +152,9 @@ namespace {
class LoongArchPassConfig : public TargetPassConfig {
public:
LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
: TargetPassConfig(TM, PM) {
setEnableSinkAndFold(EnableSinkFold);
}

LoongArchTargetMachine &getLoongArchTargetMachine() const {
return getTM<LoongArchTargetMachine>();
Expand Down
10 changes: 4 additions & 6 deletions llvm/test/CodeGen/LoongArch/ldptr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ define signext i32 @ldptr_w(ptr %p) nounwind {
; LA32-LABEL: ldptr_w:
; LA32: # %bb.0: # %entry
; LA32-NEXT: addi.w $a0, $a0, 2047
; LA32-NEXT: addi.w $a0, $a0, 1
; LA32-NEXT: ld.w $a0, $a0, 0
; LA32-NEXT: ld.w $a0, $a0, 1
; LA32-NEXT: ret
;
; LA64-LABEL: ldptr_w:
Expand Down Expand Up @@ -81,10 +80,9 @@ entry:
define i64 @ldptr_d(ptr %p) nounwind {
; LA32-LABEL: ldptr_d:
; LA32: # %bb.0: # %entry
; LA32-NEXT: addi.w $a0, $a0, 2047
; LA32-NEXT: addi.w $a1, $a0, 1
; LA32-NEXT: ld.w $a0, $a1, 0
; LA32-NEXT: ld.w $a1, $a1, 4
; LA32-NEXT: addi.w $a1, $a0, 2047
; LA32-NEXT: ld.w $a0, $a1, 1
; LA32-NEXT: ld.w $a1, $a1, 5
; LA32-NEXT: ret
;
; LA64-LABEL: ldptr_d:
Expand Down
Loading
Loading