[llvm] [ARM] CMSE security mitigation on function arguments and returned values (PR #89944)

Lucas Duarte Prates via llvm-commits llvm-commits at lists.llvm.org
Tue May 21 08:19:29 PDT 2024


https://github.com/pratlucas updated https://github.com/llvm/llvm-project/pull/89944

>From f63a70827841e4df4cb3da52c43f4258e06aade0 Mon Sep 17 00:00:00 2001
From: Lucas Prates <lucas.prates at arm.com>
Date: Wed, 24 Apr 2024 16:51:30 +0100
Subject: [PATCH 1/4] [ARM] CMSE security mitigation on function arguments

The ABI mandates two things related to function calls:
 - Function arguments must be sign- or zero-extended to the register
   size by the caller.
 - Return values must be sign- or zero-extended to the register size by
   the callee.

As consequence, callees can assume that function arguments have been
extended and so can callers with regards to return values.

Here lies the problem: Nonsecure code might deliberately ignore this
mandate with the intent of attempting an exploit. It might try to pass
values that lie outside the expected type's value range in order to
trigger undefined behaviour, e.g. out of bounds access.

With the mitigation implemented, Secure code always performs extension
of values passed by Nonsecure code.

This addresses the vulnerability described in CVE-2024-0151.

This patch covers function arguments of Secure entry functions.

Patch by Victor Campos.

Co-authored-by: Victor Campos <victor.campos at arm.com>
---
 llvm/lib/Target/ARM/ARMISelLowering.cpp       |  23 +-
 .../ARM/cmse-harden-entry-arguments.ll        | 235 ++++++++++++++++++
 2 files changed, 256 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/ARM/cmse-harden-entry-arguments.ll

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index d0e9f61c0bd12..cf7961650b896 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -156,6 +156,17 @@ static const MCPhysReg GPRArgRegs[] = {
   ARM::R0, ARM::R1, ARM::R2, ARM::R3
 };
 
+static SDValue handleCMSEValue(const SDValue &Value, const ISD::InputArg &Arg,
+                               SelectionDAG &DAG, const SDLoc &DL, EVT RegVT) {
+  assert(Arg.ArgVT.isScalarInteger() && RegVT.isScalarInteger());
+  assert(Arg.ArgVT.bitsLT(RegVT));
+  SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, Arg.ArgVT, Value);
+  SDValue Ext =
+      DAG.getNode(Arg.Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, DL,
+                  RegVT, Trunc);
+  return Ext;
+}
+
 void ARMTargetLowering::addTypeForNEON(MVT VT, MVT PromotedLdStVT) {
   if (VT != PromotedLdStVT) {
     setOperationAction(ISD::LOAD, VT, Promote);
@@ -4479,8 +4490,6 @@ SDValue ARMTargetLowering::LowerFormalArguments(
                  *DAG.getContext());
   CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, isVarArg));
 
-  SmallVector<SDValue, 16> ArgValues;
-  SDValue ArgValue;
   Function::const_arg_iterator CurOrigArg = MF.getFunction().arg_begin();
   unsigned CurArgIdx = 0;
 
@@ -4535,6 +4544,7 @@ SDValue ARMTargetLowering::LowerFormalArguments(
     // Arguments stored in registers.
     if (VA.isRegLoc()) {
       EVT RegVT = VA.getLocVT();
+      SDValue ArgValue;
 
       if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
         // f64 and vector types are split up into multiple registers or
@@ -4617,6 +4627,15 @@ SDValue ARMTargetLowering::LowerFormalArguments(
           (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
         ArgValue = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), ArgValue);
 
+      // On CMSE Entry Functions, formal integer arguments whose bitwidth is
+      // less than 32 bits must be sign- or zero-extended in the callee for
+      // security reasons. Although the ABI mandates an extension done by the
+      // caller, the latter cannot be trusted to follow the rules of the ABI.
+      const ISD::InputArg &Arg = Ins[VA.getValNo()];
+      if (AFI->isCmseNSEntryFunction() && Arg.ArgVT.isScalarInteger() &&
+          RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(RegVT))
+        ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl, RegVT);
+
       InVals.push_back(ArgValue);
     } else { // VA.isRegLoc()
       // Only arguments passed on the stack should make it here.
diff --git a/llvm/test/CodeGen/ARM/cmse-harden-entry-arguments.ll b/llvm/test/CodeGen/ARM/cmse-harden-entry-arguments.ll
new file mode 100644
index 0000000000000..dd0dd598e75ce
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/cmse-harden-entry-arguments.ll
@@ -0,0 +1,235 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc %s -mtriple=thumbv8m.main     -o - | FileCheck %s --check-prefix V8M
+; RUN: llc %s -mtriple=thumbebv8m.main   -o - | FileCheck %s --check-prefix V8M
+; RUN: llc %s -mtriple=thumbv8.1m.main   -o - | FileCheck %s --check-prefix V81M
+; RUN: llc %s -mtriple=thumbebv8.1m.main -o - | FileCheck %s --check-prefix V81M
+
+ at arr = hidden local_unnamed_addr global [256 x i32] zeroinitializer, align 4
+
+define i32 @access_i16(i16 signext %idx) "cmse_nonsecure_entry" {
+; V8M-LABEL: access_i16:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    sxth r0, r0
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    mov r2, lr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    mov r1, lr
+; V8M-NEXT:    mov r3, lr
+; V8M-NEXT:    msr apsr_nzcvq, lr
+; V8M-NEXT:    mov r12, lr
+; V8M-NEXT:    bxns lr
+;
+; V81M-LABEL: access_i16:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    sxth r0, r0
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-NEXT:    bxns lr
+entry:
+  %idxprom = sext i16 %idx to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %0 = load i32, ptr %arrayidx, align 4
+  ret i32 %0
+}
+
+define i32 @access_u16(i16 zeroext %idx) "cmse_nonsecure_entry" {
+; V8M-LABEL: access_u16:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    uxth r0, r0
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    mov r2, lr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    mov r1, lr
+; V8M-NEXT:    mov r3, lr
+; V8M-NEXT:    msr apsr_nzcvq, lr
+; V8M-NEXT:    mov r12, lr
+; V8M-NEXT:    bxns lr
+;
+; V81M-LABEL: access_u16:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    uxth r0, r0
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-NEXT:    bxns lr
+entry:
+  %idxprom = zext i16 %idx to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %0 = load i32, ptr %arrayidx, align 4
+  ret i32 %0
+}
+
+define i32 @access_i8(i8 signext %idx) "cmse_nonsecure_entry" {
+; V8M-LABEL: access_i8:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    sxtb r0, r0
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    mov r2, lr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    mov r1, lr
+; V8M-NEXT:    mov r3, lr
+; V8M-NEXT:    msr apsr_nzcvq, lr
+; V8M-NEXT:    mov r12, lr
+; V8M-NEXT:    bxns lr
+;
+; V81M-LABEL: access_i8:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    sxtb r0, r0
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-NEXT:    bxns lr
+entry:
+  %idxprom = sext i8 %idx to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %0 = load i32, ptr %arrayidx, align 4
+  ret i32 %0
+}
+
+define i32 @access_u8(i8 zeroext %idx) "cmse_nonsecure_entry" {
+; V8M-LABEL: access_u8:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    uxtb r0, r0
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    mov r2, lr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    mov r1, lr
+; V8M-NEXT:    mov r3, lr
+; V8M-NEXT:    msr apsr_nzcvq, lr
+; V8M-NEXT:    mov r12, lr
+; V8M-NEXT:    bxns lr
+;
+; V81M-LABEL: access_u8:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    uxtb r0, r0
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-NEXT:    bxns lr
+entry:
+  %idxprom = zext i8 %idx to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %0 = load i32, ptr %arrayidx, align 4
+  ret i32 %0
+}
+
+define i32 @access_i1(i1 signext %idx) "cmse_nonsecure_entry" {
+; V8M-LABEL: access_i1:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    and r0, r0, #1
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    rsbs r0, r0, #0
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    and r0, r0, #1
+; V8M-NEXT:    mov r2, lr
+; V8M-NEXT:    mov r3, lr
+; V8M-NEXT:    mov r12, lr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    mov r1, lr
+; V8M-NEXT:    msr apsr_nzcvq, lr
+; V8M-NEXT:    bxns lr
+;
+; V81M-LABEL: access_i1:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-NEXT:    and r0, r0, #1
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    rsbs r0, r0, #0
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    and r0, r0, #1
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-NEXT:    bxns lr
+entry:
+  %idxprom = zext i1 %idx to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %0 = load i32, ptr %arrayidx, align 4
+  ret i32 %0
+}
+
+define i32 @access_i5(i5 signext %idx) "cmse_nonsecure_entry" {
+; V8M-LABEL: access_i5:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    sbfx r0, r0, #0, #5
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    mov r2, lr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    mov r1, lr
+; V8M-NEXT:    mov r3, lr
+; V8M-NEXT:    msr apsr_nzcvq, lr
+; V8M-NEXT:    mov r12, lr
+; V8M-NEXT:    bxns lr
+;
+; V81M-LABEL: access_i5:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    sbfx r0, r0, #0, #5
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-NEXT:    bxns lr
+entry:
+  %idxprom = sext i5 %idx to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %0 = load i32, ptr %arrayidx, align 4
+  ret i32 %0
+}
+
+define i32 @access_u5(i5 zeroext %idx) "cmse_nonsecure_entry" {
+; V8M-LABEL: access_u5:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    and r0, r0, #31
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    mov r2, lr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    mov r1, lr
+; V8M-NEXT:    mov r3, lr
+; V8M-NEXT:    msr apsr_nzcvq, lr
+; V8M-NEXT:    mov r12, lr
+; V8M-NEXT:    bxns lr
+;
+; V81M-LABEL: access_u5:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    and r0, r0, #31
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-NEXT:    bxns lr
+entry:
+  %idxprom = zext i5 %idx to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %0 = load i32, ptr %arrayidx, align 4
+  ret i32 %0
+}

>From e563fa5ccac9e2944f684fe0db5c9d1cd91f51b5 Mon Sep 17 00:00:00 2001
From: Lucas Prates <lucas.prates at arm.com>
Date: Wed, 24 Apr 2024 16:53:16 +0100
Subject: [PATCH 2/4] [ARM] CMSE security mitigation on returned values

The ABI mandates two things related to function calls:
 - Function arguments must be sign- or zero-extended to the register
   size by the caller.
 - Return values must be sign- or zero-extended to the register size by
   the callee.

As consequence, callees can assume that function arguments have been
extended and so can callers with regards to return values.

Here lies the problem: Nonsecure code might deliberately ignore this
mandate with the intent of attempting an exploit. It might try to pass
values that lie outside the expected type's value range in order to
trigger undefined behaviour, e.g. out of bounds access.

With the mitigation implemented, Secure code always performs extension
of values passed by Nonsecure code.

This addresses the vulnerability described in CVE-2024-0151.

This patch covers returned values from Nonsecure calls.

Patch by Victor Campos.

Co-authored-by: Victor Campos <victor.campos at arm.com>
---
 llvm/lib/Target/ARM/ARMISelLowering.cpp       |  13 +-
 llvm/lib/Target/ARM/ARMISelLowering.h         |   2 +-
 .../ARM/cmse-harden-call-returned-values.ll   | 449 ++++++++++++++++++
 3 files changed, 461 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/CodeGen/ARM/cmse-harden-call-returned-values.ll

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index cf7961650b896..f1594071cdfe5 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2207,7 +2207,7 @@ SDValue ARMTargetLowering::LowerCallResult(
     SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
-    SDValue ThisVal) const {
+    SDValue ThisVal, bool isCmseNSCall) const {
   // Assign locations to each value returned by this call.
   SmallVector<CCValAssign, 16> RVLocs;
   CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
@@ -2285,6 +2285,15 @@ SDValue ARMTargetLowering::LowerCallResult(
         (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
       Val = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Val);
 
+    // On CMSE Non-secure Calls, call results (returned values) whose bitwidth
+    // is less than 32 bits must be sign- or zero-extended after the call for
+    // security reasons. Although the ABI mandates an extension done by the
+    // callee, the latter cannot be trusted to follow the rules of the ABI.
+    const ISD::InputArg &Arg = Ins[VA.getValNo()];
+    if (isCmseNSCall && Arg.ArgVT.isScalarInteger() &&
+        VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(VA.getLocVT()))
+      Val = handleCMSEValue(Val, Arg, DAG, dl, VA.getLocVT());
+
     InVals.push_back(Val);
   }
 
@@ -2897,7 +2906,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
   // return.
   return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl, DAG,
                          InVals, isThisReturn,
-                         isThisReturn ? OutVals[0] : SDValue());
+                         isThisReturn ? OutVals[0] : SDValue(), isCmseNSCall);
 }
 
 /// HandleByVal - Every parameter *after* a byval parameter is passed
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index 26ef295e3d3fc..c9371c128cb7d 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -895,7 +895,7 @@ class VectorType;
                             const SmallVectorImpl<ISD::InputArg> &Ins,
                             const SDLoc &dl, SelectionDAG &DAG,
                             SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
