[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / IROutliner / outlining-isomorphic-predicates.ll
blob127f2ed821752660da0b031ac1749947f9f5ad9f
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
5 ; function.
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(
13 ; CHECK-NEXT:  entry:
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
19 entry:
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
27   ret void
30 define void @outline_slt2() {
31 ; CHECK-LABEL: @outline_slt2(
32 ; CHECK-NEXT:  entry:
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
38 entry:
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
46   ret void
49 define void @outline_sgt() {
50 ; CHECK-LABEL: @outline_sgt(
51 ; CHECK-NEXT:  entry:
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
57 entry:
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
65   ret void
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(
73 ; CHECK-NEXT:  entry:
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
83 entry:
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
91   ret void
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
97 ; first this time.
99 define void @outline_ugt1() {
100 ; CHECK-LABEL: @outline_ugt1(
101 ; CHECK-NEXT:  entry:
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
107 entry:
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
115   ret void
118 define void @outline_ugt2() {
119 ; CHECK-LABEL: @outline_ugt2(
120 ; CHECK-NEXT:  entry:
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
126 entry:
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
134   ret void
137 define void @outline_ult() {
138 ; CHECK-LABEL: @outline_ult(
139 ; CHECK-NEXT:  entry:
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
145 entry:
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
153   ret void
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]]