brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · f31f749 Raw
309 lines · plain
1// RUN: mlir-opt -allow-unregistered-dialect %s -sccp -split-input-file | FileCheck %s2// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline="builtin.module(builtin.module(sccp))" -split-input-file | FileCheck %s --check-prefix=NESTED3// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline="builtin.module(func.func(sccp))" -split-input-file | FileCheck %s --check-prefix=FUNC4 5/// Check that a constant is properly propagated through the arguments and6/// results of a private function.7 8// CHECK-LABEL: func private @private(9func.func private @private(%arg0 : i32) -> i32 {10  // CHECK: %[[CST:.*]] = arith.constant 1 : i3211  // CHECK: return %[[CST]] : i3212 13  return %arg0 : i3214}15 16// CHECK-LABEL: func @simple_private(17func.func @simple_private() -> i32 {18  // CHECK: %[[CST:.*]] = arith.constant 1 : i3219  // CHECK: return %[[CST]] : i3220 21  %1 = arith.constant 1 : i3222  %result = call @private(%1) : (i32) -> i3223  return %result : i3224}25 26// -----27 28/// Check that a constant is properly propagated through the arguments and29/// results of a visible nested function.30 31// CHECK: func nested @nested(32func.func nested @nested(%arg0 : i32) -> i32 {33  // CHECK: %[[CST:.*]] = arith.constant 1 : i3234  // CHECK: return %[[CST]] : i3235 36  return %arg0 : i3237}38 39// CHECK-LABEL: func @simple_nested(40func.func @simple_nested() -> i32 {41  // CHECK: %[[CST:.*]] = arith.constant 1 : i3242  // CHECK: return %[[CST]] : i3243 44  %1 = arith.constant 1 : i3245  %result = call @nested(%1) : (i32) -> i3246  return %result : i3247}48 49// -----50 51/// Check that non-visible nested functions do not track arguments.52module {53  // NESTED-LABEL: module @nested_module54  module @nested_module attributes { sym_visibility = "public" } {55 56    // NESTED: func nested @nested(57    func.func nested @nested(%arg0 : i32) -> (i32, i32) {58      // NESTED: %[[CST:.*]] = arith.constant 1 : i3259      // NESTED: return %[[CST]], %arg0 : i32, i3260 61      %1 = arith.constant 1 : i3262      return %1, %arg0 : i32, i3263    }64 65    // NESTED: func @nested_not_all_uses_visible(66    func.func @nested_not_all_uses_visible() -> (i32, i32) {67      // NESTED: %[[CST:.*]] = arith.constant 1 : i3268      // NESTED: %[[CALL:.*]]:2 = call @nested69      // NESTED: return %[[CST]], %[[CALL]]#1 : i32, i3270 71      %1 = arith.constant 1 : i3272      %result:2 = call @nested(%1) : (i32) -> (i32, i32)73      return %result#0, %result#1 : i32, i3274    }75  }76}77 78// -----79 80/// Check that public functions do not track arguments.81 82// CHECK-LABEL: func @public(83func.func @public(%arg0 : i32) -> (i32, i32) {84  %1 = arith.constant 1 : i3285  return %1, %arg0 : i32, i3286}87 88// CHECK-LABEL: func @simple_public(89func.func @simple_public() -> (i32, i32) {90  // CHECK: %[[CST:.*]] = arith.constant 1 : i3291  // CHECK: %[[CALL:.*]]:2 = call @public92  // CHECK: return %[[CST]], %[[CALL]]#1 : i32, i3293 94  %1 = arith.constant 1 : i3295  %result:2 = call @public(%1) : (i32) -> (i32, i32)96  return %result#0, %result#1 : i32, i3297}98 99// -----100 101/// Check that functions with non-call users don't have arguments tracked.102 103func.func private @callable(%arg0 : i32) -> (i32, i32) {104  %1 = arith.constant 1 : i32105  return %1, %arg0 : i32, i32106}107 108// CHECK-LABEL: func @non_call_users(109func.func @non_call_users() -> (i32, i32) {110  // CHECK: %[[CST:.*]] = arith.constant 1 : i32111  // CHECK: %[[CALL:.*]]:2 = call @callable112  // CHECK: return %[[CST]], %[[CALL]]#1 : i32, i32113 114  %1 = arith.constant 1 : i32115  %result:2 = call @callable(%1) : (i32) -> (i32, i32)116  return %result#0, %result#1 : i32, i32117}118 119"live.user"() {uses = [@callable]} : () -> ()120 121// -----122 123/// Check that return values are overdefined in the presence of an unknown terminator.124 125func.func private @callable(%arg0 : i32) -> i32 {126  "unknown.return"(%arg0) : (i32) -> ()127}128 129// CHECK-LABEL: func @unknown_terminator(130func.func @unknown_terminator() -> i32 {131  // CHECK: %[[CALL:.*]] = call @callable132  // CHECK: return %[[CALL]] : i32133 134  %1 = arith.constant 1 : i32135  %result = call @callable(%1) : (i32) -> i32136  return %result : i32137}138 139// -----140 141/// Check that return values are overdefined when the constant conflicts.142 143func.func private @callable(%arg0 : i32) -> i32 {144  return %arg0 : i32145}146 147// CHECK-LABEL: func @conflicting_constant(148func.func @conflicting_constant() -> (i32, i32) {149  // CHECK: %[[CALL1:.*]] = call @callable150  // CHECK: %[[CALL2:.*]] = call @callable151  // CHECK: return %[[CALL1]], %[[CALL2]] : i32, i32152 153  %1 = arith.constant 1 : i32154  %2 = arith.constant 2 : i32155  %result = call @callable(%1) : (i32) -> i32156  %result2 = call @callable(%2) : (i32) -> i32157  return %result, %result2 : i32, i32158}159 160// -----161 162/// Check that return values are overdefined when the constant conflicts with a163/// non-constant.164 165func.func private @callable(%arg0 : i32) -> i32 {166  "unknown.return"(%arg0) : (i32) -> ()167}168 169// CHECK-LABEL: func @conflicting_constant(170func.func @conflicting_constant(%arg0 : i32) -> (i32, i32) {171  // CHECK: %[[CALL1:.*]] = call @callable172  // CHECK: %[[CALL2:.*]] = call @callable173  // CHECK: return %[[CALL1]], %[[CALL2]] : i32, i32174 175  %1 = arith.constant 1 : i32176  %result = call @callable(%1) : (i32) -> i32177  %result2 = call @callable(%arg0) : (i32) -> i32178  return %result, %result2 : i32, i32179}180 181// -----182 183/// Check a more complex interaction with calls and control flow.184 185// CHECK-LABEL: func private @complex_inner_if(186func.func private @complex_inner_if(%arg0 : i32) -> i32 {187  // CHECK-DAG: %[[TRUE:.*]] = arith.constant true188  // CHECK-DAG: %[[CST:.*]] = arith.constant 1 : i32189  // CHECK: cf.cond_br %[[TRUE]], ^bb1190 191  %cst_20 = arith.constant 20 : i32192  %cond = arith.cmpi ult, %arg0, %cst_20 : i32193  cf.cond_br %cond, ^bb1, ^bb2194 195^bb1:196  // CHECK: ^bb1:197  // CHECK: return %[[CST]] : i32198 199  %cst_1 = arith.constant 1 : i32200  return %cst_1 : i32201 202^bb2:203  %cst_1_2 = arith.constant 1 : i32204  %arg_inc = arith.addi %arg0, %cst_1_2 : i32205  return %arg_inc : i32206}207 208func.func private @complex_cond() -> i1209 210// CHECK-LABEL: func private @complex_callee(211func.func private @complex_callee(%arg0 : i32) -> i32 {212  // CHECK: %[[CST:.*]] = arith.constant 1 : i32213 214  %loop_cond = call @complex_cond() : () -> i1215  cf.cond_br %loop_cond, ^bb1, ^bb2216 217^bb1:218  // CHECK: ^bb1:219  // CHECK-NEXT: return %[[CST]] : i32220  return %arg0 : i32221 222^bb2:223  // CHECK: ^bb2:224  // CHECK: call @complex_inner_if(%[[CST]]) : (i32) -> i32225  // CHECK: call @complex_callee(%[[CST]]) : (i32) -> i32226  // CHECK: return %[[CST]] : i32227 228  %updated_arg = call @complex_inner_if(%arg0) : (i32) -> i32229  %res = call @complex_callee(%updated_arg) : (i32) -> i32230  return %res : i32231}232 233// CHECK-LABEL: func @complex_caller(234func.func @complex_caller(%arg0 : i32) -> i32 {235  // CHECK: %[[CST:.*]] = arith.constant 1 : i32236  // CHECK: return %[[CST]] : i32237 238  %1 = arith.constant 1 : i32239  %result = call @complex_callee(%1) : (i32) -> i32240  return %result : i32241}242 243// -----244 245/// Check that non-symbol defining callables currently go to overdefined.246 247// CHECK-LABEL: func @non_symbol_defining_callable248func.func @non_symbol_defining_callable() -> i32 {249  // CHECK: %[[RES:.*]] = call_indirect250  // CHECK: return %[[RES]] : i32251 252  %fn = "test.functional_region_op"() ({253    %1 = arith.constant 1 : i32254    "test.return"(%1) : (i32) -> ()255  }) : () -> (() -> i32)256  %res = call_indirect %fn() : () -> (i32)257  return %res : i32258}259 260// -----261 262/// Check that private callables don't get processed if they have no uses.263 264// CHECK-LABEL: func private @unreferenced_private_function265func.func private @unreferenced_private_function() -> i32 {266  // CHECK: %[[RES:.*]] = arith.select267  // CHECK: return %[[RES]] : i32268  %true = arith.constant true269  %cst0 = arith.constant 0 : i32270  %cst1 = arith.constant 1 : i32271  %result = arith.select %true, %cst0, %cst1 : i32272  return %result : i32273}274 275// -----276 277/// Check that callables outside the analysis scope are marked as external.278 279func.func private @foo() -> index {280  %0 = arith.constant 10 : index281  return %0 : index282}283 284// CHECK-LABEL: func @bar285// FUNC-LABEL: func @bar286func.func @bar(%arg0: index) -> index {287  // CHECK: %[[C10:.*]] = arith.constant 10288  %c0 = arith.constant 0 : index289  %1 = arith.constant 420 : index290  %7 = arith.cmpi eq, %arg0, %c0 : index291  cf.cond_br %7, ^bb1(%1 : index), ^bb2292 293// CHECK: ^bb1(%[[ARG:.*]]: index):294// FUNC: ^bb1(%[[ARG:.*]]: index):295^bb1(%8: index):  // 2 preds: ^bb0, ^bb4296  // CHECK-NEXT: return %[[ARG]]297  // FUNC-NEXT: return %[[ARG]]298  return %8 : index299 300// CHECK: ^bb2301// FUNC: ^bb2302^bb2:303  // FUNC-NEXT: %[[FOO:.*]] = call @foo304  %13 = call @foo() : () -> index305  // CHECK: cf.br ^bb1(%[[C10]]306  // FUNC: cf.br ^bb1(%[[FOO]]307  cf.br ^bb1(%13 : index)308}309