[llvm] adc26b4 - [ARM] Fix 8-bit immediate overflow in the instruction of segmented stack prologue.

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 10 15:17:05 PST 2022


Author: Zhiyao Ma
Date: 2022-03-10T15:15:24-08:00
New Revision: adc26b4eaedc50f1b99d5af5c7e248966fced660

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

LOG: [ARM] Fix 8-bit immediate overflow in the instruction of segmented stack prologue.

It fixes the overflow of 8-bit immediate field in the emitted
instruction that allocates large stacklet.

For thumb2 targets, load large immediate by a pair of movw and movt
instruction. For thumb1 and ARM targets, load large immediate by reading
from literal pool.

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

Added: 
    

Modified: 
    llvm/lib/Target/ARM/ARMFrameLowering.cpp
    llvm/test/CodeGen/ARM/segmented-stacks.ll
    llvm/test/CodeGen/Thumb/segmented-stacks.ll
    llvm/test/CodeGen/Thumb2/segmented-stacks.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 1f2f6f7497e02..b9b417865691f 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -2488,6 +2488,7 @@ void ARMFrameLowering::adjustForSegmentedStacks(
   unsigned CFIIndex;
   const ARMSubtarget *ST = &MF.getSubtarget<ARMSubtarget>();
   bool Thumb = ST->isThumb();
+  bool Thumb2 = ST->isThumb2();
 
   // Sadly, this currently doesn't support varargs, platforms other than
   // android/linux. Note that thumb1/thumb2 are support for android/linux.
@@ -2630,17 +2631,46 @@ void ARMFrameLowering::adjustForSegmentedStacks(
 
   // sub SR1, sp, #StackSize
   if (!CompareStackPointer && Thumb) {
-    BuildMI(McrMBB, DL, TII.get(ARM::tSUBi8), ScratchReg1)
-        .add(condCodeOp())
-        .addReg(ScratchReg1)
-        .addImm(AlignedStackSize)
-        .add(predOps(ARMCC::AL));
+    if (AlignedStackSize < 256) {
+      BuildMI(McrMBB, DL, TII.get(ARM::tSUBi8), ScratchReg1)
+          .add(condCodeOp())
+          .addReg(ScratchReg1)
+          .addImm(AlignedStackSize)
+          .add(predOps(ARMCC::AL));
+    } else {
+      if (Thumb2) {
+        BuildMI(McrMBB, DL, TII.get(ARM::t2MOVi32imm), ScratchReg0)
+            .addImm(AlignedStackSize);
+      } else {
+        auto MBBI = McrMBB->end();
+        auto RegInfo = STI.getRegisterInfo();
+        RegInfo->emitLoadConstPool(*McrMBB, MBBI, DL, ScratchReg0, 0,
+                                   AlignedStackSize);
+      }
+      BuildMI(McrMBB, DL, TII.get(ARM::tSUBrr), ScratchReg1)
+          .add(condCodeOp())
+          .addReg(ScratchReg1)
+          .addReg(ScratchReg0)
+          .add(predOps(ARMCC::AL));
+    }
   } else if (!CompareStackPointer) {
-    BuildMI(McrMBB, DL, TII.get(ARM::SUBri), ScratchReg1)
-        .addReg(ARM::SP)
-        .addImm(AlignedStackSize)
-        .add(predOps(ARMCC::AL))
-        .add(condCodeOp());
+    if (AlignedStackSize < 256) {
+      BuildMI(McrMBB, DL, TII.get(ARM::SUBri), ScratchReg1)
+          .addReg(ARM::SP)
+          .addImm(AlignedStackSize)
+          .add(predOps(ARMCC::AL))
+          .add(condCodeOp());
+    } else {
+      auto MBBI = McrMBB->end();
+      auto RegInfo = STI.getRegisterInfo();
+      RegInfo->emitLoadConstPool(*McrMBB, MBBI, DL, ScratchReg0, 0,
+                                 AlignedStackSize);
+      BuildMI(McrMBB, DL, TII.get(ARM::SUBrr), ScratchReg1)
+          .addReg(ARM::SP)
+          .addReg(ScratchReg0)
+          .add(predOps(ARMCC::AL))
+          .add(condCodeOp());
+    }
   }
 
   if (Thumb && ST->isThumb1Only()) {
@@ -2707,28 +2737,69 @@ void ARMFrameLowering::adjustForSegmentedStacks(
   // Pass first argument for the __morestack by Scratch Register #0.
   //   The amount size of stack required
   if (Thumb) {
-    BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg0)
-        .add(condCodeOp())
-        .addImm(AlignedStackSize)
-        .add(predOps(ARMCC::AL));
+    if (AlignedStackSize < 256) {
+      BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg0)
+          .add(condCodeOp())
+          .addImm(AlignedStackSize)
+          .add(predOps(ARMCC::AL));
+    } else {
+      if (Thumb2) {
+        BuildMI(AllocMBB, DL, TII.get(ARM::t2MOVi32imm), ScratchReg0)
+            .addImm(AlignedStackSize);
+      } else {
+        auto MBBI = AllocMBB->end();
+        auto RegInfo = STI.getRegisterInfo();
+        RegInfo->emitLoadConstPool(*AllocMBB, MBBI, DL, ScratchReg0, 0,
+                                   AlignedStackSize);
+      }
+    }
   } else {
-    BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg0)
-        .addImm(AlignedStackSize)
-        .add(predOps(ARMCC::AL))
-        .add(condCodeOp());
+    if (AlignedStackSize < 256) {
+      BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg0)
+          .addImm(AlignedStackSize)
+          .add(predOps(ARMCC::AL))
+          .add(condCodeOp());
+    } else {
+      auto MBBI = AllocMBB->end();
+      auto RegInfo = STI.getRegisterInfo();
+      RegInfo->emitLoadConstPool(*AllocMBB, MBBI, DL, ScratchReg0, 0,
+                                 AlignedStackSize);
+    }
   }
