[llvm] [AArch64] Add verification for MemOp immediate ranges (PR #97561)

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 3 04:59:16 PDT 2024


https://github.com/davemgreen created https://github.com/llvm/llvm-project/pull/97561

This adds an implementation of AArch64InstrInfo::verifyInstruction for AArch64, and adds some basic verification of the range of immediate ranges of memory operations using the information from getMemOpInfo.

Some extra memory operations have been added to getMemOpInfo, along with the equivalent opcodes to getLoadStoreImmIdx to ensure we use the correct index.

>From 1422591dbea2d03ab386f3fd098648cd697bf9da Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Wed, 3 Jul 2024 12:54:46 +0100
Subject: [PATCH] [AArch64] Add verification for MemOp immediate ranges

This adds an implementation of AArch64InstrInfo::verifyInstruction for AArch64,
and adds some basic verification of the range of immediate ranges of memory
operations.

Some extra memory operations have been added to getMemOpInfo, along with the
equivalent opcodes to getLoadStoreImmIdx to ensure the offsets are always
correctly calculated.
---
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp  | 389 +++++++++++++-----
 llvm/lib/Target/AArch64/AArch64InstrInfo.h    |   4 +
 .../machine-outliner-unsafe-stack-call.mir    |  16 +-
 llvm/test/CodeGen/AArch64/verify-memop.mir    |  51 +++
 4 files changed, 352 insertions(+), 108 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/verify-memop.mir

diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 93278a2ba0d09..2afcbc656c867 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -2344,132 +2344,250 @@ std::optional<unsigned> AArch64InstrInfo::getUnscaledLdSt(unsigned Opc) {
 unsigned AArch64InstrInfo::getLoadStoreImmIdx(unsigned Opc) {
   switch (Opc) {
   default:
+    llvm_unreachable("Unhandled Opcode in getLoadStoreImmIdx");
+  case AArch64::ADDG:
+  case AArch64::LDAPURBi:
+  case AArch64::LDAPURHi:
+  case AArch64::LDAPURi:
+  case AArch64::LDAPURSBWi:
+  case AArch64::LDAPURSBXi:
+  case AArch64::LDAPURSHWi:
+  case AArch64::LDAPURSHXi:
+  case AArch64::LDAPURSWi:
+  case AArch64::LDAPURXi:
+  case AArch64::LDR_PPXI:
+  case AArch64::LDR_PXI:
+  case AArch64::LDR_ZXI:
+  case AArch64::LDR_ZZXI:
+  case AArch64::LDR_ZZZXI:
+  case AArch64::LDR_ZZZZXI:
+  case AArch64::LDRBBui:
+  case AArch64::LDRBui:
+  case AArch64::LDRDui:
+  case AArch64::LDRHHui:
+  case AArch64::LDRHui:
+  case AArch64::LDRQui:
+  case AArch64::LDRSBWui:
+  case AArch64::LDRSBXui:
+  case AArch64::LDRSHWui:
+  case AArch64::LDRSHXui:
+  case AArch64::LDRSui:
+  case AArch64::LDRSWui:
+  case AArch64::LDRWui:
+  case AArch64::LDRXui:
+  case AArch64::LDURBBi:
+  case AArch64::LDURBi:
+  case AArch64::LDURDi:
+  case AArch64::LDURHHi:
+  case AArch64::LDURHi:
+  case AArch64::LDURQi:
+  case AArch64::LDURSBWi:
+  case AArch64::LDURSBXi:
+  case AArch64::LDURSHWi:
+  case AArch64::LDURSHXi:
+  case AArch64::LDURSi:
+  case AArch64::LDURSWi:
+  case AArch64::LDURWi:
+  case AArch64::LDURXi:
+  case AArch64::PRFMui:
+  case AArch64::PRFUMi:
+  case AArch64::ST2Gi:
+  case AArch64::STGi:
+  case AArch64::STLURBi:
+  case AArch64::STLURHi:
+  case AArch64::STLURWi:
+  case AArch64::STLURXi:
+  case AArch64::StoreSwiftAsyncContext:
+  case AArch64::STR_PPXI:
+  case AArch64::STR_PXI:
+  case AArch64::STR_ZXI:
+  case AArch64::STR_ZZXI:
+  case AArch64::STR_ZZZXI:
+  case AArch64::STR_ZZZZXI:
+  case AArch64::STRBBui:
+  case AArch64::STRBui:
+  case AArch64::STRDui:
+  case AArch64::STRHHui:
+  case AArch64::STRHui:
+  case AArch64::STRQui:
+  case AArch64::STRSui:
+  case AArch64::STRWui:
+  case AArch64::STRXui:
+  case AArch64::STURBBi:
+  case AArch64::STURBi:
+  case AArch64::STURDi:
+  case AArch64::STURHHi:
+  case AArch64::STURHi:
+  case AArch64::STURQi:
+  case AArch64::STURSi:
+  case AArch64::STURWi:
+  case AArch64::STURXi:
+  case AArch64::STZ2Gi:
+  case AArch64::STZGi:
+  case AArch64::TAGPstack:
     return 2;
-  case AArch64::LDPXi:
-  case AArch64::LDPDi:
-  case AArch64::STPXi:
-  case AArch64::STPDi:
-  case AArch64::LDNPXi:
-  case AArch64::LDNPDi:
-  case AArch64::STNPXi:
-  case AArch64::STNPDi:
-  case AArch64::LDPQi:
-  case AArch64::STPQi:
-  case AArch64::LDNPQi:
-  case AArch64::STNPQi:
-  case AArch64::LDPWi:
-  case AArch64::LDPSi:
-  case AArch64::STPWi:
-  case AArch64::STPSi:
-  case AArch64::LDNPWi:
-  case AArch64::LDNPSi:
-  case AArch64::STNPWi:
-  case AArch64::STNPSi:
-  case AArch64::LDG:
-  case AArch64::STGPi:
-
-  case AArch64::LD1B_IMM:
+  case AArch64::LD1B_D_IMM:
   case AArch64::LD1B_H_IMM:
+  case AArch64::LD1B_IMM:
   case AArch64::LD1B_S_IMM:
-  case AArch64::LD1B_D_IMM:
-  case AArch64::LD1SB_H_IMM:
-  case AArch64::LD1SB_S_IMM:
-  case AArch64::LD1SB_D_IMM:
+  case AArch64::LD1D_IMM:
+  case AArch64::LD1H_D_IMM:
   case AArch64::LD1H_IMM:
   case AArch64::LD1H_S_IMM:
-  case AArch64::LD1H_D_IMM:
-  case AArch64::LD1SH_S_IMM:
+  case AArch64::LD1RB_D_IMM:
+  case AArch64::LD1RB_H_IMM:
+  case AArch64::LD1RB_IMM:
+  case AArch64::LD1RB_S_IMM:
+  case AArch64::LD1RD_IMM:
+  case AArch64::LD1RH_D_IMM:
+  case AArch64::LD1RH_IMM:
+  case AArch64::LD1RH_S_IMM:
+  case AArch64::LD1RSB_D_IMM:
+  case AArch64::LD1RSB_H_IMM:
+  case AArch64::LD1RSB_S_IMM:
+  case AArch64::LD1RSH_D_IMM:
+  case AArch64::LD1RSH_S_IMM:
+  case AArch64::LD1RSW_IMM:
+  case AArch64::LD1RW_D_IMM:
+  case AArch64::LD1RW_IMM:
+  case AArch64::LD1SB_D_IMM:
+  case AArch64::LD1SB_H_IMM:
+  case AArch64::LD1SB_S_IMM:
   case AArch64::LD1SH_D_IMM:
-  case AArch64::LD1W_IMM:
-  case AArch64::LD1W_D_IMM:
+  case AArch64::LD1SH_S_IMM:
   case AArch64::LD1SW_D_IMM:
-  case AArch64::LD1D_IMM:
-
+  case AArch64::LD1W_D_IMM:
+  case AArch64::LD1W_IMM:
   case AArch64::LD2B_IMM:
+  case AArch64::LD2D_IMM:
   case AArch64::LD2H_IMM:
   case AArch64::LD2W_IMM:
-  case AArch64::LD2D_IMM:
   case AArch64::LD3B_IMM:
+  case AArch64::LD3D_IMM:
   case AArch64::LD3H_IMM:
   case AArch64::LD3W_IMM:
-  case AArch64::LD3D_IMM:
   case AArch64::LD4B_IMM:
+  case AArch64::LD4D_IMM:
   case AArch64::LD4H_IMM:
   case AArch64::LD4W_IMM:
-  case AArch64::LD4D_IMM:
-
-  case AArch64::ST1B_IMM:
+  case AArch64::LDG:
+  case AArch64::LDNF1B_D_IMM:
+  case AArch64::LDNF1B_H_IMM:
+  case AArch64::LDNF1B_IMM:
+  case AArch64::LDNF1B_S_IMM:
+  case AArch64::LDNF1D_IMM:
+  case AArch64::LDNF1H_D_IMM:
+  case AArch64::LDNF1H_IMM:
+  case AArch64::LDNF1H_S_IMM:
+  case AArch64::LDNF1SB_D_IMM:
+  case AArch64::LDNF1SB_H_IMM:
+  case AArch64::LDNF1SB_S_IMM:
+  case AArch64::LDNF1SH_D_IMM:
+  case AArch64::LDNF1SH_S_IMM:
+  case AArch64::LDNF1SW_D_IMM:
+  case AArch64::LDNF1W_D_IMM:
+  case AArch64::LDNF1W_IMM:
+  case AArch64::LDNPDi:
+  case AArch64::LDNPQi:
+  case AArch64::LDNPSi:
+  case AArch64::LDNPWi:
+  case AArch64::LDNPXi:
+  case AArch64::LDNT1B_ZRI:
+  case AArch64::LDNT1D_ZRI:
+  case AArch64::LDNT1H_ZRI:
+  case AArch64::LDNT1W_ZRI:
+  case AArch64::LDPDi:
+  case AArch64::LDPQi:
+  case AArch64::LDPSi:
+  case AArch64::LDPWi:
+  case AArch64::LDPXi:
+  case AArch64::LDRBpost:
+  case AArch64::LDRBpre:
+  case AArch64::LDRDpost:
+  case AArch64::LDRDpre:
+  case AArch64::LDRHpost:
+  case AArch64::LDRHpre:
+  case AArch64::LDRQpost:
+  case AArch64::LDRQpre:
+  case AArch64::LDRSpost:
+  case AArch64::LDRSpre:
+  case AArch64::LDRWpost:
+  case AArch64::LDRWpre:
+  case AArch64::LDRXpost:
+  case AArch64::LDRXpre:
+  case AArch64::ST1B_D_IMM:
   case AArch64::ST1B_H_IMM:
+  case AArch64::ST1B_IMM:
   case AArch64::ST1B_S_IMM:
-  case AArch64::ST1B_D_IMM:
+  case AArch64::ST1D_IMM:
+  case AArch64::ST1H_D_IMM:
   case AArch64::ST1H_IMM:
   case AArch64::ST1H_S_IMM:
-  case AArch64::ST1H_D_IMM:
-  case AArch64::ST1W_IMM:
   case AArch64::ST1W_D_IMM:
-  case AArch64::ST1D_IMM:
-
+  case AArch64::ST1W_IMM:
   case AArch64::ST2B_IMM:
+  case AArch64::ST2D_IMM:
   case AArch64::ST2H_IMM:
   case AArch64::ST2W_IMM:
-  case AArch64::ST2D_IMM:
   case AArch64::ST3B_IMM:
+  case AArch64::ST3D_IMM:
   case AArch64::ST3H_IMM:
   case AArch64::ST3W_IMM:
-  case AArch64::ST3D_IMM:
   case AArch64::ST4B_IMM:
+  case AArch64::ST4D_IMM:
   case AArch64::ST4H_IMM:
   case AArch64::ST4W_IMM:
-  case AArch64::ST4D_IMM:
-
-  case AArch64::LD1RB_IMM:
-  case AArch64::LD1RB_H_IMM:
-  case AArch64::LD1RB_S_IMM:
-  case AArch64::LD1RB_D_IMM:
-  case AArch64::LD1RSB_H_IMM:
-  case AArch64::LD1RSB_S_IMM:
-  case AArch64::LD1RSB_D_IMM:
-  case AArch64::LD1RH_IMM:
-  case AArch64::LD1RH_S_IMM:
-  case AArch64::LD1RH_D_IMM:
-  case AArch64::LD1RSH_S_IMM:
-  case AArch64::LD1RSH_D_IMM:
-  case AArch64::LD1RW_IMM:
-  case AArch64::LD1RW_D_IMM:
-  case AArch64::LD1RSW_IMM:
-  case AArch64::LD1RD_IMM:
-
-  case AArch64::LDNT1B_ZRI:
-  case AArch64::LDNT1H_ZRI:
-  case AArch64::LDNT1W_ZRI:
-  case AArch64::LDNT1D_ZRI:
+  case AArch64::STGPi:
+  case AArch64::STNPDi:
+  case AArch64::STNPQi:
+  case AArch64::STNPSi:
+  case AArch64::STNPWi:
+  case AArch64::STNPXi:
   case AArch64::STNT1B_ZRI:
+  case AArch64::STNT1D_ZRI:
   case AArch64::STNT1H_ZRI:
   case AArch64::STNT1W_ZRI:
-  case AArch64::STNT1D_ZRI:
-
-  case AArch64::LDNF1B_IMM:
-  case AArch64::LDNF1B_H_IMM:
-  case AArch64::LDNF1B_S_IMM:
-  case AArch64::LDNF1B_D_IMM:
-  case AArch64::LDNF1SB_H_IMM:
-  case AArch64::LDNF1SB_S_IMM:
-  case AArch64::LDNF1SB_D_IMM:
-  case AArch64::LDNF1H_IMM:
-  case AArch64::LDNF1H_S_IMM:
-  case AArch64::LDNF1H_D_IMM:
-  case AArch64::LDNF1SH_S_IMM:
-  case AArch64::LDNF1SH_D_IMM:
-  case AArch64::LDNF1W_IMM:
-  case AArch64::LDNF1W_D_IMM:
-  case AArch64::LDNF1SW_D_IMM:
-  case AArch64::LDNF1D_IMM:
+  case AArch64::STPDi:
+  case AArch64::STPQi:
+  case AArch64::STPSi:
+  case AArch64::STPWi:
+  case AArch64::STPXi:
+  case AArch64::STRBpost:
+  case AArch64::STRBpre:
+  case AArch64::STRDpost:
+  case AArch64::STRDpre:
+  case AArch64::STRHpost:
+  case AArch64::STRHpre:
+  case AArch64::STRQpost:
+  case AArch64::STRQpre:
+  case AArch64::STRSpost:
+  case AArch64::STRSpre:
+  case AArch64::STRWpost:
+  case AArch64::STRWpre:
+  case AArch64::STRXpost:
+  case AArch64::STRXpre:
     return 3;
-  case AArch64::ADDG:
-  case AArch64::STGi:
-  case AArch64::LDR_PXI:
-  case AArch64::STR_PXI:
-    return 2;
+  case AArch64::LDPDpost:
+  case AArch64::LDPDpre:
+  case AArch64::LDPQpost:
+  case AArch64::LDPQpre:
+  case AArch64::LDPSpost:
+  case AArch64::LDPSpre:
+  case AArch64::LDPWpost:
+  case AArch64::LDPWpre:
+  case AArch64::LDPXpost:
+  case AArch64::LDPXpre:
+  case AArch64::STPDpost:
+  case AArch64::STPDpre:
+  case AArch64::STPQpost:
+  case AArch64::STPQpre:
+  case AArch64::STPSpost:
+  case AArch64::STPSpre:
+  case AArch64::STPWpost:
+  case AArch64::STPWpre:
+  case AArch64::STPXpost:
+  case AArch64::STPXpre:
+    return 4;
   }
 }
 
@@ -3553,13 +3671,37 @@ bool AArch64InstrInfo::getMemOpInfo(unsigned Opcode, TypeSize &Scale,
     Width = TypeSize::getFixed(0);
     MinOffset = MaxOffset = 0;
     return false;
-  case AArch64::STRWpost:
+  case AArch64::LDRSpost:
+  case AArch64::LDRSpre:
   case AArch64::LDRWpost:
+  case AArch64::LDRWpre:
+  case AArch64::STRSpost:
+  case AArch64::STRSpre:
+  case AArch64::STRWpost:
+  case AArch64::STRWpre:
     Width = TypeSize::getFixed(32);
     Scale = TypeSize::getFixed(4);
     MinOffset = -256;
     MaxOffset = 255;
     break;
+  case AArch64::LDRHpost:
+  case AArch64::LDRHpre:
+  case AArch64::STRHpost:
+  case AArch64::STRHpre:
+    Width = TypeSize::getFixed(16);
+    Scale = TypeSize::getFixed(2);
+    MinOffset = -128;
+    MaxOffset = 127;
+    break;
+  case AArch64::LDRBpost:
+  case AArch64::LDRBpre:
+  case AArch64::STRBpost:
+  case AArch64::STRBpre:
+    Width = TypeSize::getFixed(8);
+    Scale = TypeSize::getFixed(1);
+    MinOffset = -64;
+    MaxOffset = 63;
+    break;
   case AArch64::LDURQi:
   case AArch64::STURQi:
     Width = TypeSize::getFixed(16);
@@ -3713,33 +3855,58 @@ bool AArch64InstrInfo::getMemOpInfo(unsigned Opcode, TypeSize &Scale,
     MinOffset = 0;
     MaxOffset = 4095;
     break;
-  case AArch64::STPXpre:
+  case AArch64::LDPSpost:
+  case AArch64::LDPSpre:
+  case AArch64::LDPWpost:
+  case AArch64::LDPWpre:
+  case AArch64::STPSpost:
+  case AArch64::STPSpre:
+  case AArch64::STPWpost:
+  case AArch64::STPWpre:
+    Scale = TypeSize::getFixed(4);
+    Width = TypeSize::getFixed(4);
+    MinOffset = -256;
+    MaxOffset = 252;
+    break;
+  case AArch64::LDPDpost:
+  case AArch64::LDPDpre:
   case AArch64::LDPXpost:
+  case AArch64::LDPXpre:
+  case AArch64::STPDpost:
   case AArch64::STPDpre:
-  case AArch64::LDPDpost:
+  case AArch64::STPXpost:
+  case AArch64::STPXpre:
     Scale = TypeSize::getFixed(8);
     Width = TypeSize::getFixed(8);
     MinOffset = -512;
     MaxOffset = 504;
     break;
-  case AArch64::STPQpre:
   case AArch64::LDPQpost:
+  case AArch64::LDPQpre:
+  case AArch64::STPQpost:
+  case AArch64::STPQpre:
     Scale = TypeSize::getFixed(16);
     Width = TypeSize::getFixed(16);
     MinOffset = -1024;
     MaxOffset = 1008;
     break;
-  case AArch64::STRXpre:
-  case AArch64::STRDpre:
-  case AArch64::LDRXpost:
   case AArch64::LDRDpost:
+  case AArch64::LDRDpre:
+  case AArch64::LDRXpost:
+  case AArch64::LDRXpre:
+  case AArch64::STRDpost:
+  case AArch64::STRDpre:
+  case AArch64::STRXpost:
+  case AArch64::STRXpre:
     Scale = TypeSize::getFixed(1);
     Width = TypeSize::getFixed(8);
     MinOffset = -256;
     MaxOffset = 255;
     break;
-  case AArch64::STRQpre:
   case AArch64::LDRQpost:
+  case AArch64::LDRQpre:
+  case AArch64::STRQpost:
+  case AArch64::STRQpre:
     Scale = TypeSize::getFixed(1);
     Width = TypeSize::getFixed(16);
     MinOffset = -256;
@@ -10016,6 +10183,28 @@ AArch64InstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {
       Init, IsUpdatePriorComp, Cond);
 }
 
+/// verifyInstruction - Perform target specific instruction verification.
+bool AArch64InstrInfo::verifyInstruction(const MachineInstr &MI,
+                                         StringRef &ErrInfo) const {
+
+  // Verify that immediate offsets on load/store instructions are within range.
+  // Stack objects with an FI operand are excluded as they can be fixed up
+  // during PEI.
+  TypeSize Scale(0U, false), Width(0U, false);
+  int64_t MinOffset, MaxOffset;
+  if (getMemOpInfo(MI.getOpcode(), Scale, Width, MinOffset, MaxOffset)) {
+    unsigned ImmIdx = getLoadStoreImmIdx(MI.getOpcode());
+    if (MI.getOperand(ImmIdx).isImm() && !MI.getOperand(ImmIdx - 1).isFI()) {
+      int64_t Imm = MI.getOperand(ImmIdx).getImm();
+      if (Imm < MinOffset || Imm > MaxOffset) {
+        ErrInfo = "Unexpected immediate on load/store instruction";
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
 #define GET_INSTRINFO_HELPERS
 #define GET_INSTRMAP_INFO
 #include "AArch64GenInstrInfo.inc"
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index 792e0c3063b10..8c7a9d845e09f 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -575,6 +575,10 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
   std::optional<unsigned>
   canRemovePTestInstr(MachineInstr *PTest, MachineInstr *Mask,
                       MachineInstr *Pred, const MachineRegisterInfo *MRI) const;
+
+  /// verifyInstruction - Perform target specific instruction verification.
+  bool verifyInstruction(const MachineInstr &MI,
+                         StringRef &ErrInfo) const override;
 };
 
 struct UsedNZCV {
diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-unsafe-stack-call.mir b/llvm/test/CodeGen/AArch64/machine-outliner-unsafe-stack-call.mir
index 0853b23e52916..679c9687e66f0 100644
--- a/llvm/test/CodeGen/AArch64/machine-outliner-unsafe-stack-call.mir
+++ b/llvm/test/CodeGen/AArch64/machine-outliner-unsafe-stack-call.mir
@@ -25,10 +25,10 @@ body:             |
     ; CHECK-DAG: baz
     $lr = ORRXri $xzr, 1
     BL @foo, implicit-def dead $lr, implicit $sp
-    $x20, $x19 = LDPXi $sp, 255
-    $x20, $x19 = LDPXi $sp, 255
-    $x20, $x19 = LDPXi $sp, 255
-    $x20, $x19 = LDPXi $sp, 255
+    $x20, $x19 = LDPXi $sp, 63
+    $x20, $x19 = LDPXi $sp, 63
+    $x20, $x19 = LDPXi $sp, 63
+    $x20, $x19 = LDPXi $sp, 63
   bb.1:
     BL @bar, implicit-def dead $lr, implicit $sp
     $x11 = ADDXri $sp, 48, 0;
@@ -55,10 +55,10 @@ body:             |
     ; CHECK-DAG: baz
     $lr = ORRXri $xzr, 1
     BL @foo, implicit-def dead $lr, implicit $sp
-    $x20, $x19 = LDPXi $sp, 255
-    $x20, $x19 = LDPXi $sp, 255
-    $x20, $x19 = LDPXi $sp, 255
-    $x20, $x19 = LDPXi $sp, 255
+    $x20, $x19 = LDPXi $sp, 63
+    $x20, $x19 = LDPXi $sp, 63
+    $x20, $x19 = LDPXi $sp, 63
+    $x20, $x19 = LDPXi $sp, 63
   bb.1:
     BL @bar, implicit-def dead $lr, implicit $sp
     $x11 = ADDXri $sp, 48, 0;
diff --git a/llvm/test/CodeGen/AArch64/verify-memop.mir b/llvm/test/CodeGen/AArch64/verify-memop.mir
new file mode 100644
index 0000000000000..90aa5e64a7f72
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/verify-memop.mir
@@ -0,0 +1,51 @@
+# RUN: not --crash llc -mtriple=aarch64 -run-pass machineverifier -o /dev/null %s 2>&1 | FileCheck -implicit-check-not="Bad machine code"  %s
+
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: STRSui $s1, $x0, 4096
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: STRSui $s1, $x0, -1
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: early-clobber $x0, $w1 = LDRWpre $x0(tied-def 0), 256
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: early-clobber $x0, $w1 = LDRWpre $x0(tied-def 0), -257
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: early-clobber $x0, $w1 = LDRWpre $x0(tied-def 0), 256
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: early-clobber $x0, $w1 = LDRWpre $x0(tied-def 0), -257
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: STRBBui $w1, $x0, 4096
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: STRBBui $w1, $x0, -1
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: STRHHui $w1, $x0, 4096
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: STRHHui $w1, $x0, -1
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: early-clobber $x0 = STRSpost $s1, $x0(tied-def 0), 256
+# CHECK: *** Bad machine code: Unexpected immediate on load/store instruction ***
+# CHECK: - instruction: early-clobber $x0 = STRSpost $s1, $x0(tied-def 0), -257
+
+---
+name:            testoffsets
+alignment:       4
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $d0, $s1, $q2, $x0, $w1
+
+    STRSui $s1, $x0, 4095
+    STRSui $s1, $x0, 4096
+    STRSui $s1, $x0, 0
+    STRSui $s1, $x0, -1
+    $x0, $w1 = LDRWpre $x0, 256
+    $x0, $w1 = LDRWpre $x0, -257
+    $x0, $w1 = LDRWpre $x0, 256
+    $x0, $w1 = LDRWpre $x0, -257
+    STRBBui $w1, $x0, 4096
+    STRBBui $w1, $x0, -1
+    STRHHui $w1, $x0, 4096
+    STRHHui $w1, $x0, -1
+    $x0 = STRSpost $s1, $x0, 256
+    $x0 = STRSpost $s1, $x0, -257
+    RET undef $lr, implicit $x0
+...



More information about the llvm-commits mailing list