Fix GCC build problem with 288f05f related to SmallVector. (#116958)
[llvm-project.git] / mlir / test / Transforms / canonicalize-dce.mlir
blob84631947970ded519a505646e4b6e9576ac5064b
1 // RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -pass-pipeline='builtin.module(func.func(canonicalize{region-simplify=aggressive}))' | FileCheck %s
3 // Test case: Simple case of deleting a dead pure op.
5 // CHECK:      func @f(%arg0: f32) {
6 // CHECK-NEXT:   return
8 func.func @f(%arg0: f32) {
9   %0 = "arith.addf"(%arg0, %arg0) : (f32, f32) -> f32
10   return
13 // -----
15 // Test case: Simple case of deleting a block argument.
17 // CHECK:      func @f(%arg0: f32)
18 // CHECK-NEXT:   "test.br"()[^bb1]
19 // CHECK-NEXT: ^bb1:
20 // CHECK-NEXT:   return
22 func.func @f(%arg0: f32) {
23   "test.br"(%arg0)[^succ] : (f32) -> ()
24 ^succ(%0: f32):
25   return
28 // -----
30 // Test case: Deleting recursively dead block arguments.
32 // CHECK:      func @f(%arg0: f32)
33 // CHECK-NEXT:   cf.br ^bb1
34 // CHECK-NEXT: ^bb1:
35 // CHECK-NEXT:   cf.br ^bb1
38 func.func @f(%arg0: f32) {
39   cf.br ^loop(%arg0: f32)
40 ^loop(%loop: f32):
41   cf.br ^loop(%loop: f32)
44 // -----
46 // Test case: Deleting recursively dead block arguments with pure ops in between.
48 // CHECK:      func @f(%arg0: f32)
49 // CHECK-NEXT:   cf.br ^bb1
50 // CHECK-NEXT: ^bb1:
51 // CHECK-NEXT:   cf.br ^bb1
53 func.func @f(%arg0: f32) {
54   cf.br ^loop(%arg0: f32)
55 ^loop(%0: f32):
56   %1 = "math.exp"(%0) : (f32) -> f32
57   cf.br ^loop(%1: f32)
60 // -----
62 // Test case: Delete block arguments for cf.cond_br.
64 // CHECK:      func @f(%arg0: f32, %arg1: i1)
65 // CHECK-NEXT:   return
67 func.func @f(%arg0: f32, %pred: i1) {
68   %exp = "math.exp"(%arg0) : (f32) -> f32
69   cf.cond_br %pred, ^true(%exp: f32), ^false(%exp: f32)
70 ^true(%0: f32):
71   return
72 ^false(%1: f32):
73   return
76 // -----
78 // Test case: Recursively DCE into enclosed regions.
80 // CHECK:      func.func @f(%arg0: f32)
81 // CHECK-NOT:     arith.addf
83 func.func @f(%arg0: f32) {
84   "test.region"() (
85     {
86       %0 = "arith.addf"(%arg0, %arg0) : (f32, f32) -> f32
87     }
88   ) : () -> ()
89   return
92 // -----
94 // Test case: Don't delete pure ops that feed into returns.
96 // CHECK:      func @f(%arg0: f32) -> f32
97 // CHECK-NEXT:   [[VAL0:%.+]] = arith.addf %arg0, %arg0 : f32
98 // CHECK-NEXT:   return [[VAL0]] : f32
100 func.func @f(%arg0: f32) -> f32 {
101   %0 = "arith.addf"(%arg0, %arg0) : (f32, f32) -> f32
102   return %0 : f32
105 // -----
107 // Test case: Don't delete potentially side-effecting ops.
109 // CHECK:      func @f(%arg0: f32)
110 // CHECK-NEXT:   "foo.print"(%arg0) : (f32) -> ()
111 // CHECK-NEXT:   return
113 func.func @f(%arg0: f32) {
114   "foo.print"(%arg0) : (f32) -> ()
115   return
118 // -----
120 // Test case: Uses in nested regions are deleted correctly.
122 // CHECK:      func @f(%arg0: f32)
123 // CHECK-NEXT:   "foo.has_region"
124 // CHECK-NEXT:     "foo.return"
126 func.func @f(%arg0: f32) {
127   %0 = "math.exp"(%arg0) : (f32) -> f32
128   "foo.has_region"() ({
129     %1 = "math.exp"(%0) : (f32) -> f32
130     "foo.return"() : () -> ()
131   }) : () -> ()
132   return
135 // -----
137 // Test case: Test the mechanics of deleting multiple block arguments.
139 // CHECK:      func @f(%arg0: tensor<1xf32>, %arg1: tensor<2xf32>, %arg2: tensor<3xf32>, %arg3: tensor<4xf32>, %arg4: tensor<5xf32>)
140 // CHECK-NEXT:   "test.br"()[^bb1]
141 // CHECK-NEXT: ^bb1:
142 // CHECK-NEXT:   "foo.print"(%arg1)
143 // CHECK-NEXT:   "foo.print"(%arg3)
144 // CHECK-NEXT:   return
147 func.func @f(
148   %arg0: tensor<1xf32>,
149   %arg1: tensor<2xf32>,
150   %arg2: tensor<3xf32>,
151   %arg3: tensor<4xf32>,
152   %arg4: tensor<5xf32>) {
153   "test.br"(%arg0, %arg1, %arg2, %arg3, %arg4)[^succ] : (tensor<1xf32>, tensor<2xf32>, tensor<3xf32>, tensor<4xf32>, tensor<5xf32>) -> ()
154 ^succ(%t1: tensor<1xf32>, %t2: tensor<2xf32>, %t3: tensor<3xf32>, %t4: tensor<4xf32>, %t5: tensor<5xf32>):
155   "foo.print"(%t2) : (tensor<2xf32>) -> ()
156   "foo.print"(%t4) : (tensor<4xf32>) -> ()
157   return
160 // -----
162 // Test case: Test values with use-def cycles are deleted properly.
164 // CHECK:      func @f()
165 // CHECK-NEXT:   test.graph_region
166 // CHECK-NEXT:     "test.terminator"() : () -> ()
168 func.func @f() {
169   test.graph_region {
170     %0 = "math.exp"(%1) : (f32) -> f32
171     %1 = "math.exp"(%0) : (f32) -> f32
172     "test.terminator"() : ()->()
173   }
174   return
177 // -----
180 // Test case: Delete ops that only have side-effects on an allocated result.
182 // CHECK:      func @f()
183 // CHECK-NOT:    test_effects_result
184 // CHECK-NEXT:   return
186 func.func @f() {
187   %0 = "test.test_effects_result"() : () -> i32
188   return