1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
2 ; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s
4 ; This test checks that we do not outline different intrinsics as the same
5 ; function or as a value like we would for non-intrinsic functions.
7 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1)
8 declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1)
10 define i8 @function1(i8* noalias %s, i8* noalias %d, i64 %len) {
14 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %d, i8* %s, i64 %len, i1 false)
16 %ret = load i8, i8* %s
20 define i8 @function2(i8* noalias %s, i8* noalias %d, i64 %len) {
24 call void @llvm.memmove.p0i8.p0i8.i64(i8* %d, i8* %s, i64 %len, i1 false)
26 %ret = load i8, i8* %s
29 ; CHECK-LABEL: @function1(
31 ; CHECK-NEXT: [[B_LOC:%.*]] = alloca i8, align 1
32 ; CHECK-NEXT: [[A_LOC:%.*]] = alloca i8, align 1
33 ; CHECK-NEXT: [[RET_LOC:%.*]] = alloca i8, align 1
34 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[A_LOC]])
35 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[B_LOC]])
36 ; CHECK-NEXT: call void @outlined_ir_func_1(i8* [[S:%.*]], i8* [[D:%.*]], i8* [[A_LOC]], i8* [[B_LOC]])
37 ; CHECK-NEXT: [[A_RELOAD:%.*]] = load i8, i8* [[A_LOC]], align 1
38 ; CHECK-NEXT: [[B_RELOAD:%.*]] = load i8, i8* [[B_LOC]], align 1
39 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[A_LOC]])
40 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[B_LOC]])
41 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[D]], i8* [[S]], i64 [[LEN:%.*]], i1 false)
42 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[RET_LOC]])
43 ; CHECK-NEXT: call void @outlined_ir_func_0(i8 [[A_RELOAD]], i8 [[B_RELOAD]], i8* [[S]], i8* [[RET_LOC]])
44 ; CHECK-NEXT: [[RET_RELOAD:%.*]] = load i8, i8* [[RET_LOC]], align 1
45 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[RET_LOC]])
46 ; CHECK-NEXT: ret i8 [[RET_RELOAD]]
49 ; CHECK-LABEL: @function2(
51 ; CHECK-NEXT: [[B_LOC:%.*]] = alloca i8, align 1
52 ; CHECK-NEXT: [[A_LOC:%.*]] = alloca i8, align 1
53 ; CHECK-NEXT: [[RET_LOC:%.*]] = alloca i8, align 1
54 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[A_LOC]])
55 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[B_LOC]])
56 ; CHECK-NEXT: call void @outlined_ir_func_1(i8* [[S:%.*]], i8* [[D:%.*]], i8* [[A_LOC]], i8* [[B_LOC]])
57 ; CHECK-NEXT: [[A_RELOAD:%.*]] = load i8, i8* [[A_LOC]], align 1
58 ; CHECK-NEXT: [[B_RELOAD:%.*]] = load i8, i8* [[B_LOC]], align 1
59 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[A_LOC]])
60 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[B_LOC]])
61 ; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[D]], i8* [[S]], i64 [[LEN:%.*]], i1 false)
62 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[RET_LOC]])
63 ; CHECK-NEXT: call void @outlined_ir_func_0(i8 [[A_RELOAD]], i8 [[B_RELOAD]], i8* [[S]], i8* [[RET_LOC]])
64 ; CHECK-NEXT: [[RET_RELOAD:%.*]] = load i8, i8* [[RET_LOC]], align 1
65 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[RET_LOC]])
66 ; CHECK-NEXT: ret i8 [[RET_RELOAD]]
69 ; CHECK-LABEL: define internal void @outlined_ir_func_0(
70 ; CHECK-NEXT: newFuncRoot:
71 ; CHECK-NEXT: br label [[ENTRY_TO_OUTLINE:%.*]]
72 ; CHECK: entry_to_outline:
73 ; CHECK-NEXT: [[C:%.*]] = add i8 [[TMP0:%.*]], [[TMP1:%.*]]
74 ; CHECK-NEXT: [[RET:%.*]] = load i8, i8* [[TMP2:%.*]], align 1
75 ; CHECK-NEXT: br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
76 ; CHECK: entry_after_outline.exitStub:
77 ; CHECK-NEXT: store i8 [[RET]], i8* [[TMP3:%.*]], align 1
78 ; CHECK-NEXT: ret void
81 ; CHECK-LABEL: define internal void @outlined_ir_func_1(
82 ; CHECK-NEXT: newFuncRoot:
83 ; CHECK-NEXT: br label [[ENTRY_TO_OUTLINE:%.*]]
84 ; CHECK: entry_to_outline:
85 ; CHECK-NEXT: [[A:%.*]] = load i8, i8* [[TMP0:%.*]], align 1
86 ; CHECK-NEXT: [[B:%.*]] = load i8, i8* [[TMP1:%.*]], align 1
87 ; CHECK-NEXT: br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
88 ; CHECK: entry_after_outline.exitStub:
89 ; CHECK-NEXT: store i8 [[A]], i8* [[TMP2:%.*]], align 1
90 ; CHECK-NEXT: store i8 [[B]], i8* [[TMP3:%.*]], align 1
91 ; CHECK-NEXT: ret void