1; RUN: opt -S -hotcoldsplit -hotcoldsplit-threshold=0 < %s 2>&1 | FileCheck %s 2 3declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) 4 5declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) 6 7declare void @use(i8*) 8 9declare void @cold_use2(i8*, i8*) cold 10 11; CHECK-LABEL: define {{.*}}@foo( 12define void @foo() { 13entry: 14 %local1 = alloca i256 15 %local2 = alloca i256 16 %local1_cast = bitcast i256* %local1 to i8* 17 %local2_cast = bitcast i256* %local2 to i8* 18 br i1 undef, label %normalPath, label %outlinedPath 19 20normalPath: 21 ; These two uses of stack slots are non-overlapping. Based on this alone, 22 ; the stack slots could be merged. 23 call void @llvm.lifetime.start.p0i8(i64 1, i8* %local1_cast) 24 call void @use(i8* %local1_cast) 25 call void @llvm.lifetime.end.p0i8(i64 1, i8* %local1_cast) 26 call void @llvm.lifetime.start.p0i8(i64 1, i8* %local2_cast) 27 call void @use(i8* %local2_cast) 28 call void @llvm.lifetime.end.p0i8(i64 1, i8* %local2_cast) 29 ret void 30 31; CHECK-LABEL: codeRepl: 32; CHECK: [[local1_cast:%.*]] = bitcast i256* %local1 to i8* 33; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[local1_cast]]) 34; CHECK-NEXT: [[local2_cast:%.*]] = bitcast i256* %local2 to i8* 35; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[local2_cast]]) 36; CHECK-NEXT: call i1 @foo.cold.1(i8* %local1_cast, i8* %local2_cast) 37; CHECK-NEXT: br i1 38 39outlinedPath: 40 ; These two uses of stack slots are overlapping. This should prevent 41 ; merging of stack slots. CodeExtractor must replicate the effects of 42 ; these markers in the caller to inhibit stack coloring. 43 %gep1 = getelementptr inbounds i8, i8* %local1_cast, i64 1 44 call void @llvm.lifetime.start.p0i8(i64 1, i8* %gep1) 45 call void @llvm.lifetime.start.p0i8(i64 1, i8* %local2_cast) 46 call void @cold_use2(i8* %local1_cast, i8* %local2_cast) 47 call void @llvm.lifetime.end.p0i8(i64 1, i8* %gep1) 48 call void @llvm.lifetime.end.p0i8(i64 1, i8* %local2_cast) 49 br i1 undef, label %outlinedPath2, label %outlinedPathExit 50 51outlinedPath2: 52 ; These extra lifetime markers are used to test that we emit only one 53 ; pair of guard markers in the caller per memory object. 54 call void @llvm.lifetime.start.p0i8(i64 1, i8* %local2_cast) 55 call void @use(i8* %local2_cast) 56 call void @llvm.lifetime.end.p0i8(i64 1, i8* %local2_cast) 57 ret void 58 59outlinedPathExit: 60 ret void 61} 62 63; CHECK-LABEL: define {{.*}}@foo.cold.1( 64; CHECK-NOT: @llvm.lifetime 65