-                            SDValue ThisVal) const;
+                            SDValue ThisVal, bool isCmseNSCall) const;
 
     bool supportSplitCSR(MachineFunction *MF) const override {
       return MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS &&
diff --git a/llvm/test/CodeGen/ARM/cmse-harden-call-returned-values.ll b/llvm/test/CodeGen/ARM/cmse-harden-call-returned-values.ll
new file mode 100644
index 0000000000000..75f067adbf115
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/cmse-harden-call-returned-values.ll
@@ -0,0 +1,449 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc %s -mtriple=thumbv8m.main     -o - | FileCheck %s --check-prefix V8M
+; RUN: llc %s -mtriple=thumbebv8m.main   -o - | FileCheck %s --check-prefix V8M
+; RUN: llc %s -mtriple=thumbv8.1m.main   -o - | FileCheck %s --check-prefix V81M
+; RUN: llc %s -mtriple=thumbebv8.1m.main -o - | FileCheck %s --check-prefix V81M
+
+ at get_idx = hidden local_unnamed_addr global ptr null, align 4
+ at arr = hidden local_unnamed_addr global [256 x i32] zeroinitializer, align 4
+
+define i32 @access_i16() {
+; V8M-LABEL: access_i16:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    push {r7, lr}
+; V8M-NEXT:    movw r0, :lower16:get_idx
+; V8M-NEXT:    movt r0, :upper16:get_idx
+; V8M-NEXT:    ldr r0, [r0]
+; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    bic r0, r0, #1
+; V8M-NEXT:    sub sp, #136
+; V8M-NEXT:    vlstm sp
+; V8M-NEXT:    mov r1, r0
+; V8M-NEXT:    mov r2, r0
+; V8M-NEXT:    mov r3, r0
+; V8M-NEXT:    mov r4, r0
+; V8M-NEXT:    mov r5, r0
+; V8M-NEXT:    mov r6, r0
+; V8M-NEXT:    mov r7, r0
+; V8M-NEXT:    mov r8, r0
+; V8M-NEXT:    mov r9, r0
+; V8M-NEXT:    mov r10, r0
+; V8M-NEXT:    mov r11, r0
+; V8M-NEXT:    mov r12, r0
+; V8M-NEXT:    msr apsr_nzcvq, r0
+; V8M-NEXT:    blxns r0
+; V8M-NEXT:    vlldm sp
+; V8M-NEXT:    add sp, #136
+; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    sxth r0, r0
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    pop {r7, pc}
+;
+; V81M-LABEL: access_i16:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    push {r7, lr}
+; V81M-NEXT:    movw r0, :lower16:get_idx
+; V81M-NEXT:    movt r0, :upper16:get_idx
+; V81M-NEXT:    ldr r0, [r0]
+; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    bic r0, r0, #1
+; V81M-NEXT:    sub sp, #136
+; V81M-NEXT:    vlstm sp
+; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-NEXT:    blxns r0
+; V81M-NEXT:    vlldm sp
+; V81M-NEXT:    add sp, #136
+; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    sxth r0, r0
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    pop {r7, pc}
+entry:
+  %0 = load ptr, ptr @get_idx, align 4
+  %call = tail call signext i16 %0() "cmse_nonsecure_call"
+  %idxprom = sext i16 %call to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %1 = load i32, ptr %arrayidx, align 4
+  ret i32 %1
+}
+
+define i32 @access_u16() {
+; V8M-LABEL: access_u16:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    push {r7, lr}
+; V8M-NEXT:    movw r0, :lower16:get_idx
+; V8M-NEXT:    movt r0, :upper16:get_idx
+; V8M-NEXT:    ldr r0, [r0]
+; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    bic r0, r0, #1
+; V8M-NEXT:    sub sp, #136
+; V8M-NEXT:    vlstm sp
+; V8M-NEXT:    mov r1, r0
+; V8M-NEXT:    mov r2, r0
+; V8M-NEXT:    mov r3, r0
+; V8M-NEXT:    mov r4, r0
+; V8M-NEXT:    mov r5, r0
+; V8M-NEXT:    mov r6, r0
+; V8M-NEXT:    mov r7, r0
+; V8M-NEXT:    mov r8, r0
+; V8M-NEXT:    mov r9, r0
+; V8M-NEXT:    mov r10, r0
+; V8M-NEXT:    mov r11, r0
+; V8M-NEXT:    mov r12, r0
+; V8M-NEXT:    msr apsr_nzcvq, r0
+; V8M-NEXT:    blxns r0
+; V8M-NEXT:    vlldm sp
+; V8M-NEXT:    add sp, #136
+; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    uxth r0, r0
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    pop {r7, pc}
+;
+; V81M-LABEL: access_u16:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    push {r7, lr}
+; V81M-NEXT:    movw r0, :lower16:get_idx
+; V81M-NEXT:    movt r0, :upper16:get_idx
+; V81M-NEXT:    ldr r0, [r0]
+; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    bic r0, r0, #1
+; V81M-NEXT:    sub sp, #136
+; V81M-NEXT:    vlstm sp
+; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-NEXT:    blxns r0
+; V81M-NEXT:    vlldm sp
+; V81M-NEXT:    add sp, #136
+; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    uxth r0, r0
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    pop {r7, pc}
+entry:
+  %0 = load ptr, ptr @get_idx, align 4
+  %call = tail call zeroext i16 %0() "cmse_nonsecure_call"
+  %idxprom = zext i16 %call to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %1 = load i32, ptr %arrayidx, align 4
+  ret i32 %1
+}
+
+define i32 @access_i8() {
+; V8M-LABEL: access_i8:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    push {r7, lr}
+; V8M-NEXT:    movw r0, :lower16:get_idx
+; V8M-NEXT:    movt r0, :upper16:get_idx
+; V8M-NEXT:    ldr r0, [r0]
+; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    bic r0, r0, #1
+; V8M-NEXT:    sub sp, #136
+; V8M-NEXT:    vlstm sp
+; V8M-NEXT:    mov r1, r0
+; V8M-NEXT:    mov r2, r0
+; V8M-NEXT:    mov r3, r0
+; V8M-NEXT:    mov r4, r0
+; V8M-NEXT:    mov r5, r0
+; V8M-NEXT:    mov r6, r0
+; V8M-NEXT:    mov r7, r0
+; V8M-NEXT:    mov r8, r0
+; V8M-NEXT:    mov r9, r0
+; V8M-NEXT:    mov r10, r0
+; V8M-NEXT:    mov r11, r0
+; V8M-NEXT:    mov r12, r0
+; V8M-NEXT:    msr apsr_nzcvq, r0
+; V8M-NEXT:    blxns r0
+; V8M-NEXT:    vlldm sp
+; V8M-NEXT:    add sp, #136
+; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    sxtb r0, r0
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    pop {r7, pc}
+;
+; V81M-LABEL: access_i8:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    push {r7, lr}
+; V81M-NEXT:    movw r0, :lower16:get_idx
+; V81M-NEXT:    movt r0, :upper16:get_idx
+; V81M-NEXT:    ldr r0, [r0]
+; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    bic r0, r0, #1
+; V81M-NEXT:    sub sp, #136
+; V81M-NEXT:    vlstm sp
+; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-NEXT:    blxns r0
+; V81M-NEXT:    vlldm sp
+; V81M-NEXT:    add sp, #136
+; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    sxtb r0, r0
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    pop {r7, pc}
+entry:
+  %0 = load ptr, ptr @get_idx, align 4
+  %call = tail call signext i8 %0() "cmse_nonsecure_call"
+  %idxprom = sext i8 %call to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %1 = load i32, ptr %arrayidx, align 4
+  ret i32 %1
+}
+
+define i32 @access_u8() {
+; V8M-LABEL: access_u8:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    push {r7, lr}
+; V8M-NEXT:    movw r0, :lower16:get_idx
+; V8M-NEXT:    movt r0, :upper16:get_idx
+; V8M-NEXT:    ldr r0, [r0]
+; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    bic r0, r0, #1
+; V8M-NEXT:    sub sp, #136
+; V8M-NEXT:    vlstm sp
+; V8M-NEXT:    mov r1, r0
+; V8M-NEXT:    mov r2, r0
+; V8M-NEXT:    mov r3, r0
+; V8M-NEXT:    mov r4, r0
+; V8M-NEXT:    mov r5, r0
+; V8M-NEXT:    mov r6, r0
+; V8M-NEXT:    mov r7, r0
+; V8M-NEXT:    mov r8, r0
+; V8M-NEXT:    mov r9, r0
+; V8M-NEXT:    mov r10, r0
+; V8M-NEXT:    mov r11, r0
+; V8M-NEXT:    mov r12, r0
+; V8M-NEXT:    msr apsr_nzcvq, r0
+; V8M-NEXT:    blxns r0
+; V8M-NEXT:    vlldm sp
+; V8M-NEXT:    add sp, #136
+; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    uxtb r0, r0
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    pop {r7, pc}
+;
+; V81M-LABEL: access_u8:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    push {r7, lr}
+; V81M-NEXT:    movw r0, :lower16:get_idx
+; V81M-NEXT:    movt r0, :upper16:get_idx
+; V81M-NEXT:    ldr r0, [r0]
+; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    bic r0, r0, #1
+; V81M-NEXT:    sub sp, #136
+; V81M-NEXT:    vlstm sp
+; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-NEXT:    blxns r0
+; V81M-NEXT:    vlldm sp
+; V81M-NEXT:    add sp, #136
+; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    uxtb r0, r0
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    pop {r7, pc}
+entry:
+  %0 = load ptr, ptr @get_idx, align 4
+  %call = tail call zeroext i8 %0() "cmse_nonsecure_call"
+  %idxprom = zext i8 %call to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %1 = load i32, ptr %arrayidx, align 4
+  ret i32 %1
+}
+
+define i32 @access_i1() {
+; V8M-LABEL: access_i1:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    push {r7, lr}
+; V8M-NEXT:    movw r0, :lower16:get_idx
+; V8M-NEXT:    movt r0, :upper16:get_idx
+; V8M-NEXT:    ldr r0, [r0]
+; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    bic r0, r0, #1
+; V8M-NEXT:    sub sp, #136
+; V8M-NEXT:    vlstm sp
+; V8M-NEXT:    mov r1, r0
+; V8M-NEXT:    mov r2, r0
+; V8M-NEXT:    mov r3, r0
+; V8M-NEXT:    mov r4, r0
+; V8M-NEXT:    mov r5, r0
+; V8M-NEXT:    mov r6, r0
+; V8M-NEXT:    mov r7, r0
+; V8M-NEXT:    mov r8, r0
+; V8M-NEXT:    mov r9, r0
+; V8M-NEXT:    mov r10, r0
+; V8M-NEXT:    mov r11, r0
+; V8M-NEXT:    mov r12, r0
+; V8M-NEXT:    msr apsr_nzcvq, r0
+; V8M-NEXT:    blxns r0
+; V8M-NEXT:    vlldm sp
+; V8M-NEXT:    add sp, #136
+; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    and r0, r0, #1
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    pop {r7, pc}
+;
+; V81M-LABEL: access_i1:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    push {r7, lr}
+; V81M-NEXT:    movw r0, :lower16:get_idx
+; V81M-NEXT:    movt r0, :upper16:get_idx
+; V81M-NEXT:    ldr r0, [r0]
+; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    bic r0, r0, #1
+; V81M-NEXT:    sub sp, #136
+; V81M-NEXT:    vlstm sp
+; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-NEXT:    blxns r0
+; V81M-NEXT:    vlldm sp
+; V81M-NEXT:    add sp, #136
+; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    and r0, r0, #1
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    pop {r7, pc}
+entry:
+  %0 = load ptr, ptr @get_idx, align 4
+  %call = tail call zeroext i1 %0() "cmse_nonsecure_call"
+  %idxprom = zext i1 %call to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %1 = load i32, ptr %arrayidx, align 4
+  ret i32 %1
+}
+
+define i32 @access_i5() {
+; V8M-LABEL: access_i5:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    push {r7, lr}
+; V8M-NEXT:    movw r0, :lower16:get_idx
+; V8M-NEXT:    movt r0, :upper16:get_idx
+; V8M-NEXT:    ldr r0, [r0]
+; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    bic r0, r0, #1
+; V8M-NEXT:    sub sp, #136
+; V8M-NEXT:    vlstm sp
+; V8M-NEXT:    mov r1, r0
+; V8M-NEXT:    mov r2, r0
+; V8M-NEXT:    mov r3, r0
+; V8M-NEXT:    mov r4, r0
+; V8M-NEXT:    mov r5, r0
+; V8M-NEXT:    mov r6, r0
+; V8M-NEXT:    mov r7, r0
+; V8M-NEXT:    mov r8, r0
+; V8M-NEXT:    mov r9, r0
+; V8M-NEXT:    mov r10, r0
+; V8M-NEXT:    mov r11, r0
+; V8M-NEXT:    mov r12, r0
+; V8M-NEXT:    msr apsr_nzcvq, r0
+; V8M-NEXT:    blxns r0
+; V8M-NEXT:    vlldm sp
+; V8M-NEXT:    add sp, #136
+; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    sbfx r0, r0, #0, #5
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    pop {r7, pc}
+;
+; V81M-LABEL: access_i5:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    push {r7, lr}
+; V81M-NEXT:    movw r0, :lower16:get_idx
+; V81M-NEXT:    movt r0, :upper16:get_idx
+; V81M-NEXT:    ldr r0, [r0]
+; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    bic r0, r0, #1
+; V81M-NEXT:    sub sp, #136
+; V81M-NEXT:    vlstm sp
+; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-NEXT:    blxns r0
+; V81M-NEXT:    vlldm sp
+; V81M-NEXT:    add sp, #136
+; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    sbfx r0, r0, #0, #5
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    pop {r7, pc}
+entry:
+  %0 = load ptr, ptr @get_idx, align 4
+  %call = tail call signext i5 %0() "cmse_nonsecure_call"
+  %idxprom = sext i5 %call to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %1 = load i32, ptr %arrayidx, align 4
+  ret i32 %1
+}
+
+define i32 @access_u5() {
+; V8M-LABEL: access_u5:
+; V8M:       @ %bb.0: @ %entry
+; V8M-NEXT:    push {r7, lr}
+; V8M-NEXT:    movw r0, :lower16:get_idx
+; V8M-NEXT:    movt r0, :upper16:get_idx
+; V8M-NEXT:    ldr r0, [r0]
+; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    bic r0, r0, #1
+; V8M-NEXT:    sub sp, #136
+; V8M-NEXT:    vlstm sp
+; V8M-NEXT:    mov r1, r0
+; V8M-NEXT:    mov r2, r0
+; V8M-NEXT:    mov r3, r0
+; V8M-NEXT:    mov r4, r0
+; V8M-NEXT:    mov r5, r0
+; V8M-NEXT:    mov r6, r0
+; V8M-NEXT:    mov r7, r0
+; V8M-NEXT:    mov r8, r0
+; V8M-NEXT:    mov r9, r0
+; V8M-NEXT:    mov r10, r0
+; V8M-NEXT:    mov r11, r0
+; V8M-NEXT:    mov r12, r0
+; V8M-NEXT:    msr apsr_nzcvq, r0
+; V8M-NEXT:    blxns r0
+; V8M-NEXT:    vlldm sp
+; V8M-NEXT:    add sp, #136
+; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-NEXT:    movw r1, :lower16:arr
+; V8M-NEXT:    and r0, r0, #31
+; V8M-NEXT:    movt r1, :upper16:arr
+; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-NEXT:    pop {r7, pc}
+;
+; V81M-LABEL: access_u5:
+; V81M:       @ %bb.0: @ %entry
+; V81M-NEXT:    push {r7, lr}
+; V81M-NEXT:    movw r0, :lower16:get_idx
+; V81M-NEXT:    movt r0, :upper16:get_idx
+; V81M-NEXT:    ldr r0, [r0]
+; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    bic r0, r0, #1
+; V81M-NEXT:    sub sp, #136
+; V81M-NEXT:    vlstm sp
+; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-NEXT:    blxns r0
+; V81M-NEXT:    vlldm sp
+; V81M-NEXT:    add sp, #136
+; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-NEXT:    movw r1, :lower16:arr
+; V81M-NEXT:    and r0, r0, #31
+; V81M-NEXT:    movt r1, :upper16:arr
+; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-NEXT:    pop {r7, pc}
+entry:
+  %0 = load ptr, ptr @get_idx, align 4
+  %call = tail call zeroext i5 %0() "cmse_nonsecure_call"
+  %idxprom = zext i5 %call to i32
+  %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
+  %1 = load i32, ptr %arrayidx, align 4
+  ret i32 %1
+}

>From 61855b7793202953de384dbada76e34ed0519725 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Mon, 20 May 2024 09:20:46 +0100
Subject: [PATCH 3/4] Amend to CMSE security mitigation

 - In this particular flow, the register's ValueType is always i32.
   Replace the variable by the constant.
 - Add tests to cover cases where arguments and return types are greater
   than 32 bits.
---
 llvm/lib/Target/ARM/ARMISelLowering.cpp       |  16 +-
 .../ARM/cmse-harden-call-returned-values.ll   | 841 ++++++++++--------
 .../ARM/cmse-harden-entry-arguments.ll        | 473 ++++++----
 3 files changed, 783 insertions(+), 547 deletions(-)

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index f1594071cdfe5..e50cacddeedd3 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -157,13 +157,13 @@ static const MCPhysReg GPRArgRegs[] = {
 };
 
 static SDValue handleCMSEValue(const SDValue &Value, const ISD::InputArg &Arg,
-                               SelectionDAG &DAG, const SDLoc &DL, EVT RegVT) {
-  assert(Arg.ArgVT.isScalarInteger() && RegVT.isScalarInteger());
-  assert(Arg.ArgVT.bitsLT(RegVT));
+                               SelectionDAG &DAG, const SDLoc &DL) {
+  assert(Arg.ArgVT.isScalarInteger());
+  assert(Arg.ArgVT.bitsLT(MVT::i32));
   SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, Arg.ArgVT, Value);
   SDValue Ext =
       DAG.getNode(Arg.Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, DL,
-                  RegVT, Trunc);
+                  MVT::i32, Trunc);
   return Ext;
 }
 
