brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · 2bded9c Raw
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