+
   // Pass second argument for the __morestack by Scratch Register #1.
   //   The amount size of stack consumed to save function arguments.
   if (Thumb) {
-    BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg1)
-        .add(condCodeOp())
-        .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()))
-        .add(predOps(ARMCC::AL));
+    if (ARMFI->getArgumentStackSize() < 256) {
+      BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg1)
+          .add(condCodeOp())
+          .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()))
+          .add(predOps(ARMCC::AL));
+    } else {
+      if (Thumb2) {
+        BuildMI(AllocMBB, DL, TII.get(ARM::t2MOVi32imm), ScratchReg1)
+            .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()));
+      } else {
+        auto MBBI = AllocMBB->end();
+        auto RegInfo = STI.getRegisterInfo();
+        RegInfo->emitLoadConstPool(
+            *AllocMBB, MBBI, DL, ScratchReg1, 0,
+            alignToARMConstant(ARMFI->getArgumentStackSize()));
+      }
+    }
   } else {
-    BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg1)
-        .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()))
-        .add(predOps(ARMCC::AL))
-        .add(condCodeOp());
+    if (alignToARMConstant(ARMFI->getArgumentStackSize()) < 256) {
+      BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg1)
+          .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()))
+          .add(predOps(ARMCC::AL))
+          .add(condCodeOp());
+    } else {
+      auto MBBI = AllocMBB->end();
+      auto RegInfo = STI.getRegisterInfo();
+      RegInfo->emitLoadConstPool(
+          *AllocMBB, MBBI, DL, ScratchReg1, 0,
+          alignToARMConstant(ARMFI->getArgumentStackSize()));
+    }
   }
 
   // push {lr} - Save return address of this function.

diff  --git a/llvm/test/CodeGen/ARM/segmented-stacks.ll b/llvm/test/CodeGen/ARM/segmented-stacks.ll
index 971fdd9660652..10ce0657e573c 100644
--- a/llvm/test/CodeGen/ARM/segmented-stacks.ll
+++ b/llvm/test/CodeGen/ARM/segmented-stacks.ll
@@ -14,7 +14,7 @@ define void @test_basic() #0 {
         call void @dummy_use (i32* %mem, i32 10)
 	ret void
 
-; ARM-linux:      test_basic:
+; ARM-linux-LABEL: test_basic:
 
 ; ARM-linux:      push    {r4, r5}
 ; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
@@ -33,7 +33,7 @@ define void @test_basic() #0 {
 
 ; ARM-linux:      pop     {r4, r5}
 
