1; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 2 3; Test lowering of @llvm.frameaddress with packed-stack. 4 5; With back chain 6attributes #0 = { nounwind "packed-stack" "backchain" "use-soft-float"="true" } 7define i8* @fp0() #0 { 8entry: 9; CHECK-LABEL: fp0: 10; CHECK: la %r2, 152(%r15) 11; CHECK-NEXT: br %r14 12 %0 = tail call i8* @llvm.frameaddress(i32 0) 13 ret i8* %0 14} 15 16define i8* @fp0f() #0 { 17entry: 18; CHECK-LABEL: fp0f: 19; CHECK: lgr %r1, %r15 20; CHECK-NEXT: aghi %r15, -16 21; CHECK-NEXT: stg %r1, 152(%r15) 22; CHECK-NEXT: la %r2, 168(%r15) 23; CHECK-NEXT: aghi %r15, 16 24; CHECK-NEXT: br %r14 25 %0 = alloca i64, align 8 26 %1 = tail call i8* @llvm.frameaddress(i32 0) 27 ret i8* %1 28} 29 30; Without back chain 31 32attributes #1 = { nounwind "packed-stack" } 33define i8* @fp1() #1 { 34entry: 35; CHECK-LABEL: fp1: 36; CHECK: la %r2, 152(%r15) 37; CHECK-NEXT: br %r14 38 %0 = tail call i8* @llvm.frameaddress(i32 0) 39 ret i8* %0 40} 41 42; No saved registers: returning address of unused slot where backcahin would 43; have been located. 44define i8* @fp1f() #1 { 45entry: 46; CHECK-LABEL: fp1f: 47; CHECK: aghi %r15, -16 48; CHECK-NEXT: la %r2, 168(%r15) 49; CHECK-NEXT: aghi %r15, 16 50; CHECK-NEXT: br %r14 51 %0 = alloca i64, align 8 52 %1 = tail call i8* @llvm.frameaddress(i32 0) 53 ret i8* %1 54} 55 56; Saved registers: returning address for first saved GPR. 57declare void @foo(i8* %Arg) 58define i8* @fp2() #1 { 59entry: 60; CHECK-LABEL: fp2: 61; CHECK: stmg %r14, %r15, 144(%r15) 62; CHECK-NEXT: aghi %r15, -16 63; CHECK-NEXT: la %r2, 168(%r15) 64; CHECK-NEXT: brasl %r14, foo@PLT 65; CHECK-NEXT: la %r2, 168(%r15) 66; CHECK-NEXT: lmg %r14, %r15, 160(%r15) 67; CHECK-NEXT: br %r14 68 %0 = tail call i8* @llvm.frameaddress(i32 0) 69 call void @foo(i8* %0); 70 ret i8* %0 71} 72 73declare i8* @llvm.frameaddress(i32) nounwind readnone 74