[llvm] [AArch64] Fold UMOV(lane 0) + GPR store in FPR store (PR #199139)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 2 01:45:50 PDT 2026
================
@@ -3012,6 +3022,140 @@ bool AArch64LoadStoreOpt::tryToMergeIndexLdSt(MachineBasicBlock::iterator &MBBI,
return false;
}
+// Map a GPR store opcode to its FPR equivalent at the same data width.
+// Returns 0 if no mapping exists.
+static unsigned getGPRToFPRStoreOpcode(unsigned GPRStoreOpc) {
+ switch (GPRStoreOpc) {
+ // Unsigned immediate.
+ case AArch64::STRBBui:
+ return AArch64::STRBui;
+ case AArch64::STRHHui:
+ return AArch64::STRHui;
+ case AArch64::STRWui:
+ return AArch64::STRSui;
+ case AArch64::STRXui:
+ return AArch64::STRDui;
+ // Unscaled immediate.
+ case AArch64::STURBBi:
+ return AArch64::STURBi;
+ case AArch64::STURHHi:
+ return AArch64::STURHi;
+ case AArch64::STURWi:
+ return AArch64::STURSi;
+ case AArch64::STURXi:
+ return AArch64::STURDi;
+ // Register offset.
+ case AArch64::STRBBroW:
+ return AArch64::STRBroW;
+ case AArch64::STRBBroX:
+ return AArch64::STRBroX;
+ case AArch64::STRHHroW:
+ return AArch64::STRHroW;
+ case AArch64::STRHHroX:
+ return AArch64::STRHroX;
+ case AArch64::STRWroW:
+ return AArch64::STRSroW;
+ case AArch64::STRWroX:
+ return AArch64::STRSroX;
+ case AArch64::STRXroW:
+ return AArch64::STRDroW;
+ case AArch64::STRXroX:
+ return AArch64::STRDroX;
+ default:
+ return 0;
+ }
+}
+
+// Given a UMOV-lane-0 opcode, return the sub-register index to extract from
+// the vector register, or 0 if the opcode is not a supported UMOV.
+static unsigned getUMOVSubRegIdx(unsigned UMOVOpc) {
+ switch (UMOVOpc) {
+ case AArch64::UMOVvi8_idx0:
+ return AArch64::bsub;
+ case AArch64::UMOVvi16_idx0:
+ return AArch64::hsub;
+ case AArch64::UMOVvi32_idx0:
+ return AArch64::ssub;
+ case AArch64::UMOVvi64_idx0:
+ return AArch64::dsub;
+ default:
+ return 0;
+ }
+}
+
+bool AArch64LoadStoreOpt::tryToReplaceUMOVStore(
+ MachineBasicBlock::iterator &MBBI) {
+ MachineInstr &StoreMI = *MBBI;
+
+ unsigned FPRStoreOpc = getGPRToFPRStoreOpcode(StoreMI.getOpcode());
+ if (!FPRStoreOpc)
+ return false;
+
+ MachineBasicBlock *MBB = StoreMI.getParent();
+ MCPhysReg StoreValReg = StoreMI.getOperand(0).getReg();
+
+ if (!StoreMI.getOperand(0).isKill())
+ return false;
+
+ // Scan backward to find the UMOV that defines the store's value register.
+ MachineInstr *UMOVMI = nullptr;
+ MachineBasicBlock::iterator B = MBB->begin();
+ unsigned SubRegIdx = 0;
+ unsigned Count = 0;
+ for (auto It = MBBI; It != B && !UMOVMI;) {
+ MachineInstr &MI = *--It;
+ if (MI.isDebugInstr())
+ continue;
+ if (++Count > UMOVFoldLimit)
+ return false;
+ if (MI.readsRegister(StoreValReg, TRI))
+ return false;
+ if (MI.definesRegister(StoreValReg, TRI)) {
+ SubRegIdx = getUMOVSubRegIdx(MI.getOpcode());
+ if (!SubRegIdx)
+ return false;
+ UMOVMI = &MI;
----------------
davemgreen wrote:
break here?
https://github.com/llvm/llvm-project/pull/199139
More information about the llvm-commits
mailing list