-; ARM-android:      test_basic:
+; ARM-android-LABEL: test_basic:
 
 ; ARM-android:      push    {r4, r5}
 ; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
@@ -61,7 +61,7 @@ define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
        call void @dummy_use (i32* %mem, i32 10)
        ret i32 %result
 
-; ARM-linux:      test_nested:
+; ARM-linux-LABEL: test_nested:
 
 ; ARM-linux:      push    {r4, r5}
 ; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
@@ -80,7 +80,7 @@ define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
 
 ; ARM-linux:      pop     {r4, r5}
 
-; ARM-android:      test_nested:
+; ARM-android-LABEL: test_nested:
 
 ; ARM-android:      push    {r4, r5}
 ; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
@@ -106,16 +106,17 @@ define void @test_large() #0 {
         call void @dummy_use (i32* %mem, i32 0)
         ret void
 
-; ARM-linux:      test_large:
+; ARM-linux-LABEL: test_large:
 
 ; ARM-linux:      push    {r4, r5}
+; ARM-linux-NEXT: ldr     r4, .LCPI2_0
+; ARM-linux-NEXT: sub     r5, sp, r4
 ; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
-; ARM-linux-NEXT: sub     r5, sp, #40192
 ; ARM-linux-NEXT: ldr     r4, [r4, #4]
 ; ARM-linux-NEXT: cmp     r4, r5
 ; ARM-linux-NEXT: blo     .LBB2_2
 
-; ARM-linux:      mov     r4, #40192
+; ARM-linux:      ldr     r4, .LCPI2_0
 ; ARM-linux-NEXT: mov     r5, #0
 ; ARM-linux-NEXT: stmdb   sp!, {lr}
 ; ARM-linux-NEXT: bl      __morestack
@@ -125,16 +126,20 @@ define void @test_large() #0 {
 
 ; ARM-linux:      pop     {r4, r5}
 
-; ARM-android:      test_large:
+; ARM-linux:      .LCPI2_0:
+; ARM-linux-NEXT: .long   40192
+
+; ARM-android-LABEL: test_large:
 
 ; ARM-android:      push    {r4, r5}
+; ARM-android-NEXT: ldr     r4, .LCPI2_0
+; ARM-android-NEXT: sub     r5, sp, r4
 ; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
-; ARM-android-NEXT: sub     r5, sp, #40192
 ; ARM-android-NEXT: ldr     r4, [r4, #252]
 ; ARM-android-NEXT: cmp     r4, r5
 ; ARM-android-NEXT: blo     .LBB2_2
 
-; ARM-android:      mov     r4, #40192
+; ARM-android:      ldr     r4, .LCPI2_0
 ; ARM-android-NEXT: mov     r5, #0
 ; ARM-android-NEXT: stmdb   sp!, {lr}
 ; ARM-android-NEXT: bl      __morestack
@@ -144,6 +149,9 @@ define void @test_large() #0 {
 
 ; ARM-android:      pop     {r4, r5}
 
+; ARM-android:      .LCPI2_0:
+; ARM-android-NEXT: .long   40192
+
 }
 
 define fastcc void @test_fastcc() #0 {
@@ -151,7 +159,7 @@ define fastcc void @test_fastcc() #0 {
         call void @dummy_use (i32* %mem, i32 10)
         ret void
 
-; ARM-linux:      test_fastcc:
+; ARM-linux-LABEL: test_fastcc:
 
 ; ARM-linux:      push    {r4, r5}
 ; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
@@ -170,7 +178,7 @@ define fastcc void @test_fastcc() #0 {
 
 ; ARM-linux:      pop     {r4, r5}
 
-; ARM-android:      test_fastcc:
+; ARM-android-LABEL: test_fastcc:
 
 ; ARM-android:      push    {r4, r5}
 ; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
@@ -196,16 +204,17 @@ define fastcc void @test_fastcc_large() #0 {
         call void @dummy_use (i32* %mem, i32 0)
         ret void
 
-; ARM-linux:      test_fastcc_large:
+; ARM-linux-LABEL: test_fastcc_large:
 
 ; ARM-linux:      push    {r4, r5}
+; ARM-linux-NEXT: ldr     r4, .LCPI4_0
+; ARM-linux-NEXT: sub     r5, sp, r4
 ; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
-; ARM-linux-NEXT: sub     r5, sp, #40192
 ; ARM-linux-NEXT: ldr     r4, [r4, #4]
 ; ARM-linux-NEXT: cmp     r4, r5
 ; ARM-linux-NEXT: blo     .LBB4_2
 
-; ARM-linux:      mov     r4, #40192
+; ARM-linux:      ldr     r4, .LCPI4_0
 ; ARM-linux-NEXT: mov     r5, #0
 ; ARM-linux-NEXT: stmdb   sp!, {lr}
 ; ARM-linux-NEXT: bl      __morestack
@@ -215,16 +224,20 @@ define fastcc void @test_fastcc_large() #0 {
 
 ; ARM-linux:      pop     {r4, r5}
 
-; ARM-android:      test_fastcc_large:
+; ARM-linux:      .LCPI4_0:
+; ARM-linux-NEXT: .long   40192
+
+; ARM-android-LABEL: test_fastcc_large:
 
 ; ARM-android:      push    {r4, r5}
+; ARM-android-NEXT: ldr     r4, .LCPI4_0
+; ARM-android-NEXT: sub     r5, sp, r4
 ; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
-; ARM-android-NEXT: sub     r5, sp, #40192
 ; ARM-android-NEXT: ldr     r4, [r4, #252]
 ; ARM-android-NEXT: cmp     r4, r5
 ; ARM-android-NEXT: blo     .LBB4_2
 
-; ARM-android:      mov     r4, #40192
+; ARM-android:      ldr     r4, .LCPI4_0
 ; ARM-android-NEXT: mov     r5, #0
 ; ARM-android-NEXT: stmdb   sp!, {lr}
 ; ARM-android-NEXT: bl      __morestack
@@ -234,6 +247,9 @@ define fastcc void @test_fastcc_large() #0 {
 
 ; ARM-android:      pop     {r4, r5}
 
+; ARM-android:      .LCPI4_0:
+; ARM-android-NEXT: .long   40192
+
 }
 
 define void @test_nostack() #0 {
@@ -256,10 +272,10 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
   %call = tail call i32 @callee(i32 %x) #0
   ret i32 %call
 
-; ARM-linux:      test_sibling_call_empty_frame:
+; ARM-linux-LABEL: test_sibling_call_empty_frame:
 ; ARM-linux:      bl      __morestack
 
-; ARM-android:      test_sibling_call_empty_frame:
+; ARM-android-LABEL: test_sibling_call_empty_frame:
 ; ARM-android:      bl      __morestack
 
 }

diff  --git a/llvm/test/CodeGen/Thumb/segmented-stacks.ll b/llvm/test/CodeGen/Thumb/segmented-stacks.ll
index 7340842a42f41..6ad8cf9f20d2d 100644
--- a/llvm/test/CodeGen/Thumb/segmented-stacks.ll
+++ b/llvm/test/CodeGen/Thumb/segmented-stacks.ll
@@ -116,13 +116,14 @@ define void @test_large() #0 {
 
 ; Thumb-android:      push    {r4, r5}
 ; Thumb-android-NEXT: mov     r5, sp
-; Thumb-android-NEXT: sub     r5, #40192
 ; Thumb-android-NEXT: ldr     r4, .LCPI2_2
+; Thumb-android-NEXT: sub     r5, r5, r4
+; Thumb-android-NEXT: ldr     r4, .LCPI2_3
 ; Thumb-android-NEXT: ldr     r4, [r4]
 ; Thumb-android-NEXT: cmp     r4, r5
 ; Thumb-android-NEXT: blo     .LBB2_2
 
-; Thumb-android:      mov     r4, #40192
+; Thumb-android:      ldr     r4, .LCPI2_2
 ; Thumb-android-NEXT: mov     r5, #0
 ; Thumb-android-NEXT: push    {lr}
 ; Thumb-android-NEXT: bl      __morestack
@@ -133,17 +134,21 @@ define void @test_large() #0 {
 
 ; Thumb-android:      pop     {r4, r5}
 
+; Thumb-android:      .LCPI2_2:
+; Thumb-android-NEXT: .long   40192
+
 ; Thumb-linux-LABEL:      test_large:
 
 ; Thumb-linux:      push    {r4, r5}
 ; Thumb-linux-NEXT: mov     r5, sp
-; Thumb-linux-NEXT: sub     r5, #40192
 ; Thumb-linux-NEXT: ldr     r4, .LCPI2_2
+; Thumb-linux-NEXT: sub     r5, r5, r4
+; Thumb-linux-NEXT: ldr     r4, .LCPI2_3
 ; Thumb-linux-NEXT: ldr     r4, [r4]
 ; Thumb-linux-NEXT: cmp     r4, r5
 ; Thumb-linux-NEXT: blo     .LBB2_2
 
-; Thumb-linux:      mov     r4, #40192
+; Thumb-linux:      ldr     r4, .LCPI2_2
 ; Thumb-linux-NEXT: mov     r5, #0
 ; Thumb-linux-NEXT: push    {lr}
 ; Thumb-linux-NEXT: bl      __morestack
@@ -212,13 +217,14 @@ define fastcc void @test_fastcc_large() #0 {
 
 ; Thumb-android:      push    {r4, r5}
 ; Thumb-android-NEXT: mov     r5, sp
-; Thumb-android-NEXT: sub     r5, #40192
 ; Thumb-android-NEXT: ldr     r4, .LCPI4_2
+; Thumb-android-NEXT: sub     r5, r5, r4
+; Thumb-android-NEXT: ldr     r4, .LCPI4_3
 ; Thumb-android-NEXT: ldr     r4, [r4]
 ; Thumb-android-NEXT: cmp     r4, r5
 ; Thumb-android-NEXT: blo     .LBB4_2
 
-; Thumb-android:      mov     r4, #40192
+; Thumb-android:      ldr     r4, .LCPI4_2
 ; Thumb-android-NEXT: mov     r5, #0
 ; Thumb-android-NEXT: push    {lr}
 ; Thumb-android-NEXT: bl      __morestack
@@ -229,17 +235,21 @@ define fastcc void @test_fastcc_large() #0 {
 
 ; Thumb-android:      pop     {r4, r5}
 
+; Thumb-android:      .LCPI4_2:
+; Thumb-android-NEXT: .long   40192
+
 ; Thumb-linux-LABEL:      test_fastcc_large:
 
 ; Thumb-linux:      push    {r4, r5}
 ; Thumb-linux-NEXT: mov     r5, sp
-; Thumb-linux-NEXT: sub     r5, #40192
 ; Thumb-linux-NEXT: ldr     r4, .LCPI4_2
+; Thumb-linux-NEXT: sub     r5, r5, r4
+; Thumb-linux-NEXT: ldr     r4, .LCPI4_3
 ; Thumb-linux-NEXT: ldr     r4, [r4]
 ; Thumb-linux-NEXT: cmp     r4, r5
 ; Thumb-linux-NEXT: blo     .LBB4_2
 
-; Thumb-linux:      mov     r4, #40192
+; Thumb-linux:      ldr     r4, .LCPI4_2
 ; Thumb-linux-NEXT: mov     r5, #0
 ; Thumb-linux-NEXT: push    {lr}
 ; Thumb-linux-NEXT: bl      __morestack
@@ -250,6 +260,9 @@ define fastcc void @test_fastcc_large() #0 {
 
 ; Thumb-linux:      pop     {r4, r5}
 
+; Thumb-linux:      .LCPI4_2:
+; Thumb-linux-NEXT: .long   40192
+
 }
 
 define void @test_nostack() #0 {

