98 lines
3.5 KiB
LLVM
98 lines
3.5 KiB
LLVM
|
; 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}
|