@@ -2291,8 +2291,8 @@ SDValue ARMTargetLowering::LowerCallResult(
     // callee, the latter cannot be trusted to follow the rules of the ABI.
     const ISD::InputArg &Arg = Ins[VA.getValNo()];
     if (isCmseNSCall && Arg.ArgVT.isScalarInteger() &&
-        VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(VA.getLocVT()))
-      Val = handleCMSEValue(Val, Arg, DAG, dl, VA.getLocVT());
+        VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
+      Val = handleCMSEValue(Val, Arg, DAG, dl);
 
     InVals.push_back(Val);
   }
@@ -4642,8 +4642,8 @@ SDValue ARMTargetLowering::LowerFormalArguments(
       // caller, the latter cannot be trusted to follow the rules of the ABI.
       const ISD::InputArg &Arg = Ins[VA.getValNo()];
       if (AFI->isCmseNSEntryFunction() && Arg.ArgVT.isScalarInteger() &&
-          RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(RegVT))
-        ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl, RegVT);
+          RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
+        ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl);
 
       InVals.push_back(ArgValue);
     } else { // VA.isRegLoc()
diff --git a/llvm/test/CodeGen/ARM/cmse-harden-call-returned-values.ll b/llvm/test/CodeGen/ARM/cmse-harden-call-returned-values.ll
index 75f067adbf115..58eef443c25e6 100644
--- a/llvm/test/CodeGen/ARM/cmse-harden-call-returned-values.ll
+++ b/llvm/test/CodeGen/ARM/cmse-harden-call-returned-values.ll
@@ -1,66 +1,65 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
-; RUN: llc %s -mtriple=thumbv8m.main     -o - | FileCheck %s --check-prefix V8M
-; RUN: llc %s -mtriple=thumbebv8m.main   -o - | FileCheck %s --check-prefix V8M
-; RUN: llc %s -mtriple=thumbv8.1m.main   -o - | FileCheck %s --check-prefix V81M
-; RUN: llc %s -mtriple=thumbebv8.1m.main -o - | FileCheck %s --check-prefix V81M
+; RUN: llc %s -mtriple=thumbv8m.main     -o - | FileCheck %s --check-prefixes V8M-COMMON,V8M-LE
+; RUN: llc %s -mtriple=thumbebv8m.main   -o - | FileCheck %s --check-prefixes V8M-COMMON,V8M-BE
+; RUN: llc %s -mtriple=thumbv8.1m.main   -o - | FileCheck %s --check-prefixes V81M-COMMON,V81M-LE
+; RUN: llc %s -mtriple=thumbebv8.1m.main -o - | FileCheck %s --check-prefixes V81M-COMMON,V81M-BE
 
 @get_idx = hidden local_unnamed_addr global ptr null, align 4
 @arr = hidden local_unnamed_addr global [256 x i32] zeroinitializer, align 4
 
 define i32 @access_i16() {
-; V8M-LABEL: access_i16:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    push {r7, lr}
-; V8M-NEXT:    movw r0, :lower16:get_idx
-; V8M-NEXT:    movt r0, :upper16:get_idx
-; V8M-NEXT:    ldr r0, [r0]
-; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    bic r0, r0, #1
-; V8M-NEXT:    sub sp, #136
-; V8M-NEXT:    vlstm sp
-; V8M-NEXT:    mov r1, r0
-; V8M-NEXT:    mov r2, r0
-; V8M-NEXT:    mov r3, r0
-; V8M-NEXT:    mov r4, r0
-; V8M-NEXT:    mov r5, r0
-; V8M-NEXT:    mov r6, r0
-; V8M-NEXT:    mov r7, r0
-; V8M-NEXT:    mov r8, r0
-; V8M-NEXT:    mov r9, r0
-; V8M-NEXT:    mov r10, r0
-; V8M-NEXT:    mov r11, r0
-; V8M-NEXT:    mov r12, r0
-; V8M-NEXT:    msr apsr_nzcvq, r0
-; V8M-NEXT:    blxns r0
-; V8M-NEXT:    vlldm sp
-; V8M-NEXT:    add sp, #136
-; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    sxth r0, r0
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    pop {r7, pc}
+; V8M-COMMON-LABEL: access_i16:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    push {r7, lr}
+; V8M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V8M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V8M-COMMON-NEXT:    ldr r0, [r0]
+; V8M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    bic r0, r0, #1
+; V8M-COMMON-NEXT:    sub sp, #136
+; V8M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    mov r1, r0
+; V8M-COMMON-NEXT:    mov r2, r0
+; V8M-COMMON-NEXT:    mov r3, r0
+; V8M-COMMON-NEXT:    mov r4, r0
+; V8M-COMMON-NEXT:    mov r5, r0
+; V8M-COMMON-NEXT:    mov r6, r0
+; V8M-COMMON-NEXT:    mov r7, r0
+; V8M-COMMON-NEXT:    mov r8, r0
+; V8M-COMMON-NEXT:    mov r9, r0
+; V8M-COMMON-NEXT:    mov r10, r0
+; V8M-COMMON-NEXT:    mov r11, r0
+; V8M-COMMON-NEXT:    mov r12, r0
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, r0
+; V8M-COMMON-NEXT:    blxns r0
+; V8M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    add sp, #136
+; V8M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    sxth r0, r0
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    pop {r7, pc}
 ;
-; V81M-LABEL: access_i16:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    push {r7, lr}
-; V81M-NEXT:    movw r0, :lower16:get_idx
-; V81M-NEXT:    movt r0, :upper16:get_idx
-; V81M-NEXT:    ldr r0, [r0]
-; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    bic r0, r0, #1
-; V81M-NEXT:    sub sp, #136
-; V81M-NEXT:    vlstm sp
-; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
-; V81M-NEXT:    blxns r0
-; V81M-NEXT:    vlldm sp
-; V81M-NEXT:    add sp, #136
-; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    sxth r0, r0
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    pop {r7, pc}
+; V81M-COMMON-LABEL: access_i16:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    push {r7, lr}
+; V81M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V81M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V81M-COMMON-NEXT:    ldr r0, [r0]
+; V81M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    bic r0, r0, #1
+; V81M-COMMON-NEXT:    sub sp, #136
+; V81M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-COMMON-NEXT:    blxns r0
+; V81M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    add sp, #136
+; V81M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    sxth r0, r0
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    pop {r7, pc}
 entry:
   %0 = load ptr, ptr @get_idx, align 4
   %call = tail call signext i16 %0() "cmse_nonsecure_call"
@@ -71,59 +70,59 @@ entry:
 }
 
 define i32 @access_u16() {
-; V8M-LABEL: access_u16:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    push {r7, lr}
-; V8M-NEXT:    movw r0, :lower16:get_idx
-; V8M-NEXT:    movt r0, :upper16:get_idx
-; V8M-NEXT:    ldr r0, [r0]
-; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    bic r0, r0, #1
-; V8M-NEXT:    sub sp, #136
-; V8M-NEXT:    vlstm sp
-; V8M-NEXT:    mov r1, r0
-; V8M-NEXT:    mov r2, r0
-; V8M-NEXT:    mov r3, r0
-; V8M-NEXT:    mov r4, r0
-; V8M-NEXT:    mov r5, r0
-; V8M-NEXT:    mov r6, r0
-; V8M-NEXT:    mov r7, r0
-; V8M-NEXT:    mov r8, r0
-; V8M-NEXT:    mov r9, r0
-; V8M-NEXT:    mov r10, r0
-; V8M-NEXT:    mov r11, r0
-; V8M-NEXT:    mov r12, r0
-; V8M-NEXT:    msr apsr_nzcvq, r0
-; V8M-NEXT:    blxns r0
-; V8M-NEXT:    vlldm sp
-; V8M-NEXT:    add sp, #136
-; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    uxth r0, r0
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    pop {r7, pc}
+; V8M-COMMON-LABEL: access_u16:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    push {r7, lr}
+; V8M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V8M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V8M-COMMON-NEXT:    ldr r0, [r0]
+; V8M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    bic r0, r0, #1
+; V8M-COMMON-NEXT:    sub sp, #136
+; V8M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    mov r1, r0
+; V8M-COMMON-NEXT:    mov r2, r0
+; V8M-COMMON-NEXT:    mov r3, r0
+; V8M-COMMON-NEXT:    mov r4, r0
+; V8M-COMMON-NEXT:    mov r5, r0
+; V8M-COMMON-NEXT:    mov r6, r0
+; V8M-COMMON-NEXT:    mov r7, r0
+; V8M-COMMON-NEXT:    mov r8, r0
+; V8M-COMMON-NEXT:    mov r9, r0
+; V8M-COMMON-NEXT:    mov r10, r0
+; V8M-COMMON-NEXT:    mov r11, r0
+; V8M-COMMON-NEXT:    mov r12, r0
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, r0
+; V8M-COMMON-NEXT:    blxns r0
+; V8M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    add sp, #136
+; V8M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    uxth r0, r0
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    pop {r7, pc}
 ;
-; V81M-LABEL: access_u16:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    push {r7, lr}
-; V81M-NEXT:    movw r0, :lower16:get_idx
-; V81M-NEXT:    movt r0, :upper16:get_idx
-; V81M-NEXT:    ldr r0, [r0]
-; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    bic r0, r0, #1
-; V81M-NEXT:    sub sp, #136
-; V81M-NEXT:    vlstm sp
-; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
-; V81M-NEXT:    blxns r0
-; V81M-NEXT:    vlldm sp
-; V81M-NEXT:    add sp, #136
-; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    uxth r0, r0
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    pop {r7, pc}
+; V81M-COMMON-LABEL: access_u16:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    push {r7, lr}
+; V81M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V81M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V81M-COMMON-NEXT:    ldr r0, [r0]
+; V81M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    bic r0, r0, #1
+; V81M-COMMON-NEXT:    sub sp, #136
+; V81M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-COMMON-NEXT:    blxns r0
+; V81M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    add sp, #136
+; V81M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    uxth r0, r0
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    pop {r7, pc}
 entry:
   %0 = load ptr, ptr @get_idx, align 4
   %call = tail call zeroext i16 %0() "cmse_nonsecure_call"
@@ -134,59 +133,59 @@ entry:
 }
 
 define i32 @access_i8() {
-; V8M-LABEL: access_i8:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    push {r7, lr}
-; V8M-NEXT:    movw r0, :lower16:get_idx
-; V8M-NEXT:    movt r0, :upper16:get_idx
-; V8M-NEXT:    ldr r0, [r0]
-; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    bic r0, r0, #1
-; V8M-NEXT:    sub sp, #136
-; V8M-NEXT:    vlstm sp
-; V8M-NEXT:    mov r1, r0
-; V8M-NEXT:    mov r2, r0
-; V8M-NEXT:    mov r3, r0
-; V8M-NEXT:    mov r4, r0
-; V8M-NEXT:    mov r5, r0
-; V8M-NEXT:    mov r6, r0
-; V8M-NEXT:    mov r7, r0
-; V8M-NEXT:    mov r8, r0
-; V8M-NEXT:    mov r9, r0
-; V8M-NEXT:    mov r10, r0
-; V8M-NEXT:    mov r11, r0
-; V8M-NEXT:    mov r12, r0
-; V8M-NEXT:    msr apsr_nzcvq, r0
-; V8M-NEXT:    blxns r0
-; V8M-NEXT:    vlldm sp
-; V8M-NEXT:    add sp, #136
-; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    sxtb r0, r0
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    pop {r7, pc}
+; V8M-COMMON-LABEL: access_i8:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    push {r7, lr}
+; V8M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V8M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V8M-COMMON-NEXT:    ldr r0, [r0]
+; V8M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    bic r0, r0, #1
+; V8M-COMMON-NEXT:    sub sp, #136
+; V8M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    mov r1, r0
+; V8M-COMMON-NEXT:    mov r2, r0
+; V8M-COMMON-NEXT:    mov r3, r0
+; V8M-COMMON-NEXT:    mov r4, r0
+; V8M-COMMON-NEXT:    mov r5, r0
+; V8M-COMMON-NEXT:    mov r6, r0
+; V8M-COMMON-NEXT:    mov r7, r0
+; V8M-COMMON-NEXT:    mov r8, r0
+; V8M-COMMON-NEXT:    mov r9, r0
+; V8M-COMMON-NEXT:    mov r10, r0
+; V8M-COMMON-NEXT:    mov r11, r0
+; V8M-COMMON-NEXT:    mov r12, r0
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, r0
+; V8M-COMMON-NEXT:    blxns r0
+; V8M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    add sp, #136
+; V8M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    sxtb r0, r0
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    pop {r7, pc}
 ;
-; V81M-LABEL: access_i8:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    push {r7, lr}
-; V81M-NEXT:    movw r0, :lower16:get_idx
-; V81M-NEXT:    movt r0, :upper16:get_idx
-; V81M-NEXT:    ldr r0, [r0]
-; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    bic r0, r0, #1
-; V81M-NEXT:    sub sp, #136
-; V81M-NEXT:    vlstm sp
-; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
-; V81M-NEXT:    blxns r0
-; V81M-NEXT:    vlldm sp
-; V81M-NEXT:    add sp, #136
-; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    sxtb r0, r0
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    pop {r7, pc}
+; V81M-COMMON-LABEL: access_i8:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    push {r7, lr}
+; V81M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V81M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V81M-COMMON-NEXT:    ldr r0, [r0]
+; V81M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    bic r0, r0, #1
+; V81M-COMMON-NEXT:    sub sp, #136
+; V81M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-COMMON-NEXT:    blxns r0
+; V81M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    add sp, #136
+; V81M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    sxtb r0, r0
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    pop {r7, pc}
 entry:
   %0 = load ptr, ptr @get_idx, align 4
   %call = tail call signext i8 %0() "cmse_nonsecure_call"
@@ -197,59 +196,59 @@ entry:
 }
 
 define i32 @access_u8() {
-; V8M-LABEL: access_u8:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    push {r7, lr}
-; V8M-NEXT:    movw r0, :lower16:get_idx
-; V8M-NEXT:    movt r0, :upper16:get_idx
-; V8M-NEXT:    ldr r0, [r0]
-; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    bic r0, r0, #1
-; V8M-NEXT:    sub sp, #136
-; V8M-NEXT:    vlstm sp
-; V8M-NEXT:    mov r1, r0
-; V8M-NEXT:    mov r2, r0
-; V8M-NEXT:    mov r3, r0
-; V8M-NEXT:    mov r4, r0
-; V8M-NEXT:    mov r5, r0
-; V8M-NEXT:    mov r6, r0
-; V8M-NEXT:    mov r7, r0
-; V8M-NEXT:    mov r8, r0
-; V8M-NEXT:    mov r9, r0
-; V8M-NEXT:    mov r10, r0
-; V8M-NEXT:    mov r11, r0
-; V8M-NEXT:    mov r12, r0
-; V8M-NEXT:    msr apsr_nzcvq, r0
-; V8M-NEXT:    blxns r0
-; V8M-NEXT:    vlldm sp
-; V8M-NEXT:    add sp, #136
-; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    uxtb r0, r0
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    pop {r7, pc}
+; V8M-COMMON-LABEL: access_u8:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    push {r7, lr}
+; V8M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V8M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V8M-COMMON-NEXT:    ldr r0, [r0]
+; V8M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    bic r0, r0, #1
+; V8M-COMMON-NEXT:    sub sp, #136
+; V8M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    mov r1, r0
+; V8M-COMMON-NEXT:    mov r2, r0
+; V8M-COMMON-NEXT:    mov r3, r0
+; V8M-COMMON-NEXT:    mov r4, r0
+; V8M-COMMON-NEXT:    mov r5, r0
+; V8M-COMMON-NEXT:    mov r6, r0
+; V8M-COMMON-NEXT:    mov r7, r0
+; V8M-COMMON-NEXT:    mov r8, r0
+; V8M-COMMON-NEXT:    mov r9, r0
+; V8M-COMMON-NEXT:    mov r10, r0
+; V8M-COMMON-NEXT:    mov r11, r0
+; V8M-COMMON-NEXT:    mov r12, r0
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, r0
+; V8M-COMMON-NEXT:    blxns r0
+; V8M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    add sp, #136
+; V8M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    uxtb r0, r0
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    pop {r7, pc}
 ;
-; V81M-LABEL: access_u8:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    push {r7, lr}
-; V81M-NEXT:    movw r0, :lower16:get_idx
-; V81M-NEXT:    movt r0, :upper16:get_idx
-; V81M-NEXT:    ldr r0, [r0]
-; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    bic r0, r0, #1
-; V81M-NEXT:    sub sp, #136
-; V81M-NEXT:    vlstm sp
-; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
-; V81M-NEXT:    blxns r0
-; V81M-NEXT:    vlldm sp
-; V81M-NEXT:    add sp, #136
-; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    uxtb r0, r0
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    pop {r7, pc}
+; V81M-COMMON-LABEL: access_u8:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    push {r7, lr}
+; V81M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V81M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V81M-COMMON-NEXT:    ldr r0, [r0]
+; V81M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    bic r0, r0, #1
+; V81M-COMMON-NEXT:    sub sp, #136
+; V81M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-COMMON-NEXT:    blxns r0
+; V81M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    add sp, #136
+; V81M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    uxtb r0, r0
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    pop {r7, pc}
 entry:
   %0 = load ptr, ptr @get_idx, align 4
   %call = tail call zeroext i8 %0() "cmse_nonsecure_call"
@@ -260,59 +259,59 @@ entry:
 }
 
 define i32 @access_i1() {
-; V8M-LABEL: access_i1:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    push {r7, lr}
-; V8M-NEXT:    movw r0, :lower16:get_idx
-; V8M-NEXT:    movt r0, :upper16:get_idx
-; V8M-NEXT:    ldr r0, [r0]
-; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    bic r0, r0, #1
-; V8M-NEXT:    sub sp, #136
-; V8M-NEXT:    vlstm sp
-; V8M-NEXT:    mov r1, r0
-; V8M-NEXT:    mov r2, r0
-; V8M-NEXT:    mov r3, r0
-; V8M-NEXT:    mov r4, r0
-; V8M-NEXT:    mov r5, r0
-; V8M-NEXT:    mov r6, r0
-; V8M-NEXT:    mov r7, r0
-; V8M-NEXT:    mov r8, r0
-; V8M-NEXT:    mov r9, r0
-; V8M-NEXT:    mov r10, r0
-; V8M-NEXT:    mov r11, r0
-; V8M-NEXT:    mov r12, r0
-; V8M-NEXT:    msr apsr_nzcvq, r0
-; V8M-NEXT:    blxns r0
-; V8M-NEXT:    vlldm sp
-; V8M-NEXT:    add sp, #136
-; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    and r0, r0, #1
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    pop {r7, pc}
+; V8M-COMMON-LABEL: access_i1:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    push {r7, lr}
+; V8M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V8M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V8M-COMMON-NEXT:    ldr r0, [r0]
+; V8M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    bic r0, r0, #1
+; V8M-COMMON-NEXT:    sub sp, #136
+; V8M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    mov r1, r0
+; V8M-COMMON-NEXT:    mov r2, r0
+; V8M-COMMON-NEXT:    mov r3, r0
+; V8M-COMMON-NEXT:    mov r4, r0
+; V8M-COMMON-NEXT:    mov r5, r0
+; V8M-COMMON-NEXT:    mov r6, r0
+; V8M-COMMON-NEXT:    mov r7, r0
+; V8M-COMMON-NEXT:    mov r8, r0
+; V8M-COMMON-NEXT:    mov r9, r0
+; V8M-COMMON-NEXT:    mov r10, r0
+; V8M-COMMON-NEXT:    mov r11, r0
+; V8M-COMMON-NEXT:    mov r12, r0
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, r0
+; V8M-COMMON-NEXT:    blxns r0
+; V8M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    add sp, #136
+; V8M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    and r0, r0, #1
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    pop {r7, pc}
 ;
-; V81M-LABEL: access_i1:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    push {r7, lr}
-; V81M-NEXT:    movw r0, :lower16:get_idx
-; V81M-NEXT:    movt r0, :upper16:get_idx
-; V81M-NEXT:    ldr r0, [r0]
-; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    bic r0, r0, #1
-; V81M-NEXT:    sub sp, #136
-; V81M-NEXT:    vlstm sp
-; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
-; V81M-NEXT:    blxns r0
-; V81M-NEXT:    vlldm sp
-; V81M-NEXT:    add sp, #136
-; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    and r0, r0, #1
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    pop {r7, pc}
+; V81M-COMMON-LABEL: access_i1:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    push {r7, lr}
+; V81M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V81M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V81M-COMMON-NEXT:    ldr r0, [r0]
+; V81M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    bic r0, r0, #1
+; V81M-COMMON-NEXT:    sub sp, #136
+; V81M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-COMMON-NEXT:    blxns r0
+; V81M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    add sp, #136
+; V81M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    and r0, r0, #1
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    pop {r7, pc}
 entry:
   %0 = load ptr, ptr @get_idx, align 4
   %call = tail call zeroext i1 %0() "cmse_nonsecure_call"
@@ -323,59 +322,59 @@ entry:
 }
 
 define i32 @access_i5() {
-; V8M-LABEL: access_i5:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    push {r7, lr}
-; V8M-NEXT:    movw r0, :lower16:get_idx
-; V8M-NEXT:    movt r0, :upper16:get_idx
-; V8M-NEXT:    ldr r0, [r0]
-; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    bic r0, r0, #1
-; V8M-NEXT:    sub sp, #136
-; V8M-NEXT:    vlstm sp
-; V8M-NEXT:    mov r1, r0
-; V8M-NEXT:    mov r2, r0
-; V8M-NEXT:    mov r3, r0
-; V8M-NEXT:    mov r4, r0
-; V8M-NEXT:    mov r5, r0
-; V8M-NEXT:    mov r6, r0
-; V8M-NEXT:    mov r7, r0
-; V8M-NEXT:    mov r8, r0
-; V8M-NEXT:    mov r9, r0
-; V8M-NEXT:    mov r10, r0
-; V8M-NEXT:    mov r11, r0
-; V8M-NEXT:    mov r12, r0
-; V8M-NEXT:    msr apsr_nzcvq, r0
-; V8M-NEXT:    blxns r0
-; V8M-NEXT:    vlldm sp
-; V8M-NEXT:    add sp, #136
-; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    sbfx r0, r0, #0, #5
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    pop {r7, pc}
+; V8M-COMMON-LABEL: access_i5:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    push {r7, lr}
+; V8M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V8M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V8M-COMMON-NEXT:    ldr r0, [r0]
+; V8M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    bic r0, r0, #1
+; V8M-COMMON-NEXT:    sub sp, #136
+; V8M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    mov r1, r0
+; V8M-COMMON-NEXT:    mov r2, r0
+; V8M-COMMON-NEXT:    mov r3, r0
+; V8M-COMMON-NEXT:    mov r4, r0
+; V8M-COMMON-NEXT:    mov r5, r0
+; V8M-COMMON-NEXT:    mov r6, r0
+; V8M-COMMON-NEXT:    mov r7, r0
+; V8M-COMMON-NEXT:    mov r8, r0
+; V8M-COMMON-NEXT:    mov r9, r0
+; V8M-COMMON-NEXT:    mov r10, r0
+; V8M-COMMON-NEXT:    mov r11, r0
+; V8M-COMMON-NEXT:    mov r12, r0
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, r0
+; V8M-COMMON-NEXT:    blxns r0
+; V8M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    add sp, #136
+; V8M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    sbfx r0, r0, #0, #5
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    pop {r7, pc}
 ;
-; V81M-LABEL: access_i5:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    push {r7, lr}
-; V81M-NEXT:    movw r0, :lower16:get_idx
-; V81M-NEXT:    movt r0, :upper16:get_idx
-; V81M-NEXT:    ldr r0, [r0]
-; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    bic r0, r0, #1
-; V81M-NEXT:    sub sp, #136
-; V81M-NEXT:    vlstm sp
-; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
-; V81M-NEXT:    blxns r0
-; V81M-NEXT:    vlldm sp
-; V81M-NEXT:    add sp, #136
-; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    sbfx r0, r0, #0, #5
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    pop {r7, pc}
+; V81M-COMMON-LABEL: access_i5:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    push {r7, lr}
+; V81M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V81M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V81M-COMMON-NEXT:    ldr r0, [r0]
+; V81M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    bic r0, r0, #1
+; V81M-COMMON-NEXT:    sub sp, #136
+; V81M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-COMMON-NEXT:    blxns r0
+; V81M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    add sp, #136
+; V81M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    sbfx r0, r0, #0, #5
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    pop {r7, pc}
 entry:
   %0 = load ptr, ptr @get_idx, align 4
   %call = tail call signext i5 %0() "cmse_nonsecure_call"
@@ -386,59 +385,59 @@ entry:
 }
 
 define i32 @access_u5() {
-; V8M-LABEL: access_u5:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    push {r7, lr}
-; V8M-NEXT:    movw r0, :lower16:get_idx
-; V8M-NEXT:    movt r0, :upper16:get_idx
-; V8M-NEXT:    ldr r0, [r0]
-; V8M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    bic r0, r0, #1
-; V8M-NEXT:    sub sp, #136
-; V8M-NEXT:    vlstm sp
-; V8M-NEXT:    mov r1, r0
-; V8M-NEXT:    mov r2, r0
-; V8M-NEXT:    mov r3, r0
-; V8M-NEXT:    mov r4, r0
-; V8M-NEXT:    mov r5, r0
-; V8M-NEXT:    mov r6, r0
-; V8M-NEXT:    mov r7, r0
-; V8M-NEXT:    mov r8, r0
-; V8M-NEXT:    mov r9, r0
-; V8M-NEXT:    mov r10, r0
-; V8M-NEXT:    mov r11, r0
-; V8M-NEXT:    mov r12, r0
-; V8M-NEXT:    msr apsr_nzcvq, r0
-; V8M-NEXT:    blxns r0
-; V8M-NEXT:    vlldm sp
-; V8M-NEXT:    add sp, #136
-; V8M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    and r0, r0, #31
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    pop {r7, pc}
+; V8M-COMMON-LABEL: access_u5:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    push {r7, lr}
+; V8M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V8M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V8M-COMMON-NEXT:    ldr r0, [r0]
+; V8M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    bic r0, r0, #1
+; V8M-COMMON-NEXT:    sub sp, #136
+; V8M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    mov r1, r0
+; V8M-COMMON-NEXT:    mov r2, r0
+; V8M-COMMON-NEXT:    mov r3, r0
+; V8M-COMMON-NEXT:    mov r4, r0
+; V8M-COMMON-NEXT:    mov r5, r0
+; V8M-COMMON-NEXT:    mov r6, r0
+; V8M-COMMON-NEXT:    mov r7, r0
+; V8M-COMMON-NEXT:    mov r8, r0
+; V8M-COMMON-NEXT:    mov r9, r0
+; V8M-COMMON-NEXT:    mov r10, r0
+; V8M-COMMON-NEXT:    mov r11, r0
+; V8M-COMMON-NEXT:    mov r12, r0
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, r0
+; V8M-COMMON-NEXT:    blxns r0
+; V8M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    add sp, #136
+; V8M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    and r0, r0, #31
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    pop {r7, pc}
 ;
-; V81M-LABEL: access_u5:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    push {r7, lr}
-; V81M-NEXT:    movw r0, :lower16:get_idx
-; V81M-NEXT:    movt r0, :upper16:get_idx
-; V81M-NEXT:    ldr r0, [r0]
-; V81M-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    bic r0, r0, #1
-; V81M-NEXT:    sub sp, #136
-; V81M-NEXT:    vlstm sp
-; V81M-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
-; V81M-NEXT:    blxns r0
-; V81M-NEXT:    vlldm sp
-; V81M-NEXT:    add sp, #136
-; V81M-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    and r0, r0, #31
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    pop {r7, pc}
+; V81M-COMMON-LABEL: access_u5:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    push {r7, lr}
+; V81M-COMMON-NEXT:    movw r0, :lower16:get_idx
+; V81M-COMMON-NEXT:    movt r0, :upper16:get_idx
+; V81M-COMMON-NEXT:    ldr r0, [r0]
+; V81M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    bic r0, r0, #1
+; V81M-COMMON-NEXT:    sub sp, #136
+; V81M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-COMMON-NEXT:    blxns r0
+; V81M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    add sp, #136
+; V81M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    and r0, r0, #31
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    pop {r7, pc}
 entry:
   %0 = load ptr, ptr @get_idx, align 4
   %call = tail call zeroext i5 %0() "cmse_nonsecure_call"
@@ -447,3 +446,107 @@ entry:
   %1 = load i32, ptr %arrayidx, align 4
   ret i32 %1
 }
+
+define i32 @access_i33(ptr %f) {
+; V8M-COMMON-LABEL: access_i33:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    push {r7, lr}
+; V8M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    bic r0, r0, #1
+; V8M-COMMON-NEXT:    sub sp, #136
+; V8M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    mov r1, r0
+; V8M-COMMON-NEXT:    mov r2, r0
+; V8M-COMMON-NEXT:    mov r3, r0
+; V8M-COMMON-NEXT:    mov r4, r0
+; V8M-COMMON-NEXT:    mov r5, r0
+; V8M-COMMON-NEXT:    mov r6, r0
+; V8M-COMMON-NEXT:    mov r7, r0
+; V8M-COMMON-NEXT:    mov r8, r0
+; V8M-COMMON-NEXT:    mov r9, r0
+; V8M-COMMON-NEXT:    mov r10, r0
+; V8M-COMMON-NEXT:    mov r11, r0
+; V8M-COMMON-NEXT:    mov r12, r0
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, r0
+; V8M-COMMON-NEXT:    blxns r0
+; V8M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    add sp, #136
+; V8M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-LE-NEXT:        and r0, r1, #1
+; V8M-BE-NEXT:        and r0, r0, #1
+; V8M-COMMON-NEXT:    rsb.w r0, r0, #0
+; V8M-COMMON-NEXT:    pop {r7, pc}
+;
+; V81M-COMMON-LABEL: access_i33:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    push {r7, lr}
+; V81M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    bic r0, r0, #1
+; V81M-COMMON-NEXT:    sub sp, #136
+; V81M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-COMMON-NEXT:    blxns r0
+; V81M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    add sp, #136
+; V81M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-LE-NEXT:        and r0, r1, #1
+; V81M-BE-NEXT:        and r0, r0, #1
+; V81M-COMMON-NEXT:    rsb.w r0, r0, #0
+; V81M-COMMON-NEXT:    pop {r7, pc}
+entry:
+  %call = tail call i33 %f() "cmse_nonsecure_call"
+  %shr = ashr i33 %call, 32
+  %conv = trunc nsw i33 %shr to i32
+  ret i32 %conv
+}
+
+define i32 @access_u33(ptr %f) {
+; V8M-COMMON-LABEL: access_u33:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    push {r7, lr}
+; V8M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-COMMON-NEXT:    bic r0, r0, #1
+; V8M-COMMON-NEXT:    sub sp, #136
+; V8M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    mov r1, r0
+; V8M-COMMON-NEXT:    mov r2, r0
+; V8M-COMMON-NEXT:    mov r3, r0
+; V8M-COMMON-NEXT:    mov r4, r0
+; V8M-COMMON-NEXT:    mov r5, r0
+; V8M-COMMON-NEXT:    mov r6, r0
+; V8M-COMMON-NEXT:    mov r7, r0
+; V8M-COMMON-NEXT:    mov r8, r0
+; V8M-COMMON-NEXT:    mov r9, r0
+; V8M-COMMON-NEXT:    mov r10, r0
+; V8M-COMMON-NEXT:    mov r11, r0
+; V8M-COMMON-NEXT:    mov r12, r0
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, r0
+; V8M-COMMON-NEXT:    blxns r0
+; V8M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V8M-COMMON-NEXT:    add sp, #136
+; V8M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V8M-LE-NEXT:        and r0, r1, #1
+; V8M-BE-NEXT:        and r0, r0, #1
+; V8M-COMMON-NEXT:    pop {r7, pc}
+;
+; V81M-COMMON-LABEL: access_u33:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    push {r7, lr}
+; V81M-COMMON-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-COMMON-NEXT:    bic r0, r0, #1
+; V81M-COMMON-NEXT:    sub sp, #136
+; V81M-COMMON-NEXT:    vlstm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
+; V81M-COMMON-NEXT:    blxns r0
+; V81M-COMMON-NEXT:    vlldm sp, {d0 - d15}
+; V81M-COMMON-NEXT:    add sp, #136
+; V81M-COMMON-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
+; V81M-LE-NEXT:        and r0, r1, #1
+; V81M-BE-NEXT:        and r0, r0, #1
+; V81M-COMMON-NEXT:    pop {r7, pc}
+entry:
+  %call = tail call i33 %f() "cmse_nonsecure_call"
+  %shr = lshr i33 %call, 32
+  %conv = trunc nuw nsw i33 %shr to i32
+  ret i32 %conv
+}
diff --git a/llvm/test/CodeGen/ARM/cmse-harden-entry-arguments.ll b/llvm/test/CodeGen/ARM/cmse-harden-entry-arguments.ll
index dd0dd598e75ce..c66ab00566ddf 100644
--- a/llvm/test/CodeGen/ARM/cmse-harden-entry-arguments.ll
+++ b/llvm/test/CodeGen/ARM/cmse-harden-entry-arguments.ll
@@ -1,36 +1,35 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
-; RUN: llc %s -mtriple=thumbv8m.main     -o - | FileCheck %s --check-prefix V8M
-; RUN: llc %s -mtriple=thumbebv8m.main   -o - | FileCheck %s --check-prefix V8M
-; RUN: llc %s -mtriple=thumbv8.1m.main   -o - | FileCheck %s --check-prefix V81M
-; RUN: llc %s -mtriple=thumbebv8.1m.main -o - | FileCheck %s --check-prefix V81M
+; RUN: llc %s -mtriple=thumbv8m.main     -o - | FileCheck %s --check-prefixes V8M-COMMON,V8M-LE
+; RUN: llc %s -mtriple=thumbebv8m.main   -o - | FileCheck %s --check-prefixes V8M-COMMON,V8M-BE
+; RUN: llc %s -mtriple=thumbv8.1m.main   -o - | FileCheck %s --check-prefixes V81M-COMMON,V81M-LE
+; RUN: llc %s -mtriple=thumbebv8.1m.main -o - | FileCheck %s --check-prefixes V81M-COMMON,V81M-BE
 
 @arr = hidden local_unnamed_addr global [256 x i32] zeroinitializer, align 4
 
 define i32 @access_i16(i16 signext %idx) "cmse_nonsecure_entry" {
-; V8M-LABEL: access_i16:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    sxth r0, r0
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    mov r2, lr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    mov r1, lr
-; V8M-NEXT:    mov r3, lr
-; V8M-NEXT:    msr apsr_nzcvq, lr
-; V8M-NEXT:    mov r12, lr
-; V8M-NEXT:    bxns lr
+; V8M-COMMON-LABEL: access_i16:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    sxth r0, r0
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    bxns lr
 ;
-; V81M-LABEL: access_i16:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    sxth r0, r0
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
-; V81M-NEXT:    vldr fpcxtns, [sp], #4
-; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
-; V81M-NEXT:    bxns lr
+; V81M-COMMON-LABEL: access_i16:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    sxth r0, r0
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
 entry:
   %idxprom = sext i16 %idx to i32
   %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
@@ -39,30 +38,30 @@ entry:
 }
 
 define i32 @access_u16(i16 zeroext %idx) "cmse_nonsecure_entry" {
-; V8M-LABEL: access_u16:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    uxth r0, r0
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    mov r2, lr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    mov r1, lr
-; V8M-NEXT:    mov r3, lr
-; V8M-NEXT:    msr apsr_nzcvq, lr
-; V8M-NEXT:    mov r12, lr
-; V8M-NEXT:    bxns lr
+; V8M-COMMON-LABEL: access_u16:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    uxth r0, r0
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    bxns lr
 ;
-; V81M-LABEL: access_u16:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    uxth r0, r0
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
-; V81M-NEXT:    vldr fpcxtns, [sp], #4
-; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
-; V81M-NEXT:    bxns lr
+; V81M-COMMON-LABEL: access_u16:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    uxth r0, r0
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
 entry:
   %idxprom = zext i16 %idx to i32
   %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
@@ -71,30 +70,30 @@ entry:
 }
 
 define i32 @access_i8(i8 signext %idx) "cmse_nonsecure_entry" {
-; V8M-LABEL: access_i8:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    sxtb r0, r0
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    mov r2, lr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    mov r1, lr
-; V8M-NEXT:    mov r3, lr
-; V8M-NEXT:    msr apsr_nzcvq, lr
-; V8M-NEXT:    mov r12, lr
-; V8M-NEXT:    bxns lr
+; V8M-COMMON-LABEL: access_i8:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    sxtb r0, r0
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    bxns lr
 ;
-; V81M-LABEL: access_i8:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    sxtb r0, r0
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
-; V81M-NEXT:    vldr fpcxtns, [sp], #4
-; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
-; V81M-NEXT:    bxns lr
+; V81M-COMMON-LABEL: access_i8:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    sxtb r0, r0
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
 entry:
   %idxprom = sext i8 %idx to i32
   %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
@@ -103,30 +102,30 @@ entry:
 }
 
 define i32 @access_u8(i8 zeroext %idx) "cmse_nonsecure_entry" {
-; V8M-LABEL: access_u8:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    uxtb r0, r0
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    mov r2, lr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    mov r1, lr
-; V8M-NEXT:    mov r3, lr
-; V8M-NEXT:    msr apsr_nzcvq, lr
-; V8M-NEXT:    mov r12, lr
-; V8M-NEXT:    bxns lr
+; V8M-COMMON-LABEL: access_u8:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    uxtb r0, r0
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    bxns lr
 ;
-; V81M-LABEL: access_u8:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    uxtb r0, r0
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
-; V81M-NEXT:    vldr fpcxtns, [sp], #4
-; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
-; V81M-NEXT:    bxns lr
+; V81M-COMMON-LABEL: access_u8:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    uxtb r0, r0
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
 entry:
   %idxprom = zext i8 %idx to i32
   %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
@@ -135,34 +134,34 @@ entry:
 }
 
 define i32 @access_i1(i1 signext %idx) "cmse_nonsecure_entry" {
-; V8M-LABEL: access_i1:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    and r0, r0, #1
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    rsbs r0, r0, #0
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    and r0, r0, #1
-; V8M-NEXT:    mov r2, lr
-; V8M-NEXT:    mov r3, lr
-; V8M-NEXT:    mov r12, lr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    mov r1, lr
-; V8M-NEXT:    msr apsr_nzcvq, lr
-; V8M-NEXT:    bxns lr
+; V8M-COMMON-LABEL: access_i1:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    and r0, r0, #1
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    rsbs r0, r0, #0
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    and r0, r0, #1
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    bxns lr
 ;
-; V81M-LABEL: access_i1:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
-; V81M-NEXT:    and r0, r0, #1
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    rsbs r0, r0, #0
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    and r0, r0, #1
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
-; V81M-NEXT:    vldr fpcxtns, [sp], #4
-; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
-; V81M-NEXT:    bxns lr
+; V81M-COMMON-LABEL: access_i1:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-COMMON-NEXT:    and r0, r0, #1
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    rsbs r0, r0, #0
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    and r0, r0, #1
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
 entry:
   %idxprom = zext i1 %idx to i32
   %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
@@ -171,30 +170,30 @@ entry:
 }
 
 define i32 @access_i5(i5 signext %idx) "cmse_nonsecure_entry" {
-; V8M-LABEL: access_i5:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    sbfx r0, r0, #0, #5
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    mov r2, lr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    mov r1, lr
-; V8M-NEXT:    mov r3, lr
-; V8M-NEXT:    msr apsr_nzcvq, lr
-; V8M-NEXT:    mov r12, lr
-; V8M-NEXT:    bxns lr
+; V8M-COMMON-LABEL: access_i5:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    sbfx r0, r0, #0, #5
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    bxns lr
 ;
-; V81M-LABEL: access_i5:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    sbfx r0, r0, #0, #5
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
-; V81M-NEXT:    vldr fpcxtns, [sp], #4
-; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
-; V81M-NEXT:    bxns lr
+; V81M-COMMON-LABEL: access_i5:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    sbfx r0, r0, #0, #5
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
 entry:
   %idxprom = sext i5 %idx to i32
   %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
@@ -203,33 +202,167 @@ entry:
 }
 
 define i32 @access_u5(i5 zeroext %idx) "cmse_nonsecure_entry" {
-; V8M-LABEL: access_u5:
-; V8M:       @ %bb.0: @ %entry
-; V8M-NEXT:    movw r1, :lower16:arr
-; V8M-NEXT:    and r0, r0, #31
-; V8M-NEXT:    movt r1, :upper16:arr
-; V8M-NEXT:    mov r2, lr
-; V8M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V8M-NEXT:    mov r1, lr
-; V8M-NEXT:    mov r3, lr
-; V8M-NEXT:    msr apsr_nzcvq, lr
-; V8M-NEXT:    mov r12, lr
-; V8M-NEXT:    bxns lr
+; V8M-COMMON-LABEL: access_u5:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    movw r1, :lower16:arr
+; V8M-COMMON-NEXT:    and r0, r0, #31
+; V8M-COMMON-NEXT:    movt r1, :upper16:arr
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    bxns lr
 ;
-; V81M-LABEL: access_u5:
-; V81M:       @ %bb.0: @ %entry
-; V81M-NEXT:    vstr fpcxtns, [sp, #-4]!
-; V81M-NEXT:    movw r1, :lower16:arr
-; V81M-NEXT:    and r0, r0, #31
-; V81M-NEXT:    movt r1, :upper16:arr
-; V81M-NEXT:    ldr.w r0, [r1, r0, lsl #2]
-; V81M-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
-; V81M-NEXT:    vldr fpcxtns, [sp], #4
-; V81M-NEXT:    clrm {r1, r2, r3, r12, apsr}
-; V81M-NEXT:    bxns lr
+; V81M-COMMON-LABEL: access_u5:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-COMMON-NEXT:    movw r1, :lower16:arr
+; V81M-COMMON-NEXT:    and r0, r0, #31
+; V81M-COMMON-NEXT:    movt r1, :upper16:arr
+; V81M-COMMON-NEXT:    ldr.w r0, [r1, r0, lsl #2]
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
 entry:
   %idxprom = zext i5 %idx to i32
   %arrayidx = getelementptr inbounds [256 x i32], ptr @arr, i32 0, i32 %idxprom
   %0 = load i32, ptr %arrayidx, align 4
   ret i32 %0
 }
+
+define i32 @access_i33(i33 %arg) "cmse_nonsecure_entry" {
+; V8M-COMMON-LABEL: access_i33:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-LE-NEXT:        and r0, r1, #1
+; V8M-BE-NEXT:        and r0, r0, #1
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    rsbs r0, r0, #0
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    bxns lr
+;
+; V81M-COMMON-LABEL: access_i33:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-LE-NEXT:        and r0, r1, #1
+; V81M-BE-NEXT:        and r0, r0, #1
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    rsbs r0, r0, #0
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
+entry:
+  %shr = ashr i33 %arg, 32
+  %conv = trunc nsw i33 %shr to i32
+  ret i32 %conv
+}
+
+define i32 @access_u33(i33 %arg) "cmse_nonsecure_entry" {
+; V8M-COMMON-LABEL: access_u33:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-LE-NEXT:        and r0, r1, #1
+; V8M-BE-NEXT:        and r0, r0, #1
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    bxns lr
+;
+; V81M-COMMON-LABEL: access_u33:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-LE-NEXT:        and r0, r1, #1
+; V81M-BE-NEXT:        and r0, r0, #1
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
+entry:
+  %shr = lshr i33 %arg, 32
+  %conv = trunc nuw nsw i33 %shr to i32
+  ret i32 %conv
+}
+
+define i32 @access_i65(ptr byval(i65) %0) "cmse_nonsecure_entry" {
+; V8M-COMMON-LABEL: access_i65:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    sub sp, #16
+; V8M-COMMON-NEXT:    stm.w sp, {r0, r1, r2, r3}
+; V8M-LE-NEXT:        ldrb.w r0, [sp, #8]
+; V8M-LE-NEXT:        and r0, r0, #1
+; V8M-LE-NEXT:        rsbs r0, r0, #0
+; V8M-BE-NEXT:        movs r1, #0
+; V8M-BE-NEXT:        sub.w r0, r1, r0, lsr #24
+; V8M-COMMON-NEXT:    add sp, #16
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    bxns lr
+;
+; V81M-COMMON-LABEL: access_i65:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-COMMON-NEXT:    sub sp, #16
+; V81M-COMMON-NEXT:    add sp, #4
+; V81M-COMMON-NEXT:    stm.w sp, {r0, r1, r2, r3}
+; V81M-LE-NEXT:        ldrb.w r0, [sp, #8]
+; V81M-LE-NEXT:        and r0, r0, #1
+; V81M-LE-NEXT:        rsbs r0, r0, #0
+; V81M-BE-NEXT:        movs r1, #0
+; V81M-BE-NEXT:        sub.w r0, r1, r0, lsr #24
+; V81M-COMMON-NEXT:    sub sp, #4
+; V81M-COMMON-NEXT:    add sp, #16
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
+entry:
+  %arg = load i65, ptr %0, align 8
+  %shr = ashr i65 %arg, 64
+  %conv = trunc nsw i65 %shr to i32
+  ret i32 %conv
+}
+
+define i32 @access_u65(ptr byval(i65) %0) "cmse_nonsecure_entry" {
+; V8M-COMMON-LABEL: access_u65:
+; V8M-COMMON:       @ %bb.0: @ %entry
+; V8M-COMMON-NEXT:    sub sp, #16
+; V8M-COMMON-NEXT:    stm.w sp, {r0, r1, r2, r3}
+; V8M-LE-NEXT:        ldrb.w r0, [sp, #8]
+; V8M-BE-NEXT:        lsrs r0, r0, #24
+; V8M-COMMON-NEXT:    add sp, #16
+; V8M-COMMON-NEXT:    mov r1, lr
+; V8M-COMMON-NEXT:    mov r2, lr
+; V8M-COMMON-NEXT:    mov r3, lr
+; V8M-COMMON-NEXT:    mov r12, lr
+; V8M-COMMON-NEXT:    msr apsr_nzcvq, lr
+; V8M-COMMON-NEXT:    bxns lr
+;
+; V81M-COMMON-LABEL: access_u65:
+; V81M-COMMON:       @ %bb.0: @ %entry
+; V81M-COMMON-NEXT:    vstr fpcxtns, [sp, #-4]!
+; V81M-COMMON-NEXT:    sub sp, #16
+; V81M-COMMON-NEXT:    add sp, #4
+; V81M-COMMON-NEXT:    stm.w sp, {r0, r1, r2, r3}
+; V81M-LE-NEXT:        ldrb.w r0, [sp, #8]
+; V81M-BE-NEXT:        lsrs r0, r0, #24
+; V81M-COMMON-NEXT:    sub sp, #4
+; V81M-COMMON-NEXT:    add sp, #16
+; V81M-COMMON-NEXT:    vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
+; V81M-COMMON-NEXT:    vldr fpcxtns, [sp], #4
+; V81M-COMMON-NEXT:    clrm {r1, r2, r3, r12, apsr}
+; V81M-COMMON-NEXT:    bxns lr
+entry:
+  %arg = load i65, ptr %0, align 8
+  %shr = lshr i65 %arg, 64
+  %conv = trunc nuw nsw i65 %shr to i32
+  ret i32 %conv
+}

>From ffad0ae95e1a70c40b2910ad580c306e4bbbc104 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Tue, 21 May 2024 12:48:21 +0100
Subject: [PATCH 4/4] Remove dead code in formal argument lowering

This is a code that, if run, can nullify the CMSE security mitigaton.
Since it seems to be dead, since no LLVM test runs it, we remove it.
---
 llvm/lib/Target/ARM/ARMISelLowering.cpp | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index e50cacddeedd3..79eae9c643f8f 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -4617,16 +4617,6 @@ SDValue ARMTargetLowering::LowerFormalArguments(
       case CCValAssign::BCvt:
         ArgValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), ArgValue);
         break;
-      case CCValAssign::SExt:
-        ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
-                               DAG.getValueType(VA.getValVT()));
-        ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
-        break;
-      case CCValAssign::ZExt:
-        ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
-                               DAG.getValueType(VA.getValVT()));
-        ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
-        break;
       }
 
       // f16 arguments have their size extended to 4 bytes and passed as if they



More information about the llvm-commits mailing list