1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s
4 ; This test checks the isomorphic comparisons can be outlined together into one
7 ; The following three function are identical, except that in the third, the
8 ; operand order, and predicate are swapped, meaning it is structurally the same
9 ; and should be outlined together.
11 define void @outline_slt1() {
12 ; CHECK-LABEL: @outline_slt1(
14 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
15 ; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
16 ; CHECK-NEXT: call void @outlined_ir_func_1(i32* [[A]], i32* [[B]])
17 ; CHECK-NEXT: ret void
20 %a = alloca i32, align 4
21 %b = alloca i32, align 4
22 store i32 2, i32* %a, align 4
23 store i32 3, i32* %b, align 4
24 %al = load i32, i32* %a
25 %bl = load i32, i32* %b
26 %0 = icmp slt i32 %al, %bl
30 define void @outline_slt2() {
31 ; CHECK-LABEL: @outline_slt2(
33 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
34 ; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
35 ; CHECK-NEXT: call void @outlined_ir_func_1(i32* [[A]], i32* [[B]])
36 ; CHECK-NEXT: ret void
39 %a = alloca i32, align 4
40 %b = alloca i32, align 4
41 store i32 2, i32* %a, align 4
42 store i32 3, i32* %b, align 4
43 %al = load i32, i32* %a
44 %bl = load i32, i32* %b
45 %0 = icmp slt i32 %al, %bl
49 define void @outline_sgt() {
50 ; CHECK-LABEL: @outline_sgt(
52 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
53 ; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
54 ; CHECK-NEXT: call void @outlined_ir_func_1(i32* [[A]], i32* [[B]])
55 ; CHECK-NEXT: ret void
58 %a = alloca i32, align 4
59 %b = alloca i32, align 4
60 store i32 2, i32* %a, align 4
61 store i32 3, i32* %b, align 4
62 %al = load i32, i32* %a
63 %bl = load i32, i32* %b
64 %0 = icmp sgt i32 %bl, %al
68 ; This has a swapped predicate, but not swapped operands, so it cannot use
69 ; the same outlined function as the ones above.
71 define void @dontoutline_sgt() {
72 ; CHECK-LABEL: @dontoutline_sgt(
74 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
75 ; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
76 ; CHECK-NEXT: store i32 2, i32* [[A]], align 4
77 ; CHECK-NEXT: store i32 3, i32* [[B]], align 4
78 ; CHECK-NEXT: [[AL:%.*]] = load i32, i32* [[A]], align 4
79 ; CHECK-NEXT: [[BL:%.*]] = load i32, i32* [[B]], align 4
80 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[AL]], [[BL]]
81 ; CHECK-NEXT: ret void
84 %a = alloca i32, align 4
85 %b = alloca i32, align 4
86 store i32 2, i32* %a, align 4
87 store i32 3, i32* %b, align 4
88 %al = load i32, i32* %a
89 %bl = load i32, i32* %b
90 %0 = icmp sgt i32 %al, %bl
94 ; The below functions use a different kind of predicate that is not compatible
95 ; with the ones above, and should use a different outlined function.
96 ; The other difference here is that the predicate with swapped operands comes
99 define void @outline_ugt1() {
100 ; CHECK-LABEL: @outline_ugt1(
102 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
103 ; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
104 ; CHECK-NEXT: call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
105 ; CHECK-NEXT: ret void
108 %a = alloca i32, align 4
109 %b = alloca i32, align 4
110 store i32 2, i32* %a, align 4
111 store i32 3, i32* %b, align 4
112 %al = load i32, i32* %a
113 %bl = load i32, i32* %b
114 %0 = icmp ugt i32 %al, %bl
118 define void @outline_ugt2() {
119 ; CHECK-LABEL: @outline_ugt2(
121 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
122 ; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
123 ; CHECK-NEXT: call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
124 ; CHECK-NEXT: ret void
127 %a = alloca i32, align 4
128 %b = alloca i32, align 4
129 store i32 2, i32* %a, align 4
130 store i32 3, i32* %b, align 4
131 %al = load i32, i32* %a
132 %bl = load i32, i32* %b
133 %0 = icmp ugt i32 %al, %bl
137 define void @outline_ult() {
138 ; CHECK-LABEL: @outline_ult(
140 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
141 ; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
142 ; CHECK-NEXT: call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
143 ; CHECK-NEXT: ret void
146 %a = alloca i32, align 4
147 %b = alloca i32, align 4
148 store i32 2, i32* %a, align 4
149 store i32 3, i32* %b, align 4
150 %al = load i32, i32* %a
151 %bl = load i32, i32* %b
152 %0 = icmp ult i32 %bl, %al
156 ; CHECK: define internal void @outlined_ir_func_0(i32* [[ARG0:%.*]], i32* [[ARG1:%.*]]) #0 {
157 ; CHECK: entry_to_outline:
158 ; CHECK-NEXT: store i32 2, i32* [[ARG0]], align 4
159 ; CHECK-NEXT: store i32 3, i32* [[ARG1]], align 4
160 ; CHECK-NEXT: [[AL:%.*]] = load i32, i32* [[ARG0]], align 4
161 ; CHECK-NEXT: [[BL:%.*]] = load i32, i32* [[ARG1]], align 4
162 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[AL]], [[BL]]
164 ; CHECK: define internal void @outlined_ir_func_1(i32* [[ARG0:%.*]], i32* [[ARG1:%.*]]) #0 {
165 ; CHECK: entry_to_outline:
166 ; CHECK-NEXT: store i32 2, i32* [[ARG0]], align 4
167 ; CHECK-NEXT: store i32 3, i32* [[ARG1]], align 4
168 ; CHECK-NEXT: [[AL:%.*]] = load i32, i32* [[ARG0]], align 4
169 ; CHECK-NEXT: [[BL:%.*]] = load i32, i32* [[ARG1]], align 4
170 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[AL]], [[BL]]