summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/llvm/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/llvm/llvm')
-rw-r--r--meta/recipes-devtools/llvm/llvm/0001-AsmMatcherEmitter-sort-ClassInfo-lists-by-name-as-we.patch31
-rw-r--r--meta/recipes-devtools/llvm/llvm/0001-llvm-TargetLibraryInfo-Undefine-libc-functions-if-th.patch93
-rw-r--r--meta/recipes-devtools/llvm/llvm/0002-llvm-Fix-CVE-2024-0151.patch1086
-rw-r--r--meta/recipes-devtools/llvm/llvm/0002-llvm-allow-env-override-of-exe-path.patch72
-rw-r--r--meta/recipes-devtools/llvm/llvm/0007-llvm-allow-env-override-of-exe-path.patch37
-rw-r--r--meta/recipes-devtools/llvm/llvm/llvm-config51
6 files changed, 1205 insertions, 165 deletions
diff --git a/meta/recipes-devtools/llvm/llvm/0001-AsmMatcherEmitter-sort-ClassInfo-lists-by-name-as-we.patch b/meta/recipes-devtools/llvm/llvm/0001-AsmMatcherEmitter-sort-ClassInfo-lists-by-name-as-we.patch
new file mode 100644
index 0000000000..a5c53b6657
--- /dev/null
+++ b/meta/recipes-devtools/llvm/llvm/0001-AsmMatcherEmitter-sort-ClassInfo-lists-by-name-as-we.patch
@@ -0,0 +1,31 @@
+From 3b30a9bda88374e8f03bf96e972aee5bd214b98b Mon Sep 17 00:00:00 2001
+From: Alexander Kanavin <alex.kanavin@gmail.com>
+Date: Fri, 27 Nov 2020 10:11:08 +0000
+Subject: [PATCH] AsmMatcherEmitter: sort ClassInfo lists by name as well
+
+Otherwise, there are instances which are identical in
+every other field and therefore sort non-reproducibly
+(which breaks binary and source reproducibiliy).
+
+Upstream-Status: Submitted [https://reviews.llvm.org/D97477]
+Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+---
+ llvm/utils/TableGen/AsmMatcherEmitter.cpp | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+index 73724e662f9e..1ca9c73415db 100644
+--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
++++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+@@ -361,7 +361,10 @@ public:
+ // name of a class shouldn't be significant. However, some of the backends
+ // accidentally rely on this behaviour, so it will have to stay like this
+ // until they are fixed.
+- return ValueName < RHS.ValueName;
++ if (ValueName != RHS.ValueName)
++ return ValueName < RHS.ValueName;
++ // All else being equal, we should sort by name, for source and binary reproducibility
++ return Name < RHS.Name;
+ }
+ };
+
diff --git a/meta/recipes-devtools/llvm/llvm/0001-llvm-TargetLibraryInfo-Undefine-libc-functions-if-th.patch b/meta/recipes-devtools/llvm/llvm/0001-llvm-TargetLibraryInfo-Undefine-libc-functions-if-th.patch
deleted file mode 100644
index 209764c8ba..0000000000
--- a/meta/recipes-devtools/llvm/llvm/0001-llvm-TargetLibraryInfo-Undefine-libc-functions-if-th.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 96558c4f25d5132936014f6f2d6252cfdfdf478a Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Sat, 21 May 2016 00:33:20 +0000
-Subject: [PATCH 1/2] llvm: TargetLibraryInfo: Undefine libc functions if they
- are macros
-
-musl defines some functions as macros and not inline functions
-if this is the case then make sure to undefine them
-
-Signed-off-by: Khem Raj <raj.khem@gmail.com>
----
-Upstream-Status: Pending
-
- include/llvm/Analysis/TargetLibraryInfo.def | 21 +++++++++++++++++++++
- 1 file changed, 21 insertions(+)
-
-diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def
-index a461ed813b9..f9fd9faeee0 100644
---- a/include/llvm/Analysis/TargetLibraryInfo.def
-+++ b/include/llvm/Analysis/TargetLibraryInfo.def
-@@ -665,6 +665,9 @@ TLI_DEFINE_STRING_INTERNAL("fmodl")
- TLI_DEFINE_ENUM_INTERNAL(fopen)
- TLI_DEFINE_STRING_INTERNAL("fopen")
- /// FILE *fopen64(const char *filename, const char *opentype)
-+#ifdef fopen64
-+#undef fopen64
-+#endif
- TLI_DEFINE_ENUM_INTERNAL(fopen64)
- TLI_DEFINE_STRING_INTERNAL("fopen64")
- /// int fprintf(FILE *stream, const char *format, ...);
-@@ -700,6 +703,9 @@ TLI_DEFINE_STRING_INTERNAL("fseek")
- /// int fseeko(FILE *stream, off_t offset, int whence);
- TLI_DEFINE_ENUM_INTERNAL(fseeko)
- TLI_DEFINE_STRING_INTERNAL("fseeko")
-+#ifdef fseeko64
-+#undef fseeko64
-+#endif
- /// int fseeko64(FILE *stream, off64_t offset, int whence)
- TLI_DEFINE_ENUM_INTERNAL(fseeko64)
- TLI_DEFINE_STRING_INTERNAL("fseeko64")
-@@ -710,6 +716,9 @@ TLI_DEFINE_STRING_INTERNAL("fsetpos")
- TLI_DEFINE_ENUM_INTERNAL(fstat)
- TLI_DEFINE_STRING_INTERNAL("fstat")
- /// int fstat64(int filedes, struct stat64 *buf)
-+#ifdef fstat64
-+#undef fstat64
-+#endif
- TLI_DEFINE_ENUM_INTERNAL(fstat64)
- TLI_DEFINE_STRING_INTERNAL("fstat64")
- /// int fstatvfs(int fildes, struct statvfs *buf);
-@@ -725,6 +734,9 @@ TLI_DEFINE_STRING_INTERNAL("ftell")
- TLI_DEFINE_ENUM_INTERNAL(ftello)
- TLI_DEFINE_STRING_INTERNAL("ftello")
- /// off64_t ftello64(FILE *stream)
-+#ifdef ftello64
-+#undef ftello64
-+#endif
- TLI_DEFINE_ENUM_INTERNAL(ftello64)
- TLI_DEFINE_STRING_INTERNAL("ftello64")
- /// int ftrylockfile(FILE *file);
-@@ -845,6 +857,9 @@ TLI_DEFINE_STRING_INTERNAL("logl")
- TLI_DEFINE_ENUM_INTERNAL(lstat)
- TLI_DEFINE_STRING_INTERNAL("lstat")
- /// int lstat64(const char *path, struct stat64 *buf);
-+#ifdef lstat64
-+#undef lstat64
-+#endif
- TLI_DEFINE_ENUM_INTERNAL(lstat64)
- TLI_DEFINE_STRING_INTERNAL("lstat64")
- /// void *malloc(size_t size);
-@@ -1064,6 +1079,9 @@ TLI_DEFINE_STRING_INTERNAL("sscanf")
- TLI_DEFINE_ENUM_INTERNAL(stat)
- TLI_DEFINE_STRING_INTERNAL("stat")
- /// int stat64(const char *path, struct stat64 *buf);
-+#ifdef stat64
-+#undef stat64
-+#endif
- TLI_DEFINE_ENUM_INTERNAL(stat64)
- TLI_DEFINE_STRING_INTERNAL("stat64")
- /// int statvfs(const char *path, struct statvfs *buf);
-@@ -1193,6 +1211,9 @@ TLI_DEFINE_STRING_INTERNAL("times")
- TLI_DEFINE_ENUM_INTERNAL(tmpfile)
- TLI_DEFINE_STRING_INTERNAL("tmpfile")
- /// FILE *tmpfile64(void)
-+#ifdef tmpfile64
-+#undef tmpfile64
-+#endif
- TLI_DEFINE_ENUM_INTERNAL(tmpfile64)
- TLI_DEFINE_STRING_INTERNAL("tmpfile64")
- /// int toascii(int c);
---
-2.16.1
-
diff --git a/meta/recipes-devtools/llvm/llvm/0002-llvm-Fix-CVE-2024-0151.patch b/meta/recipes-devtools/llvm/llvm/0002-llvm-Fix-CVE-2024-0151.patch
new file mode 100644
index 0000000000..c05685e64d
--- /dev/null
+++ b/meta/recipes-devtools/llvm/llvm/0002-llvm-Fix-CVE-2024-0151.patch
@@ -0,0 +1,1086 @@
+commit 78ff617d3f573fb3a9b2fef180fa0fd43d5584ea
+Author: Lucas Duarte Prates <lucas.prates@arm.com>
+Date: Thu Jun 20 10:22:01 2024 +0100
+
+ [ARM] CMSE security mitigation on function arguments and returned values (#89944)
+
+ 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.
+
+ Patches by Victor Campos.
+
+ ---------
+
+ Co-authored-by: Victor Campos <victor.campos@arm.com>
+
+Upstream-Status: Backport [https://github.com/llvm/llvm-project/commit/78ff617d3f573fb3a9b2fef180fa0fd43d5584ea]
+CVE: CVE-2024-0151
+Signed-off-by: Deepthi Hemraj <Deepthi.Hemraj@windriver.com>
+---
+diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
+index bfe137b95602..5490c3c9df6c 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) {
++ 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,
++ MVT::i32, Trunc);
++ return Ext;
++}
++
+ void ARMTargetLowering::addTypeForNEON(MVT VT, MVT PromotedLdStVT) {
+ if (VT != PromotedLdStVT) {
+ setOperationAction(ISD::LOAD, VT, Promote);
+@@ -2196,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,
+@@ -2274,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(MVT::i32))
++ Val = handleCMSEValue(Val, Arg, DAG, dl);
++
+ InVals.push_back(Val);
+ }
+
+@@ -2888,7 +2908,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
+@@ -4485,8 +4505,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;
+
+@@ -4541,6 +4559,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
+@@ -4604,16 +4623,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
+@@ -4623,6 +4632,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(MVT::i32))
++ ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl);
++
+ InVals.push_back(ArgValue);
+ } else { // VA.isRegLoc()
+ // Only arguments passed on the stack should make it here.
+diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
+index 62a52bdb03f7..a255e9b6fc36 100644
+--- a/llvm/lib/Target/ARM/ARMISelLowering.h
++++ b/llvm/lib/Target/ARM/ARMISelLowering.h
+@@ -891,7 +891,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 0000000000..58eef443c25e
+--- /dev/null
++++ b/llvm/test/CodeGen/ARM/cmse-harden-call-returned-values.ll
+@@ -0,0 +1,552 @@
++; 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-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-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"
++ %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-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-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"
++ %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-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-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"
++ %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-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-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"
++ %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-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-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"
++ %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-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-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"
++ %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-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-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"
++ %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
++}
++
++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
+new file mode 100644
+index 0000000000..c66ab00566dd
+--- /dev/null
++++ b/llvm/test/CodeGen/ARM/cmse-harden-entry-arguments.ll
+@@ -0,0 +1,368 @@
++; 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-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-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
++ %0 = load i32, ptr %arrayidx, align 4
++ ret i32 %0
++}
++
++define i32 @access_u16(i16 zeroext %idx) "cmse_nonsecure_entry" {
++; 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-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
++ %0 = load i32, ptr %arrayidx, align 4
++ ret i32 %0
++}
++
++define i32 @access_i8(i8 signext %idx) "cmse_nonsecure_entry" {
++; 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-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
++ %0 = load i32, ptr %arrayidx, align 4
++ ret i32 %0
++}
++
++define i32 @access_u8(i8 zeroext %idx) "cmse_nonsecure_entry" {
++; 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-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
++ %0 = load i32, ptr %arrayidx, align 4
++ ret i32 %0
++}
++
++define i32 @access_i1(i1 signext %idx) "cmse_nonsecure_entry" {
++; 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-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
++ %0 = load i32, ptr %arrayidx, align 4
++ ret i32 %0
++}
++
++define i32 @access_i5(i5 signext %idx) "cmse_nonsecure_entry" {
++; 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-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
++ %0 = load i32, ptr %arrayidx, align 4
++ ret i32 %0
++}
++
++define i32 @access_u5(i5 zeroext %idx) "cmse_nonsecure_entry" {
++; 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-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
++}
diff --git a/meta/recipes-devtools/llvm/llvm/0002-llvm-allow-env-override-of-exe-path.patch b/meta/recipes-devtools/llvm/llvm/0002-llvm-allow-env-override-of-exe-path.patch
deleted file mode 100644
index 6a9283323c..0000000000
--- a/meta/recipes-devtools/llvm/llvm/0002-llvm-allow-env-override-of-exe-path.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From aeccf16eaccdd80e4d5ecaa51673ce4b2bac1130 Mon Sep 17 00:00:00 2001
-From: Martin Kelly <mkelly@xevo.com>
-Date: Fri, 19 May 2017 00:22:57 -0700
-Subject: [PATCH 2/2] llvm: allow env override of exe path
-
-When using a native llvm-config from inside a sysroot, we need llvm-config to
-return the libraries, include directories, etc. from inside the sysroot rather
-than from the native sysroot. Thus provide an env override for calling
-llvm-config from a target sysroot.
-
-To let it work in multilib environment, we need to provide a knob to supply
-multilib dirname as well
-
-Upstream-Status: Inappropriate [OE-Specific]
-
-Signed-off-by: Martin Kelly <mkelly@xevo.com>
-Signed-off-by: Khem Raj <raj.khem@gmail.com>
----
- tools/llvm-config/llvm-config.cpp | 17 ++++++++++++++++-
- 1 file changed, 16 insertions(+), 1 deletion(-)
-
-diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp
-index 08b096afb05..360cc5abf4e 100644
---- a/tools/llvm-config/llvm-config.cpp
-+++ b/tools/llvm-config/llvm-config.cpp
-@@ -225,6 +225,13 @@ Typical components:\n\
-
- /// \brief Compute the path to the main executable.
- std::string GetExecutablePath(const char *Argv0) {
-+ // Hack for Yocto: we need to override the root path when we are using
-+ // llvm-config from within a target sysroot.
-+ const char *Sysroot = std::getenv("YOCTO_ALTERNATE_EXE_PATH");
-+ if (Sysroot != nullptr) {
-+ return Sysroot;
-+ }
-+
- // This just needs to be some symbol in the binary; C++ doesn't
- // allow taking the address of ::main however.
- void *P = (void *)(intptr_t)GetExecutablePath;
-@@ -306,12 +313,20 @@ int main(int argc, char **argv) {
- std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir,
- ActiveCMakeDir;
- std::string ActiveIncludeOption;
-+ // Hack for Yocto: we need to override the multilib path when we are using
-+ // llvm-config from within a target sysroot.
-+ std::string Multilibdir = std::getenv("YOCTO_ALTERNATE_MULTILIB_NAME");
-+ if (Multilibdir.empty()) {
-+ Multilibdir = "/lib" LLVM_LIBDIR_SUFFIX;
-+ }
-+
- if (IsInDevelopmentTree) {
- ActiveIncludeDir = std::string(LLVM_SRC_ROOT) + "/include";
- ActivePrefix = CurrentExecPrefix;
-
- // CMake organizes the products differently than a normal prefix style
- // layout.
-+
- switch (DevelopmentTreeLayout) {
- case CMakeStyle:
- ActiveBinDir = ActiveObjRoot + "/bin";
-@@ -336,7 +351,7 @@ int main(int argc, char **argv) {
- SmallString<256> path(StringRef(LLVM_TOOLS_INSTALL_DIR));
- sys::fs::make_absolute(ActivePrefix, path);
- ActiveBinDir = path.str();
-- ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX;
-+ ActiveLibDir = ActivePrefix + Multilibdir;
- ActiveCMakeDir = ActiveLibDir + "/cmake/llvm";
- ActiveIncludeOption = "-I" + ActiveIncludeDir;
- }
---
-2.18.0
-
diff --git a/meta/recipes-devtools/llvm/llvm/0007-llvm-allow-env-override-of-exe-path.patch b/meta/recipes-devtools/llvm/llvm/0007-llvm-allow-env-override-of-exe-path.patch
new file mode 100644
index 0000000000..add38b3bb4
--- /dev/null
+++ b/meta/recipes-devtools/llvm/llvm/0007-llvm-allow-env-override-of-exe-path.patch
@@ -0,0 +1,37 @@
+From 588a8694c6540e31140c7e242bfb5e279d6ca08c Mon Sep 17 00:00:00 2001
+From: Martin Kelly <mkelly@xevo.com>
+Date: Fri, 19 May 2017 00:22:57 -0700
+Subject: [PATCH] llvm: allow env override of exe and libdir path
+
+When using a native llvm-config from inside a sysroot, we need llvm-config to
+return the libraries, include directories, etc. from inside the sysroot rather
+than from the native sysroot. Thus provide an env override for calling
+llvm-config from a target sysroot.
+
+Upstream-Status: Inappropriate [OE-specific]
+
+Signed-off-by: Martin Kelly <mkelly@xevo.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ llvm/tools/llvm-config/llvm-config.cpp | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/llvm/tools/llvm-config/llvm-config.cpp b/llvm/tools/llvm-config/llvm-config.cpp
+index e86eb2b44b10..7b2abf318dbe 100644
+--- a/llvm/tools/llvm-config/llvm-config.cpp
++++ b/llvm/tools/llvm-config/llvm-config.cpp
+@@ -246,6 +246,13 @@ Typical components:\n\
+
+ /// Compute the path to the main executable.
+ std::string GetExecutablePath(const char *Argv0) {
++ // Hack for Yocto: we need to override the root path when we are using
++ // llvm-config from within a target sysroot.
++ const char *Sysroot = std::getenv("YOCTO_ALTERNATE_EXE_PATH");
++ if (Sysroot != nullptr) {
++ return Sysroot;
++ }
++
+ // This just needs to be some symbol in the binary; C++ doesn't
+ // allow taking the address of ::main however.
+ void *P = (void *)(intptr_t)GetExecutablePath;
+
diff --git a/meta/recipes-devtools/llvm/llvm/llvm-config b/meta/recipes-devtools/llvm/llvm/llvm-config
new file mode 100644
index 0000000000..5e4ded2da5
--- /dev/null
+++ b/meta/recipes-devtools/llvm/llvm/llvm-config
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+# Copyright OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+#
+# Wrap llvm-config since the native llvm-config will remap some values correctly
+# if placed in the target sysroot but for flags, it would provide the native ones.
+# Provide ours from the environment instead.
+
+NEXT_LLVM_CONFIG="$(which -a llvm-config | sed -n 2p)"
+if [[ $# == 0 ]]; then
+ exec "$NEXT_LLVM_CONFIG"
+fi
+
+remain=""
+output=""
+for arg in "$@"; do
+ case "$arg" in
+ --cppflags)
+ output="${output} ${CPPFLAGS}"
+ ;;
+ --cflags)
+ output="${output} ${CFLAGS}"
+ ;;
+ --cxxflags)
+ output="${output} ${CXXFLAGS}"
+ ;;
+ --ldflags)
+ output="${output} ${LDFLAGS}"
+ ;;
+ --shared-mode)
+ output="${output} shared"
+ ;;
+ --libs)
+ output="${output} -lLLVM"
+ ;;
+ --link-shared)
+ break
+ ;;
+ *)
+ remain="${remain} ${arg}"
+ ;;
+ esac
+done
+
+if [ "${remain}" != "" ]; then
+ output="${output} "$("$NEXT_LLVM_CONFIG" ${remain})
+fi
+
+echo "${output}"