141 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -S -passes='cgscc(inline)' -pass-remarks=inline -pass-remarks-missed=inline < %s 2> %t.err | FileCheck %s3; RUN: FileCheck -implicit-check-not=remark -check-prefix=REMARK %s < %t.err4 5; REMARK: remark: <unknown>:0:0: 'callee_with_gc' inlined into 'caller_no_gc'6; REMARK-NEXT: remark: <unknown>:0:0: 'callee_with_gc' inlined into 'caller_same_gc'7; REMARK-NEXT: remark: <unknown>:0:0: 'callee_with_gc' is not inlined into 'caller_incompatible_gc': incompatible GC8; REMARK-NEXT: remark: <unknown>:0:0: 'callee_with_gc' inlined into 'caller_inline_first_caller'9; REMARK-NEXT: remark: <unknown>:0:0: 'callee_with_other_gc' is not inlined into 'caller_inline_first_caller': incompatible GC10; REMARK-NEXT: remark: <unknown>:0:0: 'callee_with_gc' inlined into 'caller_inline_second_caller'11; REMARK-NEXT: remark: <unknown>:0:0: 'callee_with_other_gc' is not inlined into 'caller_inline_second_caller': incompatible GC12 13%IntArray = type { i32, [0 x ptr] }14 15; Callee gc propagates to the caller16define i32 @caller_no_gc() {17; CHECK-LABEL: define i32 @caller_no_gc() gc "example" {18; CHECK-NEXT: [[ROOT_I:%.*]] = alloca ptr, align 819; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[ROOT_I]])20; CHECK-NEXT: call void @llvm.gcroot(ptr [[ROOT_I]], ptr null)21; CHECK-NEXT: [[OBJ_I:%.*]] = call ptr @h()22; CHECK-NEXT: store ptr [[OBJ_I]], ptr [[ROOT_I]], align 823; CHECK-NEXT: [[LENGTH_I:%.*]] = load i32, ptr [[OBJ_I]], align 424; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[ROOT_I]])25; CHECK-NEXT: ret i32 [[LENGTH_I]]26;27 %x = call i32 @callee_with_gc()28 ret i32 %x29}30 31; Inline of matching gc allowed.32define i32 @caller_same_gc() gc "example" {33; CHECK-LABEL: define i32 @caller_same_gc() gc "example" {34; CHECK-NEXT: [[ROOT_I:%.*]] = alloca ptr, align 835; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[ROOT_I]])36; CHECK-NEXT: call void @llvm.gcroot(ptr [[ROOT_I]], ptr null)37; CHECK-NEXT: [[OBJ_I:%.*]] = call ptr @h()38; CHECK-NEXT: store ptr [[OBJ_I]], ptr [[ROOT_I]], align 839; CHECK-NEXT: [[LENGTH_I:%.*]] = load i32, ptr [[OBJ_I]], align 440; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[ROOT_I]])41; CHECK-NEXT: ret i32 [[LENGTH_I]]42;43 %x = call i32 @callee_with_gc()44 ret i32 %x45}46 47; Reject inline with mismatched gc48define i32 @caller_incompatible_gc() gc "incompatible" {49; CHECK-LABEL: define i32 @caller_incompatible_gc() gc "incompatible" {50; CHECK-NEXT: [[X:%.*]] = call i32 @callee_with_gc()51; CHECK-NEXT: ret i32 [[X]]52;53 %x = call i32 @callee_with_gc()54 ret i32 %x55}56 57define i32 @callee_with_gc() gc "example" {58; CHECK-LABEL: define i32 @callee_with_gc() gc "example" {59; CHECK-NEXT: [[ROOT:%.*]] = alloca ptr, align 860; CHECK-NEXT: call void @llvm.gcroot(ptr [[ROOT]], ptr null)61; CHECK-NEXT: [[OBJ:%.*]] = call ptr @h()62; CHECK-NEXT: store ptr [[OBJ]], ptr [[ROOT]], align 863; CHECK-NEXT: [[LENGTH_PTR:%.*]] = getelementptr [[INTARRAY:%.*]], ptr [[OBJ]], i32 0, i32 064; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_PTR]], align 465; CHECK-NEXT: ret i32 [[LENGTH]]66;67 %root = alloca ptr, align 868 call void @llvm.gcroot(ptr %root, ptr null)69 %obj = call ptr @h()70 store ptr %obj, ptr %root, align 871 %Length.ptr = getelementptr %IntArray, ptr %obj, i32 0, i32 072 %Length = load i32, ptr %Length.ptr, align 473 ret i32 %Length74}75 76define i32 @callee_with_other_gc() gc "other-example" {77; CHECK-LABEL: define i32 @callee_with_other_gc() gc "other-example" {78; CHECK-NEXT: [[ROOT:%.*]] = alloca ptr, align 879; CHECK-NEXT: call void @llvm.gcroot(ptr [[ROOT]], ptr null)80; CHECK-NEXT: [[OBJ:%.*]] = call ptr @h()81; CHECK-NEXT: store ptr [[OBJ]], ptr [[ROOT]], align 882; CHECK-NEXT: [[LENGTH_PTR:%.*]] = getelementptr [[INTARRAY:%.*]], ptr [[OBJ]], i32 0, i32 083; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_PTR]], align 484; CHECK-NEXT: ret i32 [[LENGTH]]85;86 %root = alloca ptr, align 887 call void @llvm.gcroot(ptr %root, ptr null)88 %obj = call ptr @h()89 store ptr %obj, ptr %root, align 890 %Length.ptr = getelementptr %IntArray, ptr %obj, i32 0, i32 091 %Length = load i32, ptr %Length.ptr, align 492 ret i32 %Length93}94 95; After inlining the first call, inline is blocked of the second call96; since the gc type propagates to the caller.97define i32 @caller_inline_first_caller() {98; CHECK-LABEL: define i32 @caller_inline_first_caller() gc "example" {99; CHECK-NEXT: [[ROOT_I:%.*]] = alloca ptr, align 8100; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[ROOT_I]])101; CHECK-NEXT: call void @llvm.gcroot(ptr [[ROOT_I]], ptr null)102; CHECK-NEXT: [[OBJ_I:%.*]] = call ptr @h()103; CHECK-NEXT: store ptr [[OBJ_I]], ptr [[ROOT_I]], align 8104; CHECK-NEXT: [[LENGTH_I:%.*]] = load i32, ptr [[OBJ_I]], align 4105; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[ROOT_I]])106; CHECK-NEXT: [[Y:%.*]] = call i32 @callee_with_other_gc()107; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LENGTH_I]], [[Y]]108; CHECK-NEXT: ret i32 [[ADD]]109;110 %x = call i32 @callee_with_gc()111 %y = call i32 @callee_with_other_gc()112 %add = add i32 %x, %y113 ret i32 %add114}115 116; We can't inline the first call due to the incompatible gc, but can117; inline the second118define i32 @caller_inline_second_caller() gc "example" {119; CHECK-LABEL: define i32 @caller_inline_second_caller() gc "example" {120; CHECK-NEXT: [[ROOT_I:%.*]] = alloca ptr, align 8121; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[ROOT_I]])122; CHECK-NEXT: call void @llvm.gcroot(ptr [[ROOT_I]], ptr null)123; CHECK-NEXT: [[OBJ_I:%.*]] = call ptr @h()124; CHECK-NEXT: store ptr [[OBJ_I]], ptr [[ROOT_I]], align 8125; CHECK-NEXT: [[LENGTH_I:%.*]] = load i32, ptr [[OBJ_I]], align 4126; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[ROOT_I]])127; CHECK-NEXT: [[Y:%.*]] = call i32 @callee_with_other_gc()128; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LENGTH_I]], [[Y]]129; CHECK-NEXT: ret i32 [[ADD]]130;131 %x = call i32 @callee_with_gc()132 %y = call i32 @callee_with_other_gc()133 %add = add i32 %x, %y134 ret i32 %add135}136 137declare ptr @h()138 139declare void @llvm.gcroot(ptr, ptr) #0140attributes #0 = { nounwind }141