[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / Transforms / IROutliner / outlining-bitcasts.ll
blob83ee0d9b45c78fe855d0cc39bd63c867b4898c6b
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 ensures that an extra output is not added when there is a bitcast
5 ; that is relocated to outside of the extraction due to a starting lifetime
6 ; instruction outside of the extracted region.
8 ; Additionally, we check that the newly added bitcast instruction is excluded in
9 ; further extractions.
11 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
12 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
14 define void @outline_bitcast_base() {
15 entry:
16   %a = alloca i32, align 4
17   %b = alloca i32, align 4
18   %c = alloca i32, align 4
19   %d = alloca i32, align 4
20   store i32 2, i32* %a, align 4
21   store i32 3, i32* %b, align 4
22   store i32 4, i32* %c, align 4
23   %X = bitcast i32* %d to i8*
24   %al = load i32, i32* %a
25   %bl = load i32, i32* %b
26   %cl = load i32, i32* %c
27   ret void
30 define void @outline_bitcast_removed() {
31 entry:
32   %a = alloca i32, align 4
33   %b = alloca i32, align 4
34   %c = alloca i32, align 4
35   %d = alloca i32, align 4
36   store i32 2, i32* %a, align 4
37   store i32 3, i32* %b, align 4
38   store i32 4, i32* %c, align 4
39   %X = bitcast i32* %d to i8*
40   %al = load i32, i32* %a
41   %bl = load i32, i32* %b
42   %cl = load i32, i32* %c
43   call void @llvm.lifetime.start.p0i8(i64 -1, i8* %X)
44   %am = load i32, i32* %b
45   %bm = load i32, i32* %a
46   %cm = load i32, i32* %c
47   call void @llvm.lifetime.end.p0i8(i64 -1, i8* %X)
48   ret void
51 ; The first bitcast is moved down to lifetime start, and, since the original
52 ; endpoint does not match the new endpoint, we cannot extract and outline the
53 ; second bitcast and set of adds.  Outlining only occurs in this case due to
54 ; the lack of a cost model, as denoted by the debug command line argument.
56 define void @outline_bitcast_base2(i32 %a, i32 %b, i32 %c) {
57 entry:
58   %d = alloca i32, align 4
59   %X = bitcast i32* %d to i8*
60   %al = add i32 %a, %b
61   %bl = add i32 %b, %a
62   %cl = add i32 %b, %c
63   %buffer = mul i32 %a, %b
64   %Y = bitcast i32* %d to i8*
65   %am = add i32 %a, %b
66   %bm = add i32 %b, %a
67   %cm = add i32 %b, %c
68   call void @llvm.lifetime.start.p0i8(i64 -1, i8* %X)
69   call void @llvm.lifetime.end.p0i8(i64 -1, i8* %X)
70   ret void
73 ; CHECK-LABEL: @outline_bitcast_base(
74 ; CHECK-NEXT:  entry:
75 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
76 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
77 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
78 ; CHECK-NEXT:    [[D:%.*]] = alloca i32, align 4
79 ; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]], i32* [[D]])
80 ; CHECK-NEXT:    ret void
83 ; CHECK-LABEL: @outline_bitcast_removed(
84 ; CHECK-NEXT:  entry:
85 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
86 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
87 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
88 ; CHECK-NEXT:    [[D:%.*]] = alloca i32, align 4
89 ; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]], i32* [[D]])
90 ; CHECK-NEXT:    [[LT_CAST1:%.*]] = bitcast i32* [[D]] to i8*
91 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[LT_CAST1]])
92 ; CHECK-NEXT:    [[AM:%.*]] = load i32, i32* [[B]], align 4
93 ; CHECK-NEXT:    [[BM:%.*]] = load i32, i32* [[A]], align 4
94 ; CHECK-NEXT:    [[CM:%.*]] = load i32, i32* [[C]], align 4
95 ; CHECK-NEXT:    [[LT_CAST:%.*]] = bitcast i32* [[D]] to i8*
96 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[LT_CAST]])
97 ; CHECK-NEXT:    ret void
100 ; CHECK-LABEL: @outline_bitcast_base2(
101 ; CHECK-NEXT:  entry:
102 ; CHECK-NEXT:    [[D:%.*]] = alloca i32, align 4
103 ; CHECK-NEXT:    [[X:%.*]] = bitcast i32* [[D]] to i8*
104 ; CHECK-NEXT:    [[AL:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
105 ; CHECK-NEXT:    [[BL:%.*]] = add i32 [[B]], [[A]]
106 ; CHECK-NEXT:    [[CL:%.*]] = add i32 [[B]], [[C:%.*]]
107 ; CHECK-NEXT:    [[BUFFER:%.*]] = mul i32 [[A]], [[B]]
108 ; CHECK-NEXT:    [[Y:%.*]] = bitcast i32* [[D]] to i8*
109 ; CHECK-NEXT:    [[AM:%.*]] = add i32 [[A]], [[B]]
110 ; CHECK-NEXT:    [[BM:%.*]] = add i32 [[B]], [[A]]
111 ; CHECK-NEXT:    [[CM:%.*]] = add i32 [[B]], [[C]]
112 ; CHECK-NEXT:    [[LT_CAST1:%.*]] = bitcast i32* [[D]] to i8*
113 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[LT_CAST1]])
114 ; CHECK-NEXT:    [[LT_CAST:%.*]] = bitcast i32* [[D]] to i8*
115 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[LT_CAST]])
116 ; CHECK-NEXT:    ret void
119 ; CHECK-LABEL: @outlined_ir_func_0(
120 ; CHECK-NEXT:  newFuncRoot:
121 ; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
122 ; CHECK:       entry_to_outline:
123 ; CHECK-NEXT:    store i32 2, i32* [[TMP0:%.*]], align 4
124 ; CHECK-NEXT:    store i32 3, i32* [[TMP1:%.*]], align 4
125 ; CHECK-NEXT:    store i32 4, i32* [[TMP2:%.*]], align 4
126 ; CHECK-NEXT:    [[X:%.*]] = bitcast i32* [[TMP3:%.*]] to i8*
127 ; CHECK-NEXT:    [[AL:%.*]] = load i32, i32* [[TMP0]], align 4
128 ; CHECK-NEXT:    [[BL:%.*]] = load i32, i32* [[TMP1]], align 4
129 ; CHECK-NEXT:    [[CL:%.*]] = load i32, i32* [[TMP2]], align 4
130 ; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
131 ; CHECK:       entry_after_outline.exitStub:
132 ; CHECK-NEXT:    ret void