diff  --git a/llvm/test/CodeGen/Thumb2/segmented-stacks.ll b/llvm/test/CodeGen/Thumb2/segmented-stacks.ll
index ee4dd0186b3af..0f34e9c98e893 100644
--- a/llvm/test/CodeGen/Thumb2/segmented-stacks.ll
+++ b/llvm/test/CodeGen/Thumb2/segmented-stacks.ll
@@ -67,4 +67,108 @@ define void @test_basic() #0 {
   ret void
 }
 
+define void @test_large() #0 {
+        %mem = alloca i32, i32 10000
+        call void @dummy_use (i32* %mem, i32 0)
+        ret void
+
+; THUMB-LABEL:   test_large:
+
+; THUMB:         push    {r4, r5}
+; THUMB-NEXT:    movw    r4, #40192
+; THUMB-NEXT:    mov     r5, sp
+; THUMB-NEXT:    movt    r4, #0
+; THUMB-NEXT:    sub     r5, r5, r4
+; THUMB-NEXT:    mrc     p15, #0, r4, c13, c0, #3
+; THUMB-NEXT:    ldr.w   r4, [r4, #252]
+; THUMB-NEXT:    cmp     r4, r5
+; THUMB-NEXT:    blo     .LBB1_2
+
+; THUMB:         movw    r4, #40192
+; THUMB-NEXT:    movt    r4, #0
+; THUMB-NEXT:    mov     r5, #0
+; THUMB-NEXT:    push    {lr}
+; THUMB-NEXT:    bl      __morestack
+; THUMB-NEXT:    ldr     lr, [sp], #4
+; THUMB-NEXT:    pop     {r4, r5}
+; THUMB-NEXT:    bx      lr
+
+; THUMB:         pop     {r4, r5}
+
+
+; ARM-LABEL:   test_large:
+
+; ARM:         push    {r4, r5}
+; ARM-NEXT:    ldr     r4, .LCPI1_0
+; ARM-NEXT:    sub     r5, sp, r4
+; ARM-NEXT:    mrc     p15, #0, r4, c13, c0, #3
+; ARM-NEXT:    ldr     r4, [r4, #252]
+; ARM-NEXT:    cmp     r4, r5
+; ARM-NEXT:    blo     .LBB1_2
+
+; ARM:         ldr     r4, .LCPI1_0
+; ARM-NEXT:    mov     r5, #0
+; ARM-NEXT:    stmdb   sp!, {lr}
+; ARM-NEXT:    bl      __morestack
+; ARM-NEXT:    ldm     sp!, {lr}
+; ARM-NEXT:    pop     {r4, r5}
+; ARM-NEXT:    bx      lr
+
+; ARM:         pop     {r4, r5}
+
+; ARM:         .LCPI1_0:
+; ARM-NEXT:    .long   40192
+
+}
+
+define fastcc void @test_fastcc_large() #0 {
+        %mem = alloca i32, i32 10000
+        call void @dummy_use (i32* %mem, i32 0)
+        ret void
+
+; THUMB-LABEL:   test_fastcc_large:
+
+; THUMB:         push    {r4, r5}
+; THUMB-NEXT:    movw    r4, #40192
+; THUMB-NEXT:    mov     r5, sp
+; THUMB-NEXT:    movt    r4, #0
+; THUMB-NEXT:    sub     r5, r5, r4
+; THUMB-NEXT:    mrc     p15, #0, r4, c13, c0, #3
+; THUMB-NEXT:    ldr.w   r4, [r4, #252]
+; THUMB-NEXT:    cmp     r4, r5
+; THUMB-NEXT:    blo     .LBB2_2
+
+; THUMB:         movw    r4, #40192
+; THUMB-NEXT:    movt    r4, #0
+; THUMB-NEXT:    mov     r5, #0
+; THUMB-NEXT:    push    {lr}
+; THUMB-NEXT:    bl      __morestack
+; THUMB-NEXT:    ldr     lr, [sp], #4
+; THUMB-NEXT:    pop     {r4, r5}
+; THUMB-NEXT:    bx      lr
+
+; THUMB:         pop     {r4, r5}
+
+; ARM-LABEL:   test_fastcc_large:
+
+; ARM:         push    {r4, r5}
+; ARM-NEXT:    ldr     r4, .LCPI2_0
+; ARM-NEXT:    sub     r5, sp, r4
+; ARM-NEXT:    mrc     p15, #0, r4, c13, c0, #3
+; ARM-NEXT:    ldr     r4, [r4, #252]
+; ARM-NEXT:    cmp     r4, r5
+; ARM-NEXT:    blo     .LBB2_2
+
+; ARM:         ldr     r4, .LCPI2_0
+; ARM-NEXT:    mov     r5, #0
+; ARM-NEXT:    stmdb   sp!, {lr}
+; ARM-NEXT:    bl      __morestack
+; ARM-NEXT:    ldm     sp!, {lr}
+; ARM-NEXT:    pop     {r4, r5}
+; ARM-NEXT:    bx      lr
+
+; ARM:         .LCPI2_0:
+; ARM-NEXT:    .long   40192
+}
+
 attributes #0 = { "split-stack" }


        


More information about the llvm-commits mailing list