| # RUN: llc -mtriple=s390x-linux-gnu -start-before=prolog-epilog %s -o - -mcpu=z14 \ | |
| # RUN: -debug-only=prolog-epilog -print-after=prolog-epilog -verify-machineinstrs 2>&1 \ | |
| # RUN: | FileCheck %s | |
| # REQUIRES: asserts | |
| # | |
| # Test that stack objects are ordered in a good way with respect to the | |
| # displacement operands of users. | |
| --- | | |
| define void @f1() { ret void } | |
| define void @f2() { ret void } | |
| define void @f3() { ret void } | |
| define void @f4() { ret void } | |
| define void @f5() { ret void } | |
| define void @f6() { ret void } | |
| ... | |
| ### Test that %stack.0 is placed close to its D12 user. | |
| # CHECK: alloc FI(1) at SP[-4255] | |
| # CHECK-NEXT: alloc FI(0) at SP[-4271] | |
| # CHECK-NEXT: alloc FI(2) at SP[-4280] | |
| # CHECK-NEXT: alloc FI(3) at SP[-4288] | |
| # CHECK-NEXT: # *** IR Dump After Prologue/Epilogue Insertion & Frame Finalization | |
| # CHECK-NEXT: # Machine code for function f1: IsSSA, NoPHIs, TracksLiveness, NoVRegs | |
| # CHECK-NOT: LAY | |
| # CHECK: VL32 | |
| --- | |
| name: f1 | |
| tracksRegLiveness: true | |
| stack: | |
| - { id: 0, size: 16 } | |
| - { id: 1, size: 4095 } | |
| machineFunctionInfo: {} | |
| body: | | |
| bb.0: | |
| renamable $f0s = VL32 %stack.0, 0, $noreg | |
| Return | |
| ... | |
| ### Test that %stack.1 is placed close to its D12 user. | |
| # CHECK: alloc FI(0) at SP[-176] | |
| # CHECK-NEXT: alloc FI(1) at SP[-4271] | |
| # CHECK-NEXT: alloc FI(2) at SP[-4280] | |
| # CHECK-NEXT: alloc FI(3) at SP[-4288] | |
| # CHECK-NEXT: # *** IR Dump After Prologue/Epilogue Insertion & Frame Finalization | |
| # CHECK-NEXT: # Machine code for function f2: IsSSA, NoPHIs, TracksLiveness, NoVRegs | |
| # CHECK-NOT: LAY | |
| # CHECK: VL32 | |
| --- | |
| name: f2 | |
| tracksRegLiveness: true | |
| stack: | |
| - { id: 0, size: 16 } | |
| - { id: 1, size: 4095 } | |
| machineFunctionInfo: {} | |
| body: | | |
| bb.0: | |
| renamable $f0s = VL32 %stack.1, 3916, $noreg | |
| Return | |
| ... | |
| ### Swap the order of the objects so that both accesses are in range. | |
| # CHECK: alloc FI(1) at SP[-8350] | |
| # CHECK-NEXT: alloc FI(0) at SP[-12445] | |
| # CHECK-NEXT: alloc FI(2) at SP[-12456] | |
| # CHECK-NEXT: alloc FI(3) at SP[-12464] | |
| # CHECK-NEXT: # *** IR Dump After Prologue/Epilogue Insertion & Frame Finalization | |
| # CHECK-NEXT: # Machine code for function f3: IsSSA, NoPHIs, TracksLiveness, NoVRegs | |
| # CHECK-NOT: LAY | |
| # CHECK: VL32 | |
| # CHECK-NOT: LAY | |
| # CHECK: LEY | |
| --- | |
| name: f3 | |
| tracksRegLiveness: true | |
| stack: | |
| - { id: 0, size: 4095 } | |
| - { id: 1, size: 8190 } | |
| machineFunctionInfo: {} | |
| body: | | |
| bb.0: | |
| renamable $f0s = VL32 %stack.0, 0, $noreg | |
| renamable $f0s = LE %stack.1, 0, $noreg | |
| Return | |
| ... | |
| ### Reorder the objects so that all accesses are in range. | |
| # CHECK: alloc FI(0) at SP[-8350] | |
| # CHECK-NEXT: alloc FI(2) at SP[-16540] | |
| # CHECK-NEXT: alloc FI(3) at SP[-24730] | |
| # CHECK-NEXT: alloc FI(1) at SP[-26777] | |
| # CHECK-NEXT: alloc FI(4) at SP[-28824] | |
| # CHECK-NEXT: alloc FI(5) at SP[-28832] | |
| # CHECK-NEXT: alloc FI(6) at SP[-28840] | |
| # CHECK-NEXT: # *** IR Dump After Prologue/Epilogue Insertion & Frame Finalization | |
| # CHECK-NEXT: # Machine code for function f4: IsSSA, NoPHIs, TracksLiveness, NoVRegs | |
| # CHECK-NOT: LAY | |
| # CHECK: LEY | |
| # CHECK-NEXT: VL32 | |
| # CHECK-NEXT: LEY | |
| # CHECK-NEXT: LEY | |
| # CHECK-NEXT: VL32 | |
| --- | |
| name: f4 | |
| tracksRegLiveness: true | |
| stack: | |
| - { id: 0, size: 8190 } | |
| - { id: 1, size: 2047 } | |
| - { id: 2, size: 8190 } | |
| - { id: 3, size: 8190 } | |
| - { id: 4, size: 2047 } | |
| machineFunctionInfo: {} | |
| body: | | |
| bb.0: | |
| renamable $f2s = LE %stack.0, 0, $noreg | |
| renamable $f0s = VL32 %stack.1, 0, $noreg | |
| renamable $f3s = LEY %stack.2, 0, $noreg | |
| renamable $f4s = LE %stack.3, 0, $noreg | |
| renamable $f1s = VL32 %stack.4, 0, $noreg | |
| Return | |
| ... | |
| ### Reorder the objects so that the VL32 object is in range and the LYs are | |
| ### shortened to Ls (STOC cannot be shortened). | |
| # CHECK: alloc FI(0) at SP[-8350] | |
| # CHECK-NEXT: alloc FI(1) at SP[-16540] | |
| # CHECK-NEXT: alloc FI(2) at SP[-24730] | |
| # CHECK-NEXT: alloc FI(3) at SP[-26777] | |
| # CHECK-NEXT: alloc FI(4) at SP[-26792] | |
| # CHECK-NEXT: alloc FI(5) at SP[-26800] | |
| # CHECK-NEXT: # *** IR Dump After Prologue/Epilogue Insertion & Frame Finalization | |
| # CHECK-NEXT: # Machine code for function f5: IsSSA, NoPHIs, TracksLiveness, NoVRegs | |
| # CHECK-NOT: LAY | |
| # CHECK: $r1l = L $r15 | |
| # CHECK-NEXT: $r1l = L $r15 | |
| # CHECK-NEXT: IMPLICIT_DEF | |
| # CHECK-NEXT: STOC | |
| # CHECK-NEXT: STOC | |
| # CHECK-NEXT: VL32 | |
| --- | |
| name: f5 | |
| tracksRegLiveness: true | |
| stack: | |
| - { id: 0, size: 8190 } | |
| - { id: 1, size: 8190 } | |
| - { id: 2, size: 8190 } | |
| - { id: 3, size: 2047 } | |
| machineFunctionInfo: {} | |
| body: | | |
| bb.0: | |
| $r1l = LY %stack.2, 0, $noreg | |
| $r1l = LY %stack.2, 0, $noreg | |
| $cc = IMPLICIT_DEF | |
| STOC $r1l, %stack.0, 0, 14, 8, implicit $cc | |
| STOC $r1l, %stack.1, 0, 14, 8, implicit $cc | |
| renamable $f3s = VL32 %stack.3, 0, $noreg | |
| Return | |
| ... | |
| ### Test handling of a variable sized object. | |
| # CHECK: alloc FI(1) at SP[-476] | |
| # CHECK-NEXT: alloc FI(0) at SP[-776] | |
| # CHECK-NEXT: alloc FI(2) at SP[-776] | |
| # CHECK-NEXT: # *** IR Dump After Prologue/Epilogue Insertion & Frame Finalization | |
| # CHECK-NEXT: # Machine code for function f6: IsSSA, NoPHIs, TracksLiveness, NoVRegs | |
| # CHECK: $r15d = AGHI $r15d(tied-def 0), -776, implicit-def dead $cc | |
| # CHECK: $r11d = LGR $r15d | |
| # CHECK: renamable $r2d = ADJDYNALLOC renamable $r1d, 0, $noreg | |
| # CHECK: VST64 renamable $f0d, $r11d, 160, $noreg | |
| # CHECK: VST32 renamable $f1s, $r11d, 460, $noreg | |
| # CHECK: VST32 killed renamable $f0s, killed renamable $r2d, 0, $noreg | |
| --- | |
| name: f6 | |
| tracksRegLiveness: true | |
| stack: | |
| - { id: 0, size: 300 } | |
| - { id: 1, size: 316 } | |
| - { id: 2, type: variable-sized } | |
| machineFunctionInfo: {} | |
| body: | | |
| bb.0 (%ir-block.0): | |
| liveins: $f0d, $f0s, $f1s, $r2l | |
| renamable $r2l = KILL $r2l, implicit-def $r2d | |
| renamable $r1d = RISBGN undef renamable $r1d, killed renamable $r2d, 30, 189, 2 | |
| renamable $r0d = nuw LA killed renamable $r1d, 7, $noreg | |
| renamable $r0d = RISBGN undef renamable $r0d, killed renamable $r0d, 29, 188, 0 | |
| renamable $r1d = SGRK $r15d, killed renamable $r0d, implicit-def dead $cc | |
| renamable $r2d = ADJDYNALLOC renamable $r1d, 0, $noreg | |
| $r15d = COPY killed renamable $r1d | |
| VST64 renamable $f0d, %stack.0, 0, $noreg | |
| VST32 renamable $f1s, %stack.1, 0, $noreg | |
| VST32 killed renamable $f0s, killed renamable $r2d, 0, $noreg | |
| Return | |
| ... |