Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / IROutliner / outlining-multiple-exits-one-output-set.ll
blob5293647ad6c4c8aefa1783361946c10f1ff62001
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
2 ; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
4 ; Here we have multiple exits, but different sources, and only one has an
5 ; output set.  We check to make sure that we do not generated extra output
6 ; blocks or entries in the switch statement.
8 define void @outline_outputs1() #0 {
9 entry:
10   %output = alloca i32, align 4
11   %result = alloca i32, align 4
12   %output2 = alloca i32, align 4
13   %result2 = alloca i32, align 4
14   %a = alloca i32, align 4
15   %b = alloca i32, align 4
16   br label %block_2
17 block_1:
18   %a2 = alloca i32, align 4
19   %b2 = alloca i32, align 4
20   br label %block_2
21 block_2:
22   %a2val = load i32, ptr %a
23   %b2val = load i32, ptr %b
24   %add2 = add i32 2, %a2val
25   %mul2 = mul i32 2, %b2val
26   br label %block_5
27 block_3:
28   %aval = load i32, ptr %a
29   %bval = load i32, ptr %b
30   %add = add i32 2, %aval
31   %mul = mul i32 2, %bval
32   br label %block_4
33 block_4:
34   store i32 %add, ptr %output, align 4
35   store i32 %mul, ptr %result, align 4
36   br label %block_6
37 block_5:
38   store i32 %add2, ptr %output, align 4
39   store i32 %mul2, ptr %result, align 4
40   br label %block_7
41 block_6:
42   ret void
43 block_7:
44   ret void
47 define void @outline_outputs2() #0 {
48 entry:
49   %output = alloca i32, align 4
50   %result = alloca i32, align 4
51   %output2 = alloca i32, align 4
52   %result2 = alloca i32, align 4
53   %a = alloca i32, align 4
54   %b = alloca i32, align 4
55   br label %block_2
56 block_1:
57   %a2 = alloca i32, align 4
58   %b2 = alloca i32, align 4
59   br label %block_2
60 block_2:
61   %a2val = load i32, ptr %a
62   %b2val = load i32, ptr %b
63   %add2 = add i32 2, %a2val
64   %mul2 = mul i32 2, %b2val
65   br label %block_5
66 block_3:
67   %aval = load i32, ptr %a
68   %bval = load i32, ptr %b
69   %add = add i32 2, %aval
70   %mul = mul i32 2, %bval
71   br label %block_4
72 block_4:
73   store i32 %add, ptr %output, align 4
74   store i32 %mul, ptr %result, align 4
75   br label %block_7
76 block_5:
77   store i32 %add2, ptr %output, align 4
78   store i32 %mul2, ptr %result, align 4
79   br label %block_6
80 block_6:
81   %diff = sub i32 %a2val, %b2val
82   ret void
83 block_7:
84   %quot = udiv i32 %add, %mul
85   ret void
87 ; CHECK-LABEL: @outline_outputs1(
88 ; CHECK-NEXT:  entry:
89 ; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
90 ; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
91 ; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
92 ; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
93 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
94 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
95 ; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
96 ; CHECK:       block_1:
97 ; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
98 ; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
99 ; CHECK-NEXT:    br label [[BLOCK_2]]
100 ; CHECK:       block_2:
101 ; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr null, ptr null, ptr null, ptr null, i32 -1)
102 ; CHECK-NEXT:    br i1 [[TMP0]], label [[BLOCK_6:%.*]], label [[BLOCK_7:%.*]]
103 ; CHECK:       block_6:
104 ; CHECK-NEXT:    ret void
105 ; CHECK:       block_7:
106 ; CHECK-NEXT:    ret void
109 ; CHECK-LABEL: @outline_outputs2(
110 ; CHECK-NEXT:  entry:
111 ; CHECK-NEXT:    [[MUL_LOC:%.*]] = alloca i32, align 4
112 ; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
113 ; CHECK-NEXT:    [[B2VAL_LOC:%.*]] = alloca i32, align 4
114 ; CHECK-NEXT:    [[A2VAL_LOC:%.*]] = alloca i32, align 4
115 ; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
116 ; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
117 ; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
118 ; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
119 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
120 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
121 ; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
122 ; CHECK:       block_1:
123 ; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
124 ; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
125 ; CHECK-NEXT:    br label [[BLOCK_2]]
126 ; CHECK:       block_2:
127 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 -1, ptr [[A2VAL_LOC]])
128 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 -1, ptr [[B2VAL_LOC]])
129 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 -1, ptr [[ADD_LOC]])
130 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 -1, ptr [[MUL_LOC]])
131 ; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[A2VAL_LOC]], ptr [[B2VAL_LOC]], ptr [[ADD_LOC]], ptr [[MUL_LOC]], i32 0)
132 ; CHECK-NEXT:    [[A2VAL_RELOAD:%.*]] = load i32, ptr [[A2VAL_LOC]], align 4
133 ; CHECK-NEXT:    [[B2VAL_RELOAD:%.*]] = load i32, ptr [[B2VAL_LOC]], align 4
134 ; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
135 ; CHECK-NEXT:    [[MUL_RELOAD:%.*]] = load i32, ptr [[MUL_LOC]], align 4
136 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 -1, ptr [[A2VAL_LOC]])
137 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 -1, ptr [[B2VAL_LOC]])
138 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 -1, ptr [[ADD_LOC]])
139 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 -1, ptr [[MUL_LOC]])
140 ; CHECK-NEXT:    br i1 [[TMP0]], label [[BLOCK_7:%.*]], label [[BLOCK_6:%.*]]
141 ; CHECK:       block_6:
142 ; CHECK-NEXT:    [[DIFF:%.*]] = sub i32 [[A2VAL_RELOAD]], [[B2VAL_RELOAD]]
143 ; CHECK-NEXT:    ret void
144 ; CHECK:       block_7:
145 ; CHECK-NEXT:    [[QUOT:%.*]] = udiv i32 [[ADD_RELOAD]], [[MUL_RELOAD]]
146 ; CHECK-NEXT:    ret void
149 ; CHECK: define internal i1 @outlined_ir_func_0(
150 ; CHECK-NEXT:  newFuncRoot:
151 ; CHECK-NEXT:    br label [[BLOCK_2_TO_OUTLINE:%.*]]
152 ; CHECK:       block_2_to_outline:
153 ; CHECK-NEXT:    [[A2VAL:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
154 ; CHECK-NEXT:    [[B2VAL:%.*]] = load i32, ptr [[TMP1:%.*]], align 4
155 ; CHECK-NEXT:    [[ADD2:%.*]] = add i32 2, [[A2VAL]]
156 ; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 2, [[B2VAL]]
157 ; CHECK-NEXT:    br label [[BLOCK_5:%.*]]
158 ; CHECK:       block_3:
159 ; CHECK-NEXT:    [[AVAL:%.*]] = load i32, ptr [[TMP0]], align 4
160 ; CHECK-NEXT:    [[BVAL:%.*]] = load i32, ptr [[TMP1]], align 4
161 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 2, [[AVAL]]
162 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 2, [[BVAL]]
163 ; CHECK-NEXT:    br label [[BLOCK_4:%.*]]
164 ; CHECK:       block_4:
165 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP2:%.*]], align 4
166 ; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP3:%.*]], align 4
167 ; CHECK-NEXT:    br label [[BLOCK_6_EXITSTUB:%.*]]
168 ; CHECK:       block_5:
169 ; CHECK-NEXT:    store i32 [[ADD2]], ptr [[TMP2]], align 4
170 ; CHECK-NEXT:    store i32 [[MUL2]], ptr [[TMP3]], align 4
171 ; CHECK-NEXT:    br label [[BLOCK_7_EXITSTUB:%.*]]
172 ; CHECK:       block_6.exitStub:
173 ; CHECK-NEXT:    switch i32 [[TMP8:%.*]], label [[FINAL_BLOCK_1:%.*]] [
174 ; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_1_1:%.*]]
175 ; CHECK-NEXT:    ]
176 ; CHECK:       block_7.exitStub:
177 ; CHECK-NEXT:    switch i32 [[TMP8]], label [[FINAL_BLOCK_0:%.*]] [
178 ; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_1_0:%.*]]
179 ; CHECK-NEXT:    ]
180 ; CHECK:       output_block_1_0:
181 ; CHECK-NEXT:    store i32 [[A2VAL]], ptr [[TMP4:%.*]], align 4
182 ; CHECK-NEXT:    store i32 [[B2VAL]], ptr [[TMP5:%.*]], align 4
183 ; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
184 ; CHECK:       output_block_1_1:
185 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP6:%.*]], align 4
186 ; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP7:%.*]], align 4
187 ; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
188 ; CHECK:       final_block_0:
189 ; CHECK-NEXT:    ret i1 false
190 ; CHECK:       final_block_1:
191 ; CHECK-NEXT:    ret i1 true