blob: dde75cc524344527cfd95d655f975541b144b406 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -inline -o - -S %s | FileCheck %s
; RUN: opt -passes='cgscc(inline)' %s -S | FileCheck %s
; RUN: opt -always-inline -o - -S %s | FileCheck %s
; RUN: opt -passes=always-inline -o - -S %s | FileCheck %s
declare dso_local void @foo(i8*)
; Not interesting to test.
define dso_local void @ssp(i64 %0) #0 {
%2 = alloca i64, align 8
store i64 %0, i64* %2, align 8
%3 = load i64, i64* %2, align 8
%4 = alloca i8, i64 %3, align 16
call void @foo(i8* %4)
ret void
}
; Not interesting to test.
define dso_local void @ssp_alwaysinline(i64 %0) #1 {
%2 = alloca i64, align 8
store i64 %0, i64* %2, align 8
%3 = load i64, i64* %2, align 8
%4 = alloca i8, i64 %3, align 16
call void @foo(i8* %4)
ret void
}
; @ssp should not be inlined due to mismatch stack protector.
; @ssp_alwaysinline should be inlined due to alwaysinline.
define dso_local void @nossp() {
; CHECK-LABEL: @nossp(
; CHECK-NEXT: [[TMP1:%.*]] = alloca i64, align 8
; CHECK-NEXT: call void @ssp(i64 1024)
; CHECK-NEXT: [[SAVEDSTACK:%.*]] = call i8* @llvm.stacksave()
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[TMP1]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP2]])
; CHECK-NEXT: store i64 1024, i64* [[TMP1]], align 8
; CHECK-NEXT: [[TMP3:%.*]] = load i64, i64* [[TMP1]], align 8
; CHECK-NEXT: [[TMP4:%.*]] = alloca i8, i64 [[TMP3]], align 16
; CHECK-NEXT: call void @foo(i8* [[TMP4]])
; CHECK-NEXT: [[TMP5:%.*]] = bitcast i64* [[TMP1]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP5]])
; CHECK-NEXT: call void @llvm.stackrestore(i8* [[SAVEDSTACK]])
; CHECK-NEXT: ret void
;
call void @ssp(i64 1024)
call void @ssp_alwaysinline(i64 1024)
ret void
}
; This is the same case as @nossp above. That the caller has alwaysinline is
; irrelevant. Not interesting to test.
define dso_local void @nossp_alwaysinline() #2 {
call void @ssp(i64 1024)
call void @ssp_alwaysinline(i64 1024)
ret void
}
; @nossp_alwaysinline should be inlined due to alwaysinline.
; @ssp should not be inlined due to mismatch stack protector.
; @ssp_alwaysinline should be inlined due to alwaysinline.
define dso_local void @nossp_caller() {
; CHECK-LABEL: @nossp_caller(
; CHECK-NEXT: [[TMP1:%.*]] = alloca i64, align 8
; CHECK-NEXT: [[SAVEDSTACK:%.*]] = call i8* @llvm.stacksave()
; CHECK-NEXT: call void @ssp(i64 1024)
; CHECK-NEXT: [[SAVEDSTACK_I:%.*]] = call i8* @llvm.stacksave()
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[TMP1]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP2]])
; CHECK-NEXT: store i64 1024, i64* [[TMP1]], align 8
; CHECK-NEXT: [[TMP3:%.*]] = load i64, i64* [[TMP1]], align 8
; CHECK-NEXT: [[TMP4:%.*]] = alloca i8, i64 [[TMP3]], align 16
; CHECK-NEXT: call void @foo(i8* [[TMP4]])
; CHECK-NEXT: [[TMP5:%.*]] = bitcast i64* [[TMP1]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP5]])
; CHECK-NEXT: call void @llvm.stackrestore(i8* [[SAVEDSTACK_I]])
; CHECK-NEXT: call void @llvm.stackrestore(i8* [[SAVEDSTACK]])
; CHECK-NEXT: ret void
;
call void @nossp_alwaysinline()
ret void
}
; @nossp should not be inlined due to mismatch stack protector.
define dso_local void @ssp2() #0 {
; CHECK-LABEL: @ssp2(
; CHECK-NEXT: call void @nossp()
; CHECK-NEXT: ret void
;
call void @nossp()
ret void
}
attributes #0 = { sspstrong }
attributes #1 = { sspstrong alwaysinline }
attributes #2 = { alwaysinline}