[clang-tidy][NFC]remove deps of clang in clang tidy test (#116588)
[llvm-project.git] / mlir / test / Dialect / LLVMIR / canonicalize.mlir
blob15f960167cb5f329a89e1fade0f80e396f2d283a
1 // RUN: mlir-opt --pass-pipeline='builtin.module(llvm.func(canonicalize{test-convergence}))' %s -split-input-file | FileCheck %s
3 // CHECK-LABEL: @fold_icmp_eq
4 llvm.func @fold_icmp_eq(%arg0 : i32) -> i1 {
5   // CHECK: %[[C0:.*]] = llvm.mlir.constant(true) : i1
6   %0 = llvm.icmp "eq" %arg0, %arg0 : i32
7   // CHECK: llvm.return %[[C0]]
8   llvm.return %0 : i1
11 // -----
13 // CHECK-LABEL: @fold_icmp_ne
14 llvm.func @fold_icmp_ne(%arg0 : vector<2xi32>) -> vector<2xi1> {
15   // CHECK: %[[C0:.*]] = llvm.mlir.constant(dense<false> : vector<2xi1>) : vector<2xi1>
16   %0 = llvm.icmp "ne" %arg0, %arg0 : vector<2xi32>
17   // CHECK: llvm.return %[[C0]]
18   llvm.return %0 : vector<2xi1>
21 // -----
23 // CHECK-LABEL: @fold_icmp_alloca
24 llvm.func @fold_icmp_alloca() -> i1 {
25   // CHECK: %[[C0:.*]] = llvm.mlir.constant(true) : i1
26   %c0 = llvm.mlir.zero : !llvm.ptr
27   %c1 = arith.constant 1 : i64
28   %0 = llvm.alloca %c1 x i32 : (i64) -> !llvm.ptr
29   %1 = llvm.icmp "ne" %c0, %0 : !llvm.ptr
30   // CHECK: llvm.return %[[C0]]
31   llvm.return %1 : i1
34 // -----
36 // CHECK-LABEL: fold_extractvalue
37 llvm.func @fold_extractvalue() -> i32 {
38   //  CHECK-DAG: %[[C0:.*]] = arith.constant 0 : i32
39   %c0 = arith.constant 0 : i32
40   //  CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32
41   %c1 = arith.constant 1 : i32
43   %0 = llvm.mlir.undef : !llvm.struct<(i32, i32)>
45   // CHECK-NOT: insertvalue
46   %1 = llvm.insertvalue %c0, %0[0] : !llvm.struct<(i32, i32)>
47   %2 = llvm.insertvalue %c1, %1[1] : !llvm.struct<(i32, i32)>
49   // CHECK-NOT: extractvalue
50   %3 = llvm.extractvalue %2[0] : !llvm.struct<(i32, i32)>
51   %4 = llvm.extractvalue %2[1] : !llvm.struct<(i32, i32)>
53   //     CHECK: llvm.add %[[C0]], %[[C1]]
54   %5 = llvm.add %3, %4 : i32
55   llvm.return %5 : i32
58 // -----
60 // CHECK-LABEL: no_fold_extractvalue
61 llvm.func @no_fold_extractvalue(%arr: !llvm.array<4 x f32>) -> f32 {
62   %f0 = arith.constant 0.0 : f32
63   %0 = llvm.mlir.undef : !llvm.array<4 x !llvm.array<4 x f32>>
65   // CHECK: insertvalue
66   // CHECK: insertvalue
67   // CHECK: extractvalue
68   %1 = llvm.insertvalue %f0, %0[0, 0] : !llvm.array<4 x !llvm.array<4 x f32>>
69   %2 = llvm.insertvalue %arr, %1[0] : !llvm.array<4 x !llvm.array<4 x f32>>
70   %3 = llvm.extractvalue %2[0, 0] : !llvm.array<4 x !llvm.array<4 x f32>>
72   llvm.return %3 : f32
75 // -----
77 // CHECK-LABEL: fold_unrelated_extractvalue
78 llvm.func @fold_unrelated_extractvalue(%arr: !llvm.array<4 x f32>) -> f32 {
79   %f0 = arith.constant 0.0 : f32
80   // CHECK-NOT: insertvalue
81   // CHECK: extractvalue
82   %2 = llvm.insertvalue %f0, %arr[0] : !llvm.array<4 x f32>
83   %3 = llvm.extractvalue %2[1] : !llvm.array<4 x f32>
84   llvm.return %3 : f32
87 // -----
89 // CHECK-LABEL: fold_bitcast
90 // CHECK-SAME: %[[ARG:[[:alnum:]]+]]
91 // CHECK-NEXT: llvm.return %[[ARG]]
92 llvm.func @fold_bitcast(%x : !llvm.ptr) -> !llvm.ptr {
93   %c = llvm.bitcast %x : !llvm.ptr to !llvm.ptr
94   llvm.return %c : !llvm.ptr
97 // -----
99 // CHECK-LABEL: fold_bitcast2
100 // CHECK-SAME: %[[ARG:[[:alnum:]]+]]
101 // CHECK-NEXT: llvm.return %[[ARG]]
102 llvm.func @fold_bitcast2(%x : i32) -> i32 {
103   %c = llvm.bitcast %x : i32 to f32
104   %d = llvm.bitcast %c : f32 to i32
105   llvm.return %d : i32
108 // -----
110 // CHECK-LABEL: fold_bitcast_chain
111 // CHECK-SAME: %[[ARG:[[:alnum:]]+]]
112 llvm.func @fold_bitcast_chain(%x : i32) -> vector<2xi16> {
113   %c = llvm.bitcast %x : i32 to f32
114   %d = llvm.bitcast %c : f32 to vector<2xi16>
115   // CHECK: %[[BITCAST:.*]] = llvm.bitcast %[[ARG]] : i32 to vector<2xi16>
116   // CHECK: llvm.return %[[BITCAST]]
117   llvm.return %d : vector<2xi16>
120 // -----
122 // CHECK-LABEL: fold_addrcast
123 // CHECK-SAME: %[[ARG:[[:alnum:]]+]]
124 // CHECK-NEXT: llvm.return %[[ARG]]
125 llvm.func @fold_addrcast(%x : !llvm.ptr) -> !llvm.ptr {
126   %c = llvm.addrspacecast %x : !llvm.ptr to !llvm.ptr
127   llvm.return %c : !llvm.ptr
130 // -----
132 // CHECK-LABEL: fold_addrcast2
133 // CHECK-SAME: %[[ARG:[[:alnum:]]+]]
134 // CHECK-NEXT: llvm.return %[[ARG]]
135 llvm.func @fold_addrcast2(%x : !llvm.ptr) -> !llvm.ptr {
136   %c = llvm.addrspacecast %x : !llvm.ptr to !llvm.ptr<5>
137   %d = llvm.addrspacecast %c : !llvm.ptr<5> to !llvm.ptr
138   llvm.return %d : !llvm.ptr
141 // -----
143 // CHECK-LABEL: fold_addrcast_chain
144 // CHECK-SAME: %[[ARG:[[:alnum:]]+]]
145 llvm.func @fold_addrcast_chain(%x : !llvm.ptr) -> !llvm.ptr<2> {
146   %c = llvm.addrspacecast %x : !llvm.ptr to !llvm.ptr<1>
147   %d = llvm.addrspacecast %c : !llvm.ptr<1> to !llvm.ptr<2>
148   // CHECK: %[[ADDRCAST:.*]] = llvm.addrspacecast %[[ARG]] : !llvm.ptr to !llvm.ptr<2>
149   // CHECK: llvm.return %[[ADDRCAST]]
150   llvm.return %d : !llvm.ptr<2>
153 // -----
155 // CHECK-LABEL: fold_gep
156 // CHECK-SAME: %[[ARG:[[:alnum:]]+]]
157 // CHECK-NEXT: llvm.return %[[ARG]]
158 llvm.func @fold_gep(%x : !llvm.ptr) -> !llvm.ptr {
159   %c0 = arith.constant 0 : i32
160   %c = llvm.getelementptr %x[%c0] : (!llvm.ptr, i32) -> !llvm.ptr, i8
161   llvm.return %c : !llvm.ptr
164 // -----
166 // CHECK-LABEL: fold_gep_neg
167 // CHECK-SAME: %[[ARG:[[:alnum:]]+]]
168 // CHECK-NEXT: %[[RES:.*]] = llvm.getelementptr inbounds %[[ARG]][0, 1]
169 // CHECK-NEXT: llvm.return %[[RES]]
170 llvm.func @fold_gep_neg(%x : !llvm.ptr) -> !llvm.ptr {
171   %c0 = arith.constant 0 : i32
172   %0 = llvm.getelementptr inbounds %x[%c0, 1] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<(i32, i32)>
173   llvm.return %0 : !llvm.ptr
176 // -----
178 // CHECK-LABEL: fold_gep_canon
179 // CHECK-SAME: %[[ARG:[[:alnum:]]+]]
180 // CHECK-NEXT: %[[RES:.*]] = llvm.getelementptr %[[ARG]][2]
181 // CHECK-NEXT: llvm.return %[[RES]]
182 llvm.func @fold_gep_canon(%x : !llvm.ptr) -> !llvm.ptr {
183   %c2 = arith.constant 2 : i32
184   %c = llvm.getelementptr %x[%c2] : (!llvm.ptr, i32) -> !llvm.ptr, i8
185   llvm.return %c : !llvm.ptr
188 // -----
190 // Check that LLVM constants participate in cross-dialect constant folding. The
191 // resulting constant is created in the arith dialect because the last folded
192 // operation belongs to it.
193 // CHECK-LABEL: llvm_constant
194 llvm.func @llvm_constant() -> i32 {
195   // CHECK-NOT: llvm.mlir.constant
196   %0 = llvm.mlir.constant(40 : i32) : i32
197   %1 = llvm.mlir.constant(42 : i32) : i32
198   // CHECK: %[[RES:.*]] = arith.constant 82 : i32
199   // CHECK-NOT: arith.addi
200   %2 = arith.addi %0, %1 : i32
201   // CHECK: return %[[RES]]
202   llvm.return %2 : i32
205 // -----
207 // CHECK-LABEL: load_dce
208 // CHECK-NEXT: llvm.return
209 llvm.func @load_dce(%x : !llvm.ptr) {
210   %0 = llvm.load %x : !llvm.ptr -> i8
211   llvm.return
214 // -----
216 llvm.mlir.global external @fp() : !llvm.ptr
218 // CHECK-LABEL: addr_dce
219 // CHECK-NEXT: llvm.return
220 llvm.func @addr_dce(%x : !llvm.ptr) {
221   %0 = llvm.mlir.addressof @fp : !llvm.ptr
222   llvm.return
225 // -----
227 // CHECK-LABEL: alloca_dce
228 // CHECK-NEXT: llvm.return
229 llvm.func @alloca_dce() {
230   %c1_i64 = arith.constant 1 : i64
231   %0 = llvm.alloca %c1_i64 x i32 : (i64) -> !llvm.ptr
232   llvm.return
235 // -----
237 // CHECK-LABEL: func @volatile_load
238 llvm.func @volatile_load(%x : !llvm.ptr) {
239   // A volatile load may have side-effects such as a write operation to arbitrary memory.
240   // Make sure it is not removed.
241   // CHECK: llvm.load volatile
242   %0 = llvm.load volatile %x : !llvm.ptr -> i8
243   // Same with monotonic atomics and any stricter modes.
244   // CHECK: llvm.load %{{.*}} atomic monotonic
245   %2 = llvm.load %x atomic monotonic { alignment = 1 } : !llvm.ptr -> i8
246   // But not unordered!
247   // CHECK-NOT: llvm.load %{{.*}} atomic unordered
248   %3 = llvm.load %x  atomic unordered { alignment = 1 } : !llvm.ptr -> i8
249   llvm.return
252 // -----
254 // CHECK-LABEL: func @inline_asm_side_effects
255 llvm.func @inline_asm_side_effects(%x : i32) {
256   // CHECK-NOT: llvm.inline_asm "pure inline asm"
257   llvm.inline_asm "pure inline asm", "r" %x : (i32) -> ()
258   // CHECK: llvm.inline_asm has_side_effects "inline asm with side effects"
259   llvm.inline_asm has_side_effects "inline asm with side effects", "r" %x : (i32) -> ()
260   llvm.return