xref: /llvm-project/llvm/test/Transforms/IROutliner/outlining-commutative.ll (revision f4b925ee7078f058602fd323e25f45f1ae91ca34)
1cce473e0SAndrew Litteken; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
29dd9575cSRoman Lebedev; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
3cce473e0SAndrew Litteken
4cce473e0SAndrew Litteken; This test checks that commutative instructions where the operands are
5cce473e0SAndrew Litteken; swapped are outlined as the same function.
6cce473e0SAndrew Litteken
7cce473e0SAndrew Litteken; It also checks that non-commutative instructions outlined as different
8cce473e0SAndrew Litteken; functions when the operands are swapped;
9cce473e0SAndrew Litteken
10cce473e0SAndrew Litteken; These are identical functions, except that in the flipped functions,
11cce473e0SAndrew Litteken; the operands in the adds are commuted.  However, since add instructions
12cce473e0SAndrew Litteken; are commutative, we should still outline from all four as the same
13cce473e0SAndrew Litteken; instruction.
14cce473e0SAndrew Litteken
15cce473e0SAndrew Littekendefine void @outline_from_add1() {
16cce473e0SAndrew Litteken; CHECK-LABEL: @outline_from_add1(
17cce473e0SAndrew Litteken; CHECK-NEXT:  entry:
18cce473e0SAndrew Litteken; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
19cce473e0SAndrew Litteken; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
20cce473e0SAndrew Litteken; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
21*f4b925eeSMatt Arsenault; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
22cce473e0SAndrew Litteken; CHECK-NEXT:    ret void
23cce473e0SAndrew Litteken;
24cce473e0SAndrew Littekenentry:
25cce473e0SAndrew Litteken  %a = alloca i32, align 4
26cce473e0SAndrew Litteken  %b = alloca i32, align 4
27cce473e0SAndrew Litteken  %c = alloca i32, align 4
28*f4b925eeSMatt Arsenault  store i32 2, ptr %a, align 4
29*f4b925eeSMatt Arsenault  store i32 3, ptr %b, align 4
30*f4b925eeSMatt Arsenault  store i32 4, ptr %c, align 4
31*f4b925eeSMatt Arsenault  %al = load i32, ptr %a
32*f4b925eeSMatt Arsenault  %bl = load i32, ptr %b
33*f4b925eeSMatt Arsenault  %cl = load i32, ptr %c
34cce473e0SAndrew Litteken  %0 = add i32 %al, %bl
35cce473e0SAndrew Litteken  %1 = add i32 %al, %cl
36cce473e0SAndrew Litteken  %2 = add i32 %bl, %cl
37cce473e0SAndrew Litteken  ret void
38cce473e0SAndrew Litteken}
39cce473e0SAndrew Litteken
40cce473e0SAndrew Littekendefine void @outline_from_add2() {
41cce473e0SAndrew Litteken; CHECK-LABEL: @outline_from_add2(
42cce473e0SAndrew Litteken; CHECK-NEXT:  entry:
43cce473e0SAndrew Litteken; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
44cce473e0SAndrew Litteken; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
45cce473e0SAndrew Litteken; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
46*f4b925eeSMatt Arsenault; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
47cce473e0SAndrew Litteken; CHECK-NEXT:    ret void
48cce473e0SAndrew Litteken;
49cce473e0SAndrew Littekenentry:
50cce473e0SAndrew Litteken  %a = alloca i32, align 4
51cce473e0SAndrew Litteken  %b = alloca i32, align 4
52cce473e0SAndrew Litteken  %c = alloca i32, align 4
53*f4b925eeSMatt Arsenault  store i32 2, ptr %a, align 4
54*f4b925eeSMatt Arsenault  store i32 3, ptr %b, align 4
55*f4b925eeSMatt Arsenault  store i32 4, ptr %c, align 4
56*f4b925eeSMatt Arsenault  %al = load i32, ptr %a
57*f4b925eeSMatt Arsenault  %bl = load i32, ptr %b
58*f4b925eeSMatt Arsenault  %cl = load i32, ptr %c
59cce473e0SAndrew Litteken  %0 = add i32 %al, %bl
60cce473e0SAndrew Litteken  %1 = add i32 %al, %cl
61cce473e0SAndrew Litteken  %2 = add i32 %bl, %cl
62cce473e0SAndrew Litteken  ret void
63cce473e0SAndrew Litteken}
64cce473e0SAndrew Litteken
65cce473e0SAndrew Littekendefine void @outline_from_flipped_add3() {
66cce473e0SAndrew Litteken; CHECK-LABEL: @outline_from_flipped_add3(
67cce473e0SAndrew Litteken; CHECK-NEXT:  entry:
68cce473e0SAndrew Litteken; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
69cce473e0SAndrew Litteken; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
70cce473e0SAndrew Litteken; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
71*f4b925eeSMatt Arsenault; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
72cce473e0SAndrew Litteken; CHECK-NEXT:    ret void
73cce473e0SAndrew Litteken;
74cce473e0SAndrew Littekenentry:
75cce473e0SAndrew Litteken  %a = alloca i32, align 4
76cce473e0SAndrew Litteken  %b = alloca i32, align 4
77cce473e0SAndrew Litteken  %c = alloca i32, align 4
78*f4b925eeSMatt Arsenault  store i32 2, ptr %a, align 4
79*f4b925eeSMatt Arsenault  store i32 3, ptr %b, align 4
80*f4b925eeSMatt Arsenault  store i32 4, ptr %c, align 4
81*f4b925eeSMatt Arsenault  %al = load i32, ptr %a
82*f4b925eeSMatt Arsenault  %bl = load i32, ptr %b
83*f4b925eeSMatt Arsenault  %cl = load i32, ptr %c
84cce473e0SAndrew Litteken  %0 = add i32 %bl, %al
85cce473e0SAndrew Litteken  %1 = add i32 %cl, %al
86cce473e0SAndrew Litteken  %2 = add i32 %cl, %bl
87cce473e0SAndrew Litteken  ret void
88cce473e0SAndrew Litteken}
89cce473e0SAndrew Litteken
90cce473e0SAndrew Littekendefine void @outline_from_flipped_add4() {
91cce473e0SAndrew Litteken; CHECK-LABEL: @outline_from_flipped_add4(
92cce473e0SAndrew Litteken; CHECK-NEXT:  entry:
93cce473e0SAndrew Litteken; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
94cce473e0SAndrew Litteken; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
95cce473e0SAndrew Litteken; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
96*f4b925eeSMatt Arsenault; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
97cce473e0SAndrew Litteken; CHECK-NEXT:    ret void
98cce473e0SAndrew Litteken;
99cce473e0SAndrew Littekenentry:
100cce473e0SAndrew Litteken  %a = alloca i32, align 4
101cce473e0SAndrew Litteken  %b = alloca i32, align 4
102cce473e0SAndrew Litteken  %c = alloca i32, align 4
103*f4b925eeSMatt Arsenault  store i32 2, ptr %a, align 4
104*f4b925eeSMatt Arsenault  store i32 3, ptr %b, align 4
105*f4b925eeSMatt Arsenault  store i32 4, ptr %c, align 4
106*f4b925eeSMatt Arsenault  %al = load i32, ptr %a
107*f4b925eeSMatt Arsenault  %bl = load i32, ptr %b
108*f4b925eeSMatt Arsenault  %cl = load i32, ptr %c
109cce473e0SAndrew Litteken  %0 = add i32 %bl, %al
110cce473e0SAndrew Litteken  %1 = add i32 %cl, %al
111cce473e0SAndrew Litteken  %2 = add i32 %cl, %bl
112cce473e0SAndrew Litteken  ret void
113cce473e0SAndrew Litteken}
114cce473e0SAndrew Litteken
115cce473e0SAndrew Litteken; These are identical functions, except that in the flipped functions,
116cce473e0SAndrew Litteken; the operands in the subtractions are commuted.  Since subtraction
117cce473e0SAndrew Litteken; instructions are not commutative, we should outline the first two functions
118cce473e0SAndrew Litteken; differently than the second two functions.
119cce473e0SAndrew Litteken
120cce473e0SAndrew Littekendefine void @outline_from_sub1() {
121cce473e0SAndrew Litteken; CHECK-LABEL: @outline_from_sub1(
122cce473e0SAndrew Litteken; CHECK-NEXT:  entry:
123cce473e0SAndrew Litteken; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
124cce473e0SAndrew Litteken; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
125cce473e0SAndrew Litteken; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
126*f4b925eeSMatt Arsenault; CHECK-NEXT:    call void @outlined_ir_func_2(ptr [[A]], ptr [[B]], ptr [[C]])
127cce473e0SAndrew Litteken; CHECK-NEXT:    ret void
128cce473e0SAndrew Litteken;
129cce473e0SAndrew Littekenentry:
130cce473e0SAndrew Litteken  %a = alloca i32, align 4
131cce473e0SAndrew Litteken  %b = alloca i32, align 4
132cce473e0SAndrew Litteken  %c = alloca i32, align 4
133*f4b925eeSMatt Arsenault  store i32 2, ptr %a, align 4
134*f4b925eeSMatt Arsenault  store i32 3, ptr %b, align 4
135*f4b925eeSMatt Arsenault  store i32 4, ptr %c, align 4
136*f4b925eeSMatt Arsenault  %al = load i32, ptr %a
137*f4b925eeSMatt Arsenault  %bl = load i32, ptr %b
138*f4b925eeSMatt Arsenault  %cl = load i32, ptr %c
139cce473e0SAndrew Litteken  %0 = sub i32 %al, %bl
140cce473e0SAndrew Litteken  %1 = sub i32 %al, %cl
141cce473e0SAndrew Litteken  %2 = sub i32 %bl, %cl
142cce473e0SAndrew Litteken  ret void
143cce473e0SAndrew Litteken}
144cce473e0SAndrew Litteken
145cce473e0SAndrew Littekendefine void @outline_from_sub2() {
146cce473e0SAndrew Litteken; CHECK-LABEL: @outline_from_sub2(
147cce473e0SAndrew Litteken; CHECK-NEXT:  entry:
148cce473e0SAndrew Litteken; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
149cce473e0SAndrew Litteken; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
150cce473e0SAndrew Litteken; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
151*f4b925eeSMatt Arsenault; CHECK-NEXT:    call void @outlined_ir_func_2(ptr [[A]], ptr [[B]], ptr [[C]])
152cce473e0SAndrew Litteken; CHECK-NEXT:    ret void
153cce473e0SAndrew Litteken;
154cce473e0SAndrew Littekenentry:
155cce473e0SAndrew Litteken  %a = alloca i32, align 4
156cce473e0SAndrew Litteken  %b = alloca i32, align 4
157cce473e0SAndrew Litteken  %c = alloca i32, align 4
158*f4b925eeSMatt Arsenault  store i32 2, ptr %a, align 4
159*f4b925eeSMatt Arsenault  store i32 3, ptr %b, align 4
160*f4b925eeSMatt Arsenault  store i32 4, ptr %c, align 4
161*f4b925eeSMatt Arsenault  %al = load i32, ptr %a
162*f4b925eeSMatt Arsenault  %bl = load i32, ptr %b
163*f4b925eeSMatt Arsenault  %cl = load i32, ptr %c
164cce473e0SAndrew Litteken  %0 = sub i32 %al, %bl
165cce473e0SAndrew Litteken  %1 = sub i32 %al, %cl
166cce473e0SAndrew Litteken  %2 = sub i32 %bl, %cl
167cce473e0SAndrew Litteken  ret void
168cce473e0SAndrew Litteken}
169cce473e0SAndrew Litteken
170cce473e0SAndrew Littekendefine void @dontoutline_from_flipped_sub3() {
171cce473e0SAndrew Litteken; CHECK-LABEL: @dontoutline_from_flipped_sub3(
172cce473e0SAndrew Litteken; CHECK-NEXT:  entry:
173cce473e0SAndrew Litteken; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
174cce473e0SAndrew Litteken; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
175cce473e0SAndrew Litteken; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
176*f4b925eeSMatt Arsenault; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
177cce473e0SAndrew Litteken; CHECK-NEXT:    ret void
178cce473e0SAndrew Litteken;
179cce473e0SAndrew Littekenentry:
180cce473e0SAndrew Litteken  %a = alloca i32, align 4
181cce473e0SAndrew Litteken  %b = alloca i32, align 4
182cce473e0SAndrew Litteken  %c = alloca i32, align 4
183*f4b925eeSMatt Arsenault  store i32 2, ptr %a, align 4
184*f4b925eeSMatt Arsenault  store i32 3, ptr %b, align 4
185*f4b925eeSMatt Arsenault  store i32 4, ptr %c, align 4
186*f4b925eeSMatt Arsenault  %al = load i32, ptr %a
187*f4b925eeSMatt Arsenault  %bl = load i32, ptr %b
188*f4b925eeSMatt Arsenault  %cl = load i32, ptr %c
189cce473e0SAndrew Litteken  %0 = sub i32 %bl, %al
190cce473e0SAndrew Litteken  %1 = sub i32 %cl, %al
191cce473e0SAndrew Litteken  %2 = sub i32 %cl, %bl
192cce473e0SAndrew Litteken  ret void
193cce473e0SAndrew Litteken}
194cce473e0SAndrew Litteken
195cce473e0SAndrew Littekendefine void @dontoutline_from_flipped_sub4() {
196cce473e0SAndrew Litteken; CHECK-LABEL: @dontoutline_from_flipped_sub4(
197cce473e0SAndrew Litteken; CHECK-NEXT:  entry:
198cce473e0SAndrew Litteken; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
199cce473e0SAndrew Litteken; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
200cce473e0SAndrew Litteken; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
201*f4b925eeSMatt Arsenault; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
202cce473e0SAndrew Litteken; CHECK-NEXT:    ret void
203cce473e0SAndrew Litteken;
204cce473e0SAndrew Littekenentry:
205cce473e0SAndrew Litteken  %a = alloca i32, align 4
206cce473e0SAndrew Litteken  %b = alloca i32, align 4
207cce473e0SAndrew Litteken  %c = alloca i32, align 4
208*f4b925eeSMatt Arsenault  store i32 2, ptr %a, align 4
209*f4b925eeSMatt Arsenault  store i32 3, ptr %b, align 4
210*f4b925eeSMatt Arsenault  store i32 4, ptr %c, align 4
211*f4b925eeSMatt Arsenault  %al = load i32, ptr %a
212*f4b925eeSMatt Arsenault  %bl = load i32, ptr %b
213*f4b925eeSMatt Arsenault  %cl = load i32, ptr %c
214cce473e0SAndrew Litteken  %0 = sub i32 %bl, %al
215cce473e0SAndrew Litteken  %1 = sub i32 %cl, %al
216cce473e0SAndrew Litteken  %2 = sub i32 %cl, %bl
217cce473e0SAndrew Litteken  ret void
218cce473e0SAndrew Litteken}
219cce473e0SAndrew Litteken
220*f4b925eeSMatt Arsenault; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {
221cce473e0SAndrew Litteken; CHECK: entry_to_outline:
222*f4b925eeSMatt Arsenault; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
223*f4b925eeSMatt Arsenault; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
224*f4b925eeSMatt Arsenault; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
225*f4b925eeSMatt Arsenault; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
226*f4b925eeSMatt Arsenault; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
227*f4b925eeSMatt Arsenault; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
228cce473e0SAndrew Litteken; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[AL]], [[BL]]
229cce473e0SAndrew Litteken; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[AL]], [[CL]]
230cce473e0SAndrew Litteken; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[BL]], [[CL]]
231cce473e0SAndrew Litteken
232*f4b925eeSMatt Arsenault; CHECK: define internal void @outlined_ir_func_1(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {
233cce473e0SAndrew Litteken; CHECK: entry_to_outline:
234*f4b925eeSMatt Arsenault; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
235*f4b925eeSMatt Arsenault; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
236*f4b925eeSMatt Arsenault; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
237*f4b925eeSMatt Arsenault; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
238*f4b925eeSMatt Arsenault; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
239*f4b925eeSMatt Arsenault; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
240cce473e0SAndrew Litteken; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[BL]], [[AL]]
241cce473e0SAndrew Litteken; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[CL]], [[AL]]
242cce473e0SAndrew Litteken; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 [[CL]], [[BL]]
243cce473e0SAndrew Litteken
244*f4b925eeSMatt Arsenault; CHECK: define internal void @outlined_ir_func_2(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {
245cce473e0SAndrew Litteken; CHECK: entry_to_outline:
246*f4b925eeSMatt Arsenault; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
247*f4b925eeSMatt Arsenault; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
248*f4b925eeSMatt Arsenault; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
249*f4b925eeSMatt Arsenault; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
250*f4b925eeSMatt Arsenault; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
251*f4b925eeSMatt Arsenault; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
252cce473e0SAndrew Litteken; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[AL]], [[BL]]
253cce473e0SAndrew Litteken; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[AL]], [[CL]]
254cce473e0SAndrew Litteken; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 [[BL]], [[CL]]
255