brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · f17f5ff Raw
232 lines · plain
1// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline="builtin.module(func.func(sccp))" -split-input-file | FileCheck %s2 3/// Check that a constant is properly propagated when only one edge is taken.4 5// CHECK-LABEL: func @simple(6func.func @simple(%arg0 : i32) -> i32 {7  // CHECK: %[[CST:.*]] = arith.constant 1 : i328  // CHECK-NOT: scf.if9  // CHECK: return %[[CST]] : i3210 11  %cond = arith.constant true12  %res = scf.if %cond -> (i32) {13    %1 = arith.constant 1 : i3214    scf.yield %1 : i3215  } else {16    scf.yield %arg0 : i3217  }18  return %res : i3219}20 21/// Check that a constant is properly propagated when both edges produce the22/// same value.23 24// CHECK-LABEL: func @simple_both_same(25func.func @simple_both_same(%cond : i1) -> i32 {26  // CHECK: %[[CST:.*]] = arith.constant 1 : i3227  // CHECK-NOT: scf.if28  // CHECK: return %[[CST]] : i3229 30  %res = scf.if %cond -> (i32) {31    %1 = arith.constant 1 : i3232    scf.yield %1 : i3233  } else {34    %2 = arith.constant 1 : i3235    scf.yield %2 : i3236  }37  return %res : i3238}39 40/// Check that the arguments go to overdefined if the branch cannot detect when41/// a specific successor is taken.42 43// CHECK-LABEL: func @overdefined_unknown_condition(44func.func @overdefined_unknown_condition(%cond : i1, %arg0 : i32) -> i32 {45  // CHECK: %[[RES:.*]] = scf.if46  // CHECK: return %[[RES]] : i3247 48  %res = scf.if %cond -> (i32) {49    %1 = arith.constant 1 : i3250    scf.yield %1 : i3251  } else {52    scf.yield %arg0 : i3253  }54  return %res : i3255}56 57/// Check that the arguments go to overdefined if there are conflicting58/// constants.59 60// CHECK-LABEL: func @overdefined_different_constants(61func.func @overdefined_different_constants(%cond : i1) -> i32 {62  // CHECK: %[[RES:.*]] = scf.if63  // CHECK: return %[[RES]] : i3264 65  %res = scf.if %cond -> (i32) {66    %1 = arith.constant 1 : i3267    scf.yield %1 : i3268  } else {69    %2 = arith.constant 2 : i3270    scf.yield %2 : i3271  }72  return %res : i3273}74 75/// Check that arguments are properly merged across loop-like control flow.76 77// CHECK-LABEL: func @simple_loop(78func.func @simple_loop(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {79  // CHECK: %[[CST:.*]] = arith.constant 0 : i3280  // CHECK-NOT: scf.for81  // CHECK: return %[[CST]] : i3282 83  %s0 = arith.constant 0 : i3284  %result = scf.for %i0 = %arg0 to %arg1 step %arg2 iter_args(%si = %s0) -> (i32) {85    %sn = arith.addi %si, %si : i3286    scf.yield %sn : i3287  }88  return %result : i3289}90 91/// Check that arguments go to overdefined when loop backedges produce a92/// conflicting value.93 94// CHECK-LABEL: func @loop_overdefined(95func.func @loop_overdefined(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {96  // CHECK: %[[RES:.*]] = scf.for97  // CHECK: return %[[RES]] : i3298 99  %s0 = arith.constant 1 : i32100  %result = scf.for %i0 = %arg0 to %arg1 step %arg2 iter_args(%si = %s0) -> (i32) {101    %sn = arith.addi %si, %si : i32102    scf.yield %sn : i32103  }104  return %result : i32105}106 107/// Test that we can properly propagate within inner control, and in situations108/// where the executable edges within the CFG are sensitive to the current state109/// of the analysis.110 111// CHECK-LABEL: func @loop_inner_control_flow(112func.func @loop_inner_control_flow(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {113  // CHECK: %[[CST:.*]] = arith.constant 1 : i32114  // CHECK-NOT: scf.for115  // CHECK-NOT: scf.if116  // CHECK: return %[[CST]] : i32117 118  %cst_1 = arith.constant 1 : i32119  %result = scf.for %i0 = %arg0 to %arg1 step %arg2 iter_args(%si = %cst_1) -> (i32) {120    %cst_20 = arith.constant 20 : i32121    %cond = arith.cmpi ult, %si, %cst_20 : i32122    %inner_res = scf.if %cond -> (i32) {123      %1 = arith.constant 1 : i32124      scf.yield %1 : i32125    } else {126      %si_inc = arith.addi %si, %cst_1 : i32127      scf.yield %si_inc : i32128    }129    scf.yield %inner_res : i32130  }131  return %result : i32132}133 134/// Test that we can properly visit region successors when the terminator135/// implements the RegionBranchTerminatorOpInterface.136 137// CHECK-LABEL: func @loop_region_branch_terminator_op(138func.func @loop_region_branch_terminator_op(%arg1 : i32) {139  // CHECK:      %c2_i32 = arith.constant 2 : i32140  // CHECK-NEXT: return141 142  %c2_i32 = arith.constant 2 : i32143   %0 = scf.while (%arg2 = %c2_i32) : (i32) -> (i32) {144    %1 = arith.cmpi sgt, %arg1, %arg2 : i32145    scf.condition(%1) %arg2 : i32146  } do {147  ^bb0(%arg2: i32):148    scf.yield %arg2 : i32149  }150  return151}152 153/// Check that propgation happens for affine.for -- tests its region branch op154/// interface as well.155 156// CHECK-LABEL: func @affine_loop_one_iter(157func.func @affine_loop_one_iter() -> i32 {158  // CHECK: %[[C1:.*]] = arith.constant 1 : i32159  %s0 = arith.constant 0 : i32160  %s1 = arith.constant 1 : i32161  %result = affine.for %i = 0 to 1 iter_args(%si = %s0) -> (i32) {162    %sn = arith.addi %si, %s1 : i32163    affine.yield %sn : i32164  }165  // CHECK: return %[[C1]] : i32166  return %result : i32167}168 169// CHECK-LABEL: func @affine_loop_zero_iter(170func.func @affine_loop_zero_iter() -> i32 {171  // CHECK: %[[C1:.*]] = arith.constant 1 : i32172  %s1 = arith.constant 1 : i32173  %result = affine.for %i = 0 to 0 iter_args(%si = %s1) -> (i32) {174   %sn = arith.addi %si, %si : i32175   affine.yield %sn : i32176  }177  // CHECK: return %[[C1]] : i32178  return %result : i32179}180 181// CHECK-LABEL: func @affine_loop_unknown_trip_count(182func.func @affine_loop_unknown_trip_count(%ub: index) -> i32 {183  // CHECK: %[[C0:.*]] = arith.constant 0 : i32184  %s0 = arith.constant 0 : i32185  %result = affine.for %i = 0 to %ub iter_args(%si = %s0) -> (i32) {186   %sn = arith.addi %si, %si : i32187   affine.yield %sn : i32188  }189  // CHECK: return %[[C0]] : i32190  return %result : i32191}192 193// CHECK-LABEL: func @while_loop_different_arg_count194func.func @while_loop_different_arg_count() -> index {195  // CHECK-DAG: %[[TRUE:.*]] = arith.constant true196  // CHECK-DAG: %[[C0:.*]] = arith.constant 0197  // CHECK-DAG: %[[C1:.*]] = arith.constant 1198  %c0 = arith.constant 0 : index199  %c1 = arith.constant 1 : index200  // CHECK: %[[WHILE:.*]] = scf.while201  %0 = scf.while (%arg3 = %c0, %arg4 = %c1) : (index, index) -> index {202    %1 = arith.cmpi slt, %arg3, %c1 : index203    // CHECK: scf.condition(%[[TRUE]]) %[[C1]]204    scf.condition(%1) %arg4 : index205  } do {206  ^bb0(%arg3: index):207    %1 = arith.muli %arg3, %c1 : index208    // CHECK: scf.yield %[[C0]], %[[C1]]209    scf.yield %c0, %1 : index, index210  }211  // CHECK: return %[[WHILE]]212  return %0 : index213}214 215// CHECK-LABEL: func @while_loop_false_condition216func.func @while_loop_false_condition(%arg0 : index) -> index {217  // CHECK: %[[C0:.*]] = arith.constant 0218  %c0 = arith.constant 0 : index219  %c1 = arith.constant 1 : index220  %0 = arith.muli %arg0, %c0 : index221  %1 = scf.while (%arg1 = %0) : (index) -> index {222    %2 = arith.cmpi slt, %arg1, %c0 : index223    scf.condition(%2) %arg1 : index224  } do {225  ^bb0(%arg2 : index):226    %3 = arith.addi %arg2, %c1 : index227    scf.yield %3 : index228  }229  // CHECK: return %[[C0]]230  func.return %1 : index231}232