[llvm] 668bb96 - [ARM] Implement lowering of the sponentry intrinsic

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 2 02:31:22 PDT 2022


Author: Martin Storsjö
Date: 2022-06-02T12:29:59+03:00
New Revision: 668bb96379fef1bfa85da699c681265053673987

URL: https://github.com/llvm/llvm-project/commit/668bb96379fef1bfa85da699c681265053673987
DIFF: https://github.com/llvm/llvm-project/commit/668bb96379fef1bfa85da699c681265053673987.diff

LOG: [ARM] Implement lowering of the sponentry intrinsic

This is needed for SEH based setjmp on Windows.

Differential Revision: https://reviews.llvm.org/D126763

Added: 
    llvm/test/CodeGen/ARM/sponentry.ll

Modified: 
    llvm/docs/LangRef.rst
    llvm/lib/Target/ARM/ARMISelLowering.cpp
    llvm/lib/Target/ARM/ARMISelLowering.h

Removed: 
    


################################################################################
diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index d5540229a4b2..81341860ca4c 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -12685,7 +12685,7 @@ the entry of the current function calling this intrinsic.
 Semantics:
 """"""""""
 
-Note this intrinsic is only verified on AArch64.
+Note this intrinsic is only verified on AArch64 and ARM.
 
 '``llvm.frameaddress``' Intrinsic
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index eb1a0c55ca9b..a1c1f6aa2ab1 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -10315,6 +10315,15 @@ SDValue ARMTargetLowering::LowerFSETCC(SDValue Op, SelectionDAG &DAG) const {
   return DAG.getMergeValues({Result, Chain}, dl);
 }
 
+SDValue ARMTargetLowering::LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const {
+  MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
+
+  EVT VT = getPointerTy(DAG.getDataLayout());
+  SDLoc DL(Op);
+  int FI = MFI.CreateFixedObject(4, 0, false);
+  return DAG.getFrameIndex(FI, VT);
+}
+
 SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
   LLVM_DEBUG(dbgs() << "Lowering node: "; Op.dump());
   switch (Op.getOpcode()) {
@@ -10428,6 +10437,8 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
   case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
   case ISD::STRICT_FSETCC:
   case ISD::STRICT_FSETCCS: return LowerFSETCC(Op, DAG);
+  case ISD::SPONENTRY:
+    return LowerSPONENTRY(Op, DAG);
   case ARMISD::WIN__DBZCHK: return SDValue();
   }
 }

diff  --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index 33eb00100331..b6b063ab4f34 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -846,6 +846,7 @@ class VectorType;
     SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerFSETCC(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const;
     void LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
                    SelectionDAG &DAG) const;
 

diff  --git a/llvm/test/CodeGen/ARM/sponentry.ll b/llvm/test/CodeGen/ARM/sponentry.ll
new file mode 100644
index 000000000000..b98a14591b01
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/sponentry.ll
@@ -0,0 +1,120 @@
+; RUN: llc -mtriple=thumbv7-windows-msvc -frame-pointer=all %s -o - | FileCheck %s
+; RUN: llc -mtriple=thumbv7-windows-msvc -fast-isel -frame-pointer=all %s -o - | FileCheck %s
+; RUN: llc -mtriple=thumbv7-windows-msvc %s -o - | FileCheck %s --check-prefix=NOFP
+; RUN: llc -mtriple=thumbv7-windows-msvc -fast-isel %s -o - | FileCheck %s --check-prefix=NOFP
+
+ at env2 = common dso_local global [24 x i64]* null, align 8
+
+define dso_local void @bar() {
+  %1 = call i8* @llvm.sponentry()
+  %2 = load [24 x i64]*, [24 x i64]** @env2, align 8
+  %3 = getelementptr inbounds [24 x i64], [24 x i64]* %2, i32 0, i32 0
+  %4 = bitcast i64* %3 to i8*
+  %5 = call i32 @_setjmpex(i8* %4, i8* %1) #2
+  ret void
+}
+
+; CHECK: bar:
+; CHECK: push.w  {r11, lr}
+; CHECK: mov     r11, sp
+; CHECK: add.w   r1, r11, #8
+; CHECK: bl      _setjmpex
+
+; NOFP: bar:
+; NOFP: push.w  {r11, lr}
+; NOFP: add     r1, sp, #8
+; NOFP: bl      _setjmpex
+
+define dso_local void @foo([24 x i64]*) {
+  %2 = alloca [24 x i64]*, align 8
+  %3 = alloca i32, align 4
+  %4 = alloca [100 x i32], align 4
+  store [24 x i64]* %0, [24 x i64]** %2, align 8
+  %5 = call i8* @llvm.sponentry()
+  %6 = load [24 x i64]*, [24 x i64]** %2, align 8
+  %7 = getelementptr inbounds [24 x i64], [24 x i64]* %6, i32 0, i32 0
+  %8 = bitcast i64* %7 to i8*
+  %9 = call i32 @_setjmpex(i8* %8, i8* %5)
+  store i32 %9, i32* %3, align 4
+  ret void
+}
+
+; CHECK: foo:
+; CHECK: push.w  {r11, lr}
+; CHECK: mov     r11, sp
+; CHECK: sub     sp, #416
+; CHECK: add.w   r1, r11, #8
+; CHECK: bl      _setjmpex
+
+; NOFP: foo:
+; NOFP: push.w  {r11, lr}
+; NOFP: sub     sp, #416
+; NOFP: add     r1, sp, #424
+; NOFP: bl      _setjmpex
+
+define dso_local void @var_args(i8*, ...) {
+  %2 = alloca i8*, align 8
+  %3 = alloca i8*, align 8
+  store i8* %0, i8** %2, align 8
+  %4 = bitcast i8** %3 to i8*
+  call void @llvm.va_start(i8* %4)
+  %5 = load i8*, i8** %3, align 8
+  %6 = getelementptr inbounds i8, i8* %5, i64 8
+  store i8* %6, i8** %3, align 8
+  %7 = bitcast i8* %5 to i32*
+  %8 = load i32, i32* %7, align 8
+  %9 = bitcast i8** %3 to i8*
+  call void @llvm.va_end(i8* %9)
+  %10 = call i8* @llvm.sponentry()
+  %11 = load [24 x i64]*, [24 x i64]** @env2, align 8
+  %12 = getelementptr inbounds [24 x i64], [24 x i64]* %11, i32 0, i32 0
+  %13 = bitcast i64* %12 to i8*
+  %14 = call i32 @_setjmpex(i8* %13, i8* %10) #3
+  ret void
+}
+
+; CHECK: var_args:
+; CHECK: sub     sp, #12
+; CHECK: push.w  {r11, lr}
+; CHECK: mov     r11, sp
+; CHECK: add.w   r1, r11, #20
+; CHECK: bl      _setjmpex
+
+; NOFP: var_args:
+; NOFP: sub     sp, #12
+; NOFP: push.w  {r11, lr}
+; NOFP: sub     sp, #12
+; NOFP: add     r1, sp, #32
+; NOFP: bl      _setjmpex
+
+define dso_local void @manyargs(i64 %x1, i64 %x2, i64 %x3, i64 %x4, i64 %x5, i64 %x6, i64 %x7, i64 %x8, i64 %x9, i64 %x10) {
+  %1 = call i8* @llvm.sponentry()
+  %2 = load [24 x i64]*, [24 x i64]** @env2, align 8
+  %3 = getelementptr inbounds [24 x i64], [24 x i64]* %2, i32 0, i32 0
+  %4 = bitcast i64* %3 to i8*
+  %5 = call i32 @_setjmpex(i8* %4, i8* %1) #2
+  ret void
+}
+
+; CHECK: manyargs:
+; CHECK: push.w  {r11, lr}
+; CHECK: mov     r11, sp
+; CHECK: add.w   r1, r11, #8
+; CHECK: bl      _setjmpex
+
+; NOFP: manyargs:
+; NOFP: push.w  {r11, lr}
+; NOFP: add     r1, sp, #8
+; NOFP: bl      _setjmpex
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.sponentry()
+
+; Function Attrs: returns_twice
+declare dso_local i32 @_setjmpex(i8*, i8*)
+
+; Function Attrs: nounwind
+declare void @llvm.va_start(i8*) #1
+
+; Function Attrs: nounwind
+declare void @llvm.va_end(i8*) #1


        


More information about the llvm-commits mailing list