[llvm] [AArch64] Fix register offset ld/st predicate (PR #225645)

Tomer Shafir via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 01:59:24 PDT 2026


https://github.com/tomershafir created https://github.com/llvm/llvm-project/pull/225645

The previous extension check was wrong - `CheckMemExtLSL` would always return false because it used stale memory extend type checker: `getMemExtendType`, passing a sign bit that is shifted and masked unsoundly. This patch accurately returns true for:

- W sized offset, which requires an extension by the ISA
- Shifted X sized offset

Note that UXTX and SXTX are effectively a no-op in this case so we effectively reject those.

I plan to remove stale `CheckMemExtLSL` in a followup.

>From 554e3d05ddeee585b5c41633f62ed52307a2f387 Mon Sep 17 00:00:00 2001
From: tomershafir <tomer.shafir8 at gmail.com>
Date: Wed, 23 Sep 2026 11:08:07 +0300
Subject: [PATCH] [AArch64] Fix register offset ld/st predicate

The previous extension check was wrong - `CheckMemExtLSL` would always return false because it used stale memory extend type checker: `getMemExtendType`, passing a sign bit that is shifted and masked unsoundly. This patch accurately returns true for:

- W sized offset, which requires an extension by the ISA
- Shifted X sized offset

Note that UXTX and SXTX are effectively a no-op in this case so we effectively reject those.

I plan to remove stale `CheckMemExtLSL` in a followup.
---
 .../Target/AArch64/AArch64SchedPredicates.td  | 81 ++++++++++---------
 1 file changed, 43 insertions(+), 38 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SchedPredicates.td b/llvm/lib/Target/AArch64/AArch64SchedPredicates.td
index cbaaafccd164df..b2fc95a64846b0 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedPredicates.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedPredicates.td
@@ -197,38 +197,41 @@ def IsStoreASIMDPostOp     : CheckOpcode<[ST1Onev8b_POST, ST1Onev4h_POST, ST1One
 def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
                                                      IsStoreASIMDPostOp.ValidOpcodes)>;
 
-// Identify whether an instruction is a load
-// using the register offset addressing mode.
-def IsLoadRegOffsetOp      : CheckOpcode<[PRFMroW, PRFMroX,
-                                          LDRBBroW, LDRBBroX,
-                                          LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
-                                          LDRHHroW, LDRHHroX,
-                                          LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
-                                          LDRWroW, LDRWroX,
-                                          LDRSWroW, LDRSWroX,
-                                          LDRXroW, LDRXroX,
-                                          LDRBroW, LDRBroX,
-                                          LDRHroW, LDRHroX,
-                                          LDRSroW, LDRSroX,
-                                          LDRDroW, LDRDroX,
-                                          LDRQroW, LDRQroX]>;
-
-// Identify whether an instruction is a store
-// using the register offset addressing mode.
-def IsStoreRegOffsetOp     : CheckOpcode<[STRBBroW, STRBBroX,
-                                          STRHHroW, STRHHroX,
-                                          STRWroW, STRWroX,
-                                          STRXroW, STRXroX,
-                                          STRBroW, STRBroX,
-                                          STRHroW, STRHroX,
-                                          STRSroW, STRSroX,
-                                          STRDroW, STRDroX,
-                                          STRQroW, STRQroX]>;
-
-// Identify whether an instruction is a load or
-// store using the register offset addressing mode.
-def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
-                                                     IsStoreRegOffsetOp.ValidOpcodes)>;
+// Identify whether an instruction is a load using the register offset
+// addressing mode.
+
+def IsLoadRegOffsetWOp      : CheckOpcode<[PRFMroW,
+                                           LDRBBroW, LDRSBWroW, LDRSBXroW,
+                                           LDRHHroW, LDRSHWroW, LDRSHXroW,
+                                           LDRWroW, LDRSWroW, LDRXroW,
+                                           LDRBroW, LDRHroW, LDRSroW,
+                                           LDRDroW, LDRQroW]>;
+def IsLoadRegOffsetXOp      : CheckOpcode<[PRFMroX,
+                                           LDRBBroX, LDRSBWroX, LDRSBXroX,
+                                           LDRHHroX, LDRSHWroX, LDRSHXroX,
+                                           LDRWroX, LDRSWroX, LDRXroX,
+                                           LDRBroX, LDRHroX, LDRSroX,
+                                           LDRDroX, LDRQroX]>;
+def IsLoadRegOffsetOp       : CheckOpcode<!listconcat(IsLoadRegOffsetWOp.ValidOpcodes,
+                                                      IsLoadRegOffsetXOp.ValidOpcodes)>;
+
+def IsStoreRegOffsetWOp     : CheckOpcode<[STRBBroW, STRHHroW,
+                                           STRWroW, STRXroW,
+                                           STRBroW, STRHroW, STRSroW,
+                                           STRDroW, STRQroW]>;
+def IsStoreRegOffsetXOp     : CheckOpcode<[STRBBroX, STRHHroX,
+                                           STRWroX, STRXroX,
+                                           STRBroX, STRHroX, STRSroX,
+                                           STRDroX, STRQroX]>;
+def IsStoreRegOffsetOp      : CheckOpcode<!listconcat(IsStoreRegOffsetWOp.ValidOpcodes,
+                                                      IsStoreRegOffsetXOp.ValidOpcodes)>;
+
+def IsLoadStoreRegOffsetWOp : CheckOpcode<!listconcat(IsLoadRegOffsetWOp.ValidOpcodes,
+                                                      IsStoreRegOffsetWOp.ValidOpcodes)>;
+def IsLoadStoreRegOffsetXOp : CheckOpcode<!listconcat(IsLoadRegOffsetXOp.ValidOpcodes,
+                                                      IsStoreRegOffsetXOp.ValidOpcodes)>;
+def IsLoadStoreRegOffsetOp  : CheckOpcode<!listconcat(IsLoadStoreRegOffsetWOp.ValidOpcodes,
+                                                      IsLoadStoreRegOffsetXOp.ValidOpcodes)>;
 
 // Target predicates.
 
@@ -258,15 +261,17 @@ def RegShiftedFn      : TIIPredicate<"hasShiftedReg",
                                        MCReturnStatement<FalsePred>>>;
 def RegShiftedPred    : MCSchedPredicate<RegShiftedFn>;
 
-// Identify a load or store using the register offset addressing mode
-// with an extended or scaled register.
+// Identify a load or store using the register offset addressing mode where the
+// index requires extension or scaling.  The W forms always extend Wm to 64 bits;
+// the X forms use uxtx/sxtx, which are no-ops, so only the scaling bit matters.
 def ScaledIdxFn       : TIIPredicate<"isScaledAddr",
                                      MCOpcodeSwitchStatement<
                                        [MCOpcodeSwitchCase<
-                                          IsLoadStoreRegOffsetOp.ValidOpcodes,
-                                          MCReturnStatement<
-                                            CheckAny<[CheckNot<CheckMemExtLSL>,
-                                                      CheckMemScaled]>>>],
+                                          IsLoadStoreRegOffsetWOp.ValidOpcodes,
+                                          MCReturnStatement<TruePred>>,
+                                        MCOpcodeSwitchCase<
+                                          IsLoadStoreRegOffsetXOp.ValidOpcodes,
+                                          MCReturnStatement<CheckMemScaled>>],
                                        MCReturnStatement<FalsePred>>>;
 def ScaledIdxPred     : MCSchedPredicate<ScaledIdxFn>;
 



More information about the llvm-commits mailing list