; 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}