diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td index e6d678dc1b12b..18d7abe2d707c 100644 --- a/mlir/include/mlir/Conversion/Passes.td +++ b/mlir/include/mlir/Conversion/Passes.td @@ -976,7 +976,7 @@ def ConvertParallelLoopToGpu : Pass<"convert-parallel-loops-to-gpu"> { def SCFToEmitC : Pass<"convert-scf-to-emitc"> { let summary = "Convert SCF dialect to EmitC dialect, maintaining structured" " control flow"; - let dependentDialects = ["emitc::EmitCDialect"]; + let dependentDialects = ["emitc::EmitCDialect", "memref::MemRefDialect"]; } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp b/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp index 367142a520742..db33a15b4b00a 100644 --- a/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp +++ b/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp @@ -14,11 +14,13 @@ #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/EmitC/IR/EmitC.h" +#include "mlir/Dialect/MemRef/IR/MemRef.h" #include "mlir/Dialect/SCF/IR/SCF.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/IRMapping.h" #include "mlir/IR/MLIRContext.h" +#include "mlir/IR/OpDefinition.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Transforms/DialectConversion.h" #include "mlir/Transforms/Passes.h" @@ -63,21 +65,41 @@ static SmallVector createVariablesForResults(T op, for (OpResult result : op.getResults()) { Type resultType = result.getType(); - emitc::OpaqueAttr noInit = emitc::OpaqueAttr::get(context, ""); - emitc::VariableOp var = - rewriter.create(loc, resultType, noInit); + SmallVector dimensions = {rewriter.getIndexAttr(1)}; + memref::AllocaOp var = + rewriter.create(loc, dimensions, resultType); resultVariables.push_back(var); } return resultVariables; } -// Create a series of assign ops assigning given values to given variables at +// Create a series of load ops reading the values of given variables at +// the current insertion point of given rewriter. +static SmallVector readValues(SmallVector &variables, + PatternRewriter &rewriter, Location loc) { + Value zero; + if (!variables.empty()) + zero = rewriter.create(loc, rewriter.getIndexAttr(0)); + SmallVector values; + SmallVector indices = {zero}; + for (Value var : variables) + values.push_back( + rewriter.create(loc, var, indices).getResult()); + return values; +} + +// Create a series of store ops assigning given values to given variables at // the current insertion point of given rewriter. static void assignValues(ValueRange values, SmallVector &variables, PatternRewriter &rewriter, Location loc) { - for (auto [value, var] : llvm::zip(values, variables)) - rewriter.create(loc, var, value); + Value zero; + if (!variables.empty()) + zero = rewriter.create(loc, rewriter.getIndexAttr(0)); + for (auto [value, var] : llvm::zip(values, variables)) { + SmallVector indices = {zero}; + rewriter.create(loc, value, var, indices); + } } static void lowerYield(SmallVector &resultVariables, @@ -100,8 +122,6 @@ LogicalResult ForLowering::matchAndRewrite(ForOp forOp, // Create an emitc::variable op for each result. These variables will be // assigned to by emitc::assign ops within the loop body. - SmallVector resultVariables = - createVariablesForResults(forOp, rewriter); SmallVector iterArgsVariables = createVariablesForResults(forOp, rewriter); @@ -115,18 +135,25 @@ LogicalResult ForLowering::matchAndRewrite(ForOp forOp, // Erase the auto-generated terminator for the lowered for op. rewriter.eraseOp(loweredBody->getTerminator()); + IRRewriter::InsertPoint ip = rewriter.saveInsertionPoint(); + rewriter.setInsertionPointToEnd(loweredBody); + SmallVector iterArgsValues = + readValues(iterArgsVariables, rewriter, loc); + rewriter.restoreInsertionPoint(ip); + SmallVector replacingValues; replacingValues.push_back(loweredFor.getInductionVar()); - replacingValues.append(iterArgsVariables.begin(), iterArgsVariables.end()); + replacingValues.append(iterArgsValues.begin(), iterArgsValues.end()); rewriter.mergeBlocks(forOp.getBody(), loweredBody, replacingValues); lowerYield(iterArgsVariables, rewriter, cast(loweredBody->getTerminator())); // Copy iterArgs into results after the for loop. - assignValues(iterArgsVariables, resultVariables, rewriter, loc); + SmallVector resultValues = + readValues(iterArgsVariables, rewriter, loc); - rewriter.replaceOp(forOp, resultVariables); + rewriter.replaceOp(forOp, resultValues); return success(); } @@ -169,6 +196,7 @@ LogicalResult IfLowering::matchAndRewrite(IfOp ifOp, auto loweredIf = rewriter.create(loc, ifOp.getCondition(), false, false); + SmallVector resultValues = readValues(resultVariables, rewriter, loc); Region &loweredThenRegion = loweredIf.getThenRegion(); lowerRegion(thenRegion, loweredThenRegion); @@ -178,7 +206,7 @@ LogicalResult IfLowering::matchAndRewrite(IfOp ifOp, lowerRegion(elseRegion, loweredElseRegion); } - rewriter.replaceOp(ifOp, resultVariables); + rewriter.replaceOp(ifOp, resultValues); return success(); } diff --git a/mlir/test/Conversion/SCFToEmitC/for.mlir b/mlir/test/Conversion/SCFToEmitC/for.mlir index 7f90310af2189..04d3b75e97a65 100644 --- a/mlir/test/Conversion/SCFToEmitC/for.mlir +++ b/mlir/test/Conversion/SCFToEmitC/for.mlir @@ -47,20 +47,24 @@ func.func @for_yield(%arg0 : index, %arg1 : index, %arg2 : index) -> (f32, f32) // CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index) -> (f32, f32) { // CHECK-NEXT: %[[VAL_3:.*]] = arith.constant 0.000000e+00 : f32 // CHECK-NEXT: %[[VAL_4:.*]] = arith.constant 1.000000e+00 : f32 -// CHECK-NEXT: %[[VAL_5:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 -// CHECK-NEXT: %[[VAL_6:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 -// CHECK-NEXT: %[[VAL_7:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 -// CHECK-NEXT: %[[VAL_8:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 -// CHECK-NEXT: emitc.assign %[[VAL_3]] : f32 to %[[VAL_7]] : f32 -// CHECK-NEXT: emitc.assign %[[VAL_4]] : f32 to %[[VAL_8]] : f32 -// CHECK-NEXT: emitc.for %[[VAL_9:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] { -// CHECK-NEXT: %[[VAL_10:.*]] = arith.addf %[[VAL_7]], %[[VAL_8]] : f32 -// CHECK-NEXT: emitc.assign %[[VAL_10]] : f32 to %[[VAL_7]] : f32 -// CHECK-NEXT: emitc.assign %[[VAL_10]] : f32 to %[[VAL_8]] : f32 +// CHECK-NEXT: %[[VAL_5:.*]] = memref.alloca() : memref<1xf32> +// CHECK-NEXT: %[[VAL_6:.*]] = memref.alloca() : memref<1xf32> +// CHECK-NEXT: %[[VAL_7:.*]] = arith.constant 0 : index +// CHECK-NEXT: memref.store %[[VAL_3]], %[[VAL_5]]{{\[}}%[[VAL_7]]] : memref<1xf32> +// CHECK-NEXT: memref.store %[[VAL_4]], %[[VAL_6]]{{\[}}%[[VAL_7]]] : memref<1xf32> +// CHECK-NEXT: emitc.for %[[VAL_8:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] { +// CHECK-NEXT: %[[VAL_9:.*]] = arith.constant 0 : index +// CHECK-NEXT: %[[VAL_10:.*]] = memref.load %[[VAL_5]]{{\[}}%[[VAL_9]]] : memref<1xf32> +// CHECK-NEXT: %[[VAL_11:.*]] = memref.load %[[VAL_6]]{{\[}}%[[VAL_9]]] : memref<1xf32> +// CHECK-NEXT: %[[VAL_12:.*]] = arith.addf %[[VAL_10]], %[[VAL_11]] : f32 +// CHECK-NEXT: %[[VAL_13:.*]] = arith.constant 0 : index +// CHECK-NEXT: memref.store %[[VAL_12]], %[[VAL_5]]{{\[}}%[[VAL_13]]] : memref<1xf32> +// CHECK-NEXT: memref.store %[[VAL_12]], %[[VAL_6]]{{\[}}%[[VAL_13]]] : memref<1xf32> // CHECK-NEXT: } -// CHECK-NEXT: emitc.assign %[[VAL_7]] : f32 to %[[VAL_5]] : f32 -// CHECK-NEXT: emitc.assign %[[VAL_8]] : f32 to %[[VAL_6]] : f32 -// CHECK-NEXT: return %[[VAL_5]], %[[VAL_6]] : f32, f32 +// CHECK-NEXT: %[[VAL_14:.*]] = arith.constant 0 : index +// CHECK-NEXT: %[[VAL_15:.*]] = memref.load %[[VAL_5]]{{\[}}%[[VAL_14]]] : memref<1xf32> +// CHECK-NEXT: %[[VAL_16:.*]] = memref.load %[[VAL_6]]{{\[}}%[[VAL_14]]] : memref<1xf32> +// CHECK-NEXT: return %[[VAL_15]], %[[VAL_16]] : f32, f32 // CHECK-NEXT: } func.func @nested_for_yield(%arg0 : index, %arg1 : index, %arg2 : index) -> f32 { @@ -77,20 +81,28 @@ func.func @nested_for_yield(%arg0 : index, %arg1 : index, %arg2 : index) -> f32 // CHECK-LABEL: func.func @nested_for_yield( // CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index) -> f32 { // CHECK-NEXT: %[[VAL_3:.*]] = arith.constant 1.000000e+00 : f32 -// CHECK-NEXT: %[[VAL_4:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 -// CHECK-NEXT: %[[VAL_5:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 -// CHECK-NEXT: emitc.assign %[[VAL_3]] : f32 to %[[VAL_5]] : f32 +// CHECK-NEXT: %[[VAL_4:.*]] = memref.alloca() : memref<1xf32> +// CHECK-NEXT: %[[VAL_5:.*]] = arith.constant 0 : index +// CHECK-NEXT: memref.store %[[VAL_3]], %[[VAL_4]]{{\[}}%[[VAL_5]]] : memref<1xf32> // CHECK-NEXT: emitc.for %[[VAL_6:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] { -// CHECK-NEXT: %[[VAL_7:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 -// CHECK-NEXT: %[[VAL_8:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 -// CHECK-NEXT: emitc.assign %[[VAL_5]] : f32 to %[[VAL_8]] : f32 -// CHECK-NEXT: emitc.for %[[VAL_9:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] { -// CHECK-NEXT: %[[VAL_10:.*]] = arith.addf %[[VAL_8]], %[[VAL_8]] : f32 -// CHECK-NEXT: emitc.assign %[[VAL_10]] : f32 to %[[VAL_8]] : f32 +// CHECK-NEXT: %[[VAL_7:.*]] = arith.constant 0 : index +// CHECK-NEXT: %[[VAL_8:.*]] = memref.load %[[VAL_4]]{{\[}}%[[VAL_7]]] : memref<1xf32> +// CHECK-NEXT: %[[VAL_9:.*]] = memref.alloca() : memref<1xf32> +// CHECK-NEXT: %[[VAL_10:.*]] = arith.constant 0 : index +// CHECK-NEXT: memref.store %[[VAL_8]], %[[VAL_9]]{{\[}}%[[VAL_10]]] : memref<1xf32> +// CHECK-NEXT: emitc.for %[[VAL_11:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] { +// CHECK-NEXT: %[[VAL_12:.*]] = arith.constant 0 : index +// CHECK-NEXT: %[[VAL_13:.*]] = memref.load %[[VAL_9]]{{\[}}%[[VAL_12]]] : memref<1xf32> +// CHECK-NEXT: %[[VAL_14:.*]] = arith.addf %[[VAL_13]], %[[VAL_13]] : f32 +// CHECK-NEXT: %[[VAL_15:.*]] = arith.constant 0 : index +// CHECK-NEXT: memref.store %[[VAL_14]], %[[VAL_9]]{{\[}}%[[VAL_15]]] : memref<1xf32> // CHECK-NEXT: } -// CHECK-NEXT: emitc.assign %[[VAL_8]] : f32 to %[[VAL_7]] : f32 -// CHECK-NEXT: emitc.assign %[[VAL_7]] : f32 to %[[VAL_5]] : f32 +// CHECK-NEXT: %[[VAL_16:.*]] = arith.constant 0 : index +// CHECK-NEXT: %[[VAL_17:.*]] = memref.load %[[VAL_9]]{{\[}}%[[VAL_16]]] : memref<1xf32> +// CHECK-NEXT: %[[VAL_18:.*]] = arith.constant 0 : index +// CHECK-NEXT: memref.store %[[VAL_17]], %[[VAL_4]]{{\[}}%[[VAL_18]]] : memref<1xf32> // CHECK-NEXT: } -// CHECK-NEXT: emitc.assign %[[VAL_5]] : f32 to %[[VAL_4]] : f32 -// CHECK-NEXT: return %[[VAL_4]] : f32 +// CHECK-NEXT: %[[VAL_19:.*]] = arith.constant 0 : index +// CHECK-NEXT: %[[VAL_20:.*]] = memref.load %[[VAL_4]]{{\[}}%[[VAL_19]]] : memref<1xf32> +// CHECK-NEXT: return %[[VAL_20]] : f32 // CHECK-NEXT: } diff --git a/mlir/test/Conversion/SCFToEmitC/if.mlir b/mlir/test/Conversion/SCFToEmitC/if.mlir index afc9abc761eb4..3d394f06f541f 100644 --- a/mlir/test/Conversion/SCFToEmitC/if.mlir +++ b/mlir/test/Conversion/SCFToEmitC/if.mlir @@ -53,18 +53,23 @@ func.func @test_if_yield(%arg0: i1, %arg1: f32) { // CHECK-SAME: %[[VAL_0:.*]]: i1, // CHECK-SAME: %[[VAL_1:.*]]: f32) { // CHECK-NEXT: %[[VAL_2:.*]] = arith.constant 0 : i8 -// CHECK-NEXT: %[[VAL_3:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 -// CHECK-NEXT: %[[VAL_4:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f64 +// CHECK-NEXT: %[[VAL_3:.*]] = memref.alloca() : memref<1xi32> +// CHECK-NEXT: %[[VAL_4:.*]] = memref.alloca() : memref<1xf64> // CHECK-NEXT: emitc.if %[[VAL_0]] { // CHECK-NEXT: %[[VAL_5:.*]] = emitc.call_opaque "func_true_1"(%[[VAL_1]]) : (f32) -> i32 // CHECK-NEXT: %[[VAL_6:.*]] = emitc.call_opaque "func_true_2"(%[[VAL_1]]) : (f32) -> f64 -// CHECK-NEXT: emitc.assign %[[VAL_5]] : i32 to %[[VAL_3]] : i32 -// CHECK-NEXT: emitc.assign %[[VAL_6]] : f64 to %[[VAL_4]] : f64 +// CHECK-NEXT: %[[VAL_7:.*]] = arith.constant 0 : index +// CHECK-NEXT: memref.store %[[VAL_5]], %[[VAL_3]]{{\[}}%[[VAL_7]]] : memref<1xi32> +// CHECK-NEXT: memref.store %[[VAL_6]], %[[VAL_4]]{{\[}}%[[VAL_7]]] : memref<1xf64> // CHECK-NEXT: } else { -// CHECK-NEXT: %[[VAL_7:.*]] = emitc.call_opaque "func_false_1"(%[[VAL_1]]) : (f32) -> i32 -// CHECK-NEXT: %[[VAL_8:.*]] = emitc.call_opaque "func_false_2"(%[[VAL_1]]) : (f32) -> f64 -// CHECK-NEXT: emitc.assign %[[VAL_7]] : i32 to %[[VAL_3]] : i32 -// CHECK-NEXT: emitc.assign %[[VAL_8]] : f64 to %[[VAL_4]] : f64 +// CHECK-NEXT: %[[VAL_8:.*]] = emitc.call_opaque "func_false_1"(%[[VAL_1]]) : (f32) -> i32 +// CHECK-NEXT: %[[VAL_9:.*]] = emitc.call_opaque "func_false_2"(%[[VAL_1]]) : (f32) -> f64 +// CHECK-NEXT: %[[VAL_10:.*]] = arith.constant 0 : index +// CHECK-NEXT: memref.store %[[VAL_8]], %[[VAL_3]]{{\[}}%[[VAL_10]]] : memref<1xi32> +// CHECK-NEXT: memref.store %[[VAL_9]], %[[VAL_4]]{{\[}}%[[VAL_10]]] : memref<1xf64> // CHECK-NEXT: } +// CHECK-NEXT: %[[VAL_11:.*]] = arith.constant 0 : index +// CHECK-NEXT: %[[VAL_12:.*]] = memref.load %[[VAL_3]]{{\[}}%[[VAL_11]]] : memref<1xi32> +// CHECK-NEXT: %[[VAL_13:.*]] = memref.load %[[VAL_4]]{{\[}}%[[VAL_11]]] : memref<1xf64> // CHECK-NEXT: return // CHECK-NEXT: } diff --git a/mlir/test/Target/Cpp/for.mlir b/mlir/test/Target/Cpp/for.mlir index 60988bcb46556..dc45853a0be04 100644 --- a/mlir/test/Target/Cpp/for.mlir +++ b/mlir/test/Target/Cpp/for.mlir @@ -32,85 +32,103 @@ func.func @test_for(%arg0 : index, %arg1 : index, %arg2 : index) { // CPP-DECLTOP-NEXT: } // CPP-DECLTOP-NEXT: return; -func.func @test_for_yield() { - %start = "emitc.constant"() <{value = 0 : index}> : () -> index - %stop = "emitc.constant"() <{value = 10 : index}> : () -> index - %step = "emitc.constant"() <{value = 1 : index}> : () -> index - - %s0 = "emitc.constant"() <{value = 0 : i32}> : () -> i32 - %p0 = "emitc.constant"() <{value = 1.0 : f32}> : () -> f32 - - %0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 - %1 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 - %2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 - %3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 - emitc.assign %s0 : i32 to %2 : i32 - emitc.assign %p0 : f32 to %3 : f32 - emitc.for %iter = %start to %stop step %step { - %sn = emitc.call_opaque "add"(%2, %iter) : (i32, index) -> i32 - %pn = emitc.call_opaque "mul"(%3, %iter) : (f32, index) -> f32 - emitc.assign %sn : i32 to %2 : i32 - emitc.assign %pn : f32 to %3 : f32 - emitc.yield +func.func @test_for_yield(%arg0: index, %arg1: index, %arg2: index) { + %0 = "emitc.constant"() <{value = 0.000000e+00 : f32}> : () -> f32 + %1 = "emitc.constant"() <{value = 1.000000e+00 : f32}> : () -> f32 + %2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<1xf32> + %3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<1xf32> + %4 = "emitc.constant"() <{value = 0 : index}> : () -> index + %5 = emitc.subscript %2[%4] : (!emitc.array<1xf32>, index) -> f32 + emitc.assign %0 : f32 to %5 : f32 + %6 = emitc.subscript %3[%4] : (!emitc.array<1xf32>, index) -> f32 + emitc.assign %1 : f32 to %6 : f32 + emitc.for %arg3 = %arg0 to %arg1 step %arg2 { + %12 = "emitc.constant"() <{value = 0 : index}> : () -> index + %13 = emitc.subscript %2[%12] : (!emitc.array<1xf32>, index) -> f32 + %14 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %13 : f32 to %14 : f32 + %15 = emitc.subscript %3[%12] : (!emitc.array<1xf32>, index) -> f32 + %16 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %15 : f32 to %16 : f32 + %17 = emitc.add %14, %16 : (f32, f32) -> f32 + %18 = "emitc.constant"() <{value = 0 : index}> : () -> index + %19 = emitc.subscript %2[%18] : (!emitc.array<1xf32>, index) -> f32 + emitc.assign %17 : f32 to %19 : f32 + %20 = emitc.subscript %3[%18] : (!emitc.array<1xf32>, index) -> f32 + emitc.assign %17 : f32 to %20 : f32 } - emitc.assign %2 : i32 to %0 : i32 - emitc.assign %3 : f32 to %1 : f32 - + %7 = "emitc.constant"() <{value = 0 : index}> : () -> index + %8 = emitc.subscript %2[%7] : (!emitc.array<1xf32>, index) -> f32 + %9 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %8 : f32 to %9 : f32 + %10 = emitc.subscript %3[%7] : (!emitc.array<1xf32>, index) -> f32 + %11 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %10 : f32 to %11 : f32 return } -// CPP-DEFAULT: void test_for_yield() { -// CPP-DEFAULT-NEXT: size_t [[START:[^ ]*]] = 0; -// CPP-DEFAULT-NEXT: size_t [[STOP:[^ ]*]] = 10; -// CPP-DEFAULT-NEXT: size_t [[STEP:[^ ]*]] = 1; -// CPP-DEFAULT-NEXT: int32_t [[S0:[^ ]*]] = 0; -// CPP-DEFAULT-NEXT: float [[P0:[^ ]*]] = 1.000000000e+00f; -// CPP-DEFAULT-NEXT: int32_t [[SE:[^ ]*]]; -// CPP-DEFAULT-NEXT: float [[PE:[^ ]*]]; -// CPP-DEFAULT-NEXT: int32_t [[SI:[^ ]*]]; -// CPP-DEFAULT-NEXT: float [[PI:[^ ]*]]; -// CPP-DEFAULT-NEXT: [[SI:[^ ]*]] = [[S0]]; -// CPP-DEFAULT-NEXT: [[PI:[^ ]*]] = [[P0]]; -// CPP-DEFAULT-NEXT: for (size_t [[ITER:[^ ]*]] = [[START]]; [[ITER]] < [[STOP]]; [[ITER]] += [[STEP]]) { -// CPP-DEFAULT-NEXT: int32_t [[SN:[^ ]*]] = add([[SI]], [[ITER]]); -// CPP-DEFAULT-NEXT: float [[PN:[^ ]*]] = mul([[PI]], [[ITER]]); -// CPP-DEFAULT-NEXT: [[SI]] = [[SN]]; -// CPP-DEFAULT-NEXT: [[PI]] = [[PN]]; +// CPP-DEFAULT: void test_for_yield(size_t v1, size_t v2, size_t v3) { +// CPP-DEFAULT-NEXT: float [[V4:[^ ]*]] = 0.0e+00f; +// CPP-DEFAULT-NEXT: float [[V5:[^ ]*]] = 1.000000000e+00f; +// CPP-DEFAULT-NEXT: float [[V6:[^ ]*]][1]; +// CPP-DEFAULT-NEXT: float [[V7:[^ ]*]][1]; +// CPP-DEFAULT-NEXT: size_t [[V8:[^ ]*]] = 0; +// CPP-DEFAULT-NEXT: [[V6]][[[V8]]] = [[V4]]; +// CPP-DEFAULT-NEXT: [[V7]][[[V8]]] = [[V5]]; +// CPP-DEFAULT-NEXT: for (size_t [[V9:[^ ]*]] = [[V1]]; [[V9]] < [[V2]]; [[V9]] += [[V3]]) { +// CPP-DEFAULT-NEXT: size_t [[V10:[^ ]*]] = 0; +// CPP-DEFAULT-NEXT: float [[V11:[^ ]*]]; +// CPP-DEFAULT-NEXT: [[V11]] = [[V6]][[[V10]]]; +// CPP-DEFAULT-NEXT: float [[V12:[^ ]*]]; +// CPP-DEFAULT-NEXT: [[V12]] = [[V7]][[[V10]]]; +// CPP-DEFAULT-NEXT: float [[V13:[^ ]*]] = [[V11]] + [[V12]]; +// CPP-DEFAULT-NEXT: size_t [[V14:[^ ]*]] = 0; +// CPP-DEFAULT-NEXT: [[V6]][[[V14]]] = [[V13]]; +// CPP-DEFAULT-NEXT: [[V7]][[[V14]]] = [[V13]]; // CPP-DEFAULT-NEXT: } -// CPP-DEFAULT-NEXT: [[SE]] = [[SI]]; -// CPP-DEFAULT-NEXT: [[PE]] = [[PI]]; +// CPP-DEFAULT-NEXT: size_t [[V15:[^ ]*]] = 0; +// CPP-DEFAULT-NEXT: float [[V16:[^ ]*]]; +// CPP-DEFAULT-NEXT: v16 = v6[v15]; +// CPP-DEFAULT-NEXT: float [[V17:[^ ]*]]; +// CPP-DEFAULT-NEXT: v17 = v7[v15]; // CPP-DEFAULT-NEXT: return; -// CPP-DECLTOP: void test_for_yield() { -// CPP-DECLTOP-NEXT: size_t [[START:[^ ]*]]; -// CPP-DECLTOP-NEXT: size_t [[STOP:[^ ]*]]; -// CPP-DECLTOP-NEXT: size_t [[STEP:[^ ]*]]; -// CPP-DECLTOP-NEXT: int32_t [[S0:[^ ]*]]; -// CPP-DECLTOP-NEXT: float [[P0:[^ ]*]]; -// CPP-DECLTOP-NEXT: int32_t [[SE:[^ ]*]]; -// CPP-DECLTOP-NEXT: float [[PE:[^ ]*]]; -// CPP-DECLTOP-NEXT: int32_t [[SI:[^ ]*]]; -// CPP-DECLTOP-NEXT: float [[PI:[^ ]*]]; -// CPP-DECLTOP-NEXT: int32_t [[SN:[^ ]*]]; -// CPP-DECLTOP-NEXT: float [[PN:[^ ]*]]; -// CPP-DECLTOP-NEXT: [[START]] = 0; -// CPP-DECLTOP-NEXT: [[STOP]] = 10; -// CPP-DECLTOP-NEXT: [[STEP]] = 1; -// CPP-DECLTOP-NEXT: [[S0]] = 0; -// CPP-DECLTOP-NEXT: [[P0]] = 1.000000000e+00f; +// CPP-DECLTOP: void test_for_yield(size_t v1, size_t v2, size_t v3) { +// CPP-DECLTOP-NEXT: float [[V4:[^ ]*]]; +// CPP-DECLTOP-NEXT: float [[V5:[^ ]*]]; +// CPP-DECLTOP-NEXT: float [[V6:[^ ]*]][1]; +// CPP-DECLTOP-NEXT: float [[V7:[^ ]*]][1]; +// CPP-DECLTOP-NEXT: size_t [[V8:[^ ]*]]; +// CPP-DECLTOP-NEXT: size_t [[V9:[^ ]*]]; +// CPP-DECLTOP-NEXT: float [[V10:[^ ]*]]; +// CPP-DECLTOP-NEXT: float [[V11:[^ ]*]]; +// CPP-DECLTOP-NEXT: float [[V12:[^ ]*]]; +// CPP-DECLTOP-NEXT: size_t [[V13:[^ ]*]]; +// CPP-DECLTOP-NEXT: size_t [[V14:[^ ]*]]; +// CPP-DECLTOP-NEXT: float [[V15:[^ ]*]]; +// CPP-DECLTOP-NEXT: float [[V16:[^ ]*]]; +// CPP-DECLTOP-NEXT: [[V4]] = 0.0e+00f; +// CPP-DECLTOP-NEXT: [[V5]] = 1.000000000e+00f; // CPP-DECLTOP-NEXT: ; // CPP-DECLTOP-NEXT: ; +// CPP-DECLTOP-NEXT: [[V8]] = 0; +// CPP-DECLTOP-NEXT: [[V6]][[[V8]]] = [[V4]]; +// CPP-DECLTOP-NEXT: [[V7]][[[V8]]] = [[V5]]; +// CPP-DECLTOP-NEXT: for (size_t [[V17:[^ ]*]] = [[V1]]; [[V17]] < [[V2]]; [[V17]] += [[V3]]) { +// CPP-DECLTOP-NEXT: [[V9]] = 0; +// CPP-DECLTOP-NEXT: ; +// CPP-DECLTOP-NEXT: [[V10]] = [[V6]][[[V9]]]; +// CPP-DECLTOP-NEXT: ; +// CPP-DECLTOP-NEXT: [[V11]] = [[V7]][[[V9]]]; +// CPP-DECLTOP-NEXT: [[V12]] = [[V10]] + [[V11]]; +// CPP-DECLTOP-NEXT: [[V13]] = 0; +// CPP-DECLTOP-NEXT: [[V6]][[[V13]]] = [[V12]]; +// CPP-DECLTOP-NEXT: [[V7]][[[V13]]] = [[V12]]; +// CPP-DECLTOP-NEXT: } +// CPP-DECLTOP-NEXT: [[V14]] = 0; // CPP-DECLTOP-NEXT: ; +// CPP-DECLTOP-NEXT: [[V15]] = [[V6]][[[V14]]]; // CPP-DECLTOP-NEXT: ; -// CPP-DECLTOP-NEXT: [[SI:[^ ]*]] = [[S0]]; -// CPP-DECLTOP-NEXT: [[PI:[^ ]*]] = [[P0]]; -// CPP-DECLTOP-NEXT: for (size_t [[ITER:[^ ]*]] = [[START]]; [[ITER]] < [[STOP]]; [[ITER]] += [[STEP]]) { -// CPP-DECLTOP-NEXT: [[SN]] = add([[SI]], [[ITER]]); -// CPP-DECLTOP-NEXT: [[PN]] = mul([[PI]], [[ITER]]); -// CPP-DECLTOP-NEXT: [[SI]] = [[SN]]; -// CPP-DECLTOP-NEXT: [[PI]] = [[PN]]; -// CPP-DECLTOP-NEXT: } -// CPP-DECLTOP-NEXT: [[SE]] = [[SI]]; -// CPP-DECLTOP-NEXT: [[PE]] = [[PI]]; +// CPP-DECLTOP-NEXT: [[V16]] = [[V7]][[[V14]]]; // CPP-DECLTOP-NEXT: return; func.func @test_for_yield_2() { @@ -118,25 +136,37 @@ func.func @test_for_yield_2() { %stop = emitc.literal "10" : index %step = emitc.literal "1" : index - %s0 = emitc.literal "0" : i32 - %p0 = emitc.literal "M_PI" : f32 - - %0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 - %1 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 - %2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 - %3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 - emitc.assign %s0 : i32 to %2 : i32 - emitc.assign %p0 : f32 to %3 : f32 - emitc.for %iter = %start to %stop step %step { - %sn = emitc.call_opaque "add"(%2, %iter) : (i32, index) -> i32 - %pn = emitc.call_opaque "mul"(%3, %iter) : (f32, index) -> f32 - emitc.assign %sn : i32 to %2 : i32 - emitc.assign %pn : f32 to %3 : f32 - emitc.yield + %0 = emitc.literal "0" : f32 + %1 = emitc.literal "M_PI" : f32 + %2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<1xf32> + %3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<1xf32> + %4 = "emitc.constant"() <{value = 0 : index}> : () -> index + %5 = emitc.subscript %2[%4] : (!emitc.array<1xf32>, index) -> f32 + emitc.assign %0 : f32 to %5 : f32 + %6 = emitc.subscript %3[%4] : (!emitc.array<1xf32>, index) -> f32 + emitc.assign %1 : f32 to %6 : f32 + emitc.for %arg3 = %start to %stop step %step { + %12 = "emitc.constant"() <{value = 0 : index}> : () -> index + %13 = emitc.subscript %2[%12] : (!emitc.array<1xf32>, index) -> f32 + %14 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %13 : f32 to %14 : f32 + %15 = emitc.subscript %3[%12] : (!emitc.array<1xf32>, index) -> f32 + %16 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %15 : f32 to %16 : f32 + %17 = emitc.add %14, %16 : (f32, f32) -> f32 + %18 = "emitc.constant"() <{value = 0 : index}> : () -> index + %19 = emitc.subscript %2[%18] : (!emitc.array<1xf32>, index) -> f32 + emitc.assign %17 : f32 to %19 : f32 + %20 = emitc.subscript %3[%18] : (!emitc.array<1xf32>, index) -> f32 + emitc.assign %17 : f32 to %20 : f32 } - emitc.assign %2 : i32 to %0 : i32 - emitc.assign %3 : f32 to %1 : f32 - + %7 = "emitc.constant"() <{value = 0 : index}> : () -> index + %8 = emitc.subscript %2[%7] : (!emitc.array<1xf32>, index) -> f32 + %9 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %8 : f32 to %9 : f32 + %10 = emitc.subscript %3[%7] : (!emitc.array<1xf32>, index) -> f32 + %11 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %10 : f32 to %11 : f32 return } // CPP-DEFAULT: void test_for_yield_2() { diff --git a/mlir/test/Target/Cpp/if.mlir b/mlir/test/Target/Cpp/if.mlir index 7b0e2da85d0eb..fff11eec99854 100644 --- a/mlir/test/Target/Cpp/if.mlir +++ b/mlir/test/Target/Cpp/if.mlir @@ -50,58 +50,90 @@ func.func @test_if_else(%arg0: i1, %arg1: f32) { func.func @test_if_yield(%arg0: i1, %arg1: f32) { %0 = "emitc.constant"() <{value = 0 : i8}> : () -> i8 - %x = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 - %y = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f64 + %1 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<1xi32> + %2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<1xf64> emitc.if %arg0 { - %1 = emitc.call_opaque "func_true_1"(%arg1) : (f32) -> i32 - %2 = emitc.call_opaque "func_true_2"(%arg1) : (f32) -> f64 - emitc.assign %1 : i32 to %x : i32 - emitc.assign %2 : f64 to %y : f64 + %8 = emitc.call_opaque "func_true_1"(%arg1) : (f32) -> i32 + %9 = emitc.call_opaque "func_true_2"(%arg1) : (f32) -> f64 + %10 = "emitc.constant"() <{value = 0 : index}> : () -> index + %11 = emitc.subscript %1[%10] : (!emitc.array<1xi32>, index) -> i32 + emitc.assign %8 : i32 to %11 : i32 + %12 = emitc.subscript %2[%10] : (!emitc.array<1xf64>, index) -> f64 + emitc.assign %9 : f64 to %12 : f64 } else { - %1 = emitc.call_opaque "func_false_1"(%arg1) : (f32) -> i32 - %2 = emitc.call_opaque "func_false_2"(%arg1) : (f32) -> f64 - emitc.assign %1 : i32 to %x : i32 - emitc.assign %2 : f64 to %y : f64 + %8 = emitc.call_opaque "func_false_1"(%arg1) : (f32) -> i32 + %9 = emitc.call_opaque "func_false_2"(%arg1) : (f32) -> f64 + %10 = "emitc.constant"() <{value = 0 : index}> : () -> index + %11 = emitc.subscript %1[%10] : (!emitc.array<1xi32>, index) -> i32 + emitc.assign %8 : i32 to %11 : i32 + %12 = emitc.subscript %2[%10] : (!emitc.array<1xf64>, index) -> f64 + emitc.assign %9 : f64 to %12 : f64 } + %3 = "emitc.constant"() <{value = 0 : index}> : () -> index + %4 = emitc.subscript %1[%3] : (!emitc.array<1xi32>, index) -> i32 + %5 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 + emitc.assign %4 : i32 to %5 : i32 + %6 = emitc.subscript %2[%3] : (!emitc.array<1xf64>, index) -> f64 + %7 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f64 + emitc.assign %6 : f64 to %7 : f64 return } -// CPP-DEFAULT: void test_if_yield(bool [[V0:[^ ]*]], float [[V1:[^ ]*]]) { -// CPP-DEFAULT-NEXT: int8_t [[V2:[^ ]*]] = 0; -// CPP-DEFAULT-NEXT: int32_t [[V3:[^ ]*]]; -// CPP-DEFAULT-NEXT: double [[V4:[^ ]*]]; -// CPP-DEFAULT-NEXT: if ([[V0]]) { -// CPP-DEFAULT-NEXT: int32_t [[V5:[^ ]*]] = func_true_1([[V1]]); -// CPP-DEFAULT-NEXT: double [[V6:[^ ]*]] = func_true_2([[V1]]); -// CPP-DEFAULT-NEXT: [[V3]] = [[V5]]; -// CPP-DEFAULT-NEXT: [[V4]] = [[V6]]; +// CPP-DEFAULT: void test_if_yield(bool [[V1:[^ ]*]], float [[V2:[^ ]*]]) { +// CPP-DEFAULT-NEXT: int8_t [[V3:[^ ]*]] = 0; +// CPP-DEFAULT-NEXT: int32_t [[V4:[^ ]*]][1]; +// CPP-DEFAULT-NEXT: double [[V5:[^ ]*]][1]; +// CPP-DEFAULT-NEXT: if ([[V1]]) { +// CPP-DEFAULT-NEXT: int32_t [[V6:[^ ]*]] = func_true_1([[V2]]); +// CPP-DEFAULT-NEXT: double [[V7:[^ ]*]] = func_true_2([[V2]]); +// CPP-DEFAULT-NEXT: size_t [[V8:[^ ]*]] = 0; +// CPP-DEFAULT-NEXT: [[V4]][[[V8]]] = [[V6]]; +// CPP-DEFAULT-NEXT: [[V5]][[[V8]]] = [[V7]]; // CPP-DEFAULT-NEXT: } else { -// CPP-DEFAULT-NEXT: int32_t [[V7:[^ ]*]] = func_false_1([[V1]]); -// CPP-DEFAULT-NEXT: double [[V8:[^ ]*]] = func_false_2([[V1]]); -// CPP-DEFAULT-NEXT: [[V3]] = [[V7]]; -// CPP-DEFAULT-NEXT: [[V4]] = [[V8]]; +// CPP-DEFAULT-NEXT: int32_t [[V9:[^ ]*]] = func_false_1([[V2]]); +// CPP-DEFAULT-NEXT: double [[V10:[^ ]*]] = func_false_2([[V2]]); +// CPP-DEFAULT-NEXT: size_t [[V11:[^ ]*]] = 0; +// CPP-DEFAULT-NEXT: [[V4]][[[V11]]] = [[V9]]; +// CPP-DEFAULT-NEXT: [[V5]][[[V11]]] = [[V10]]; // CPP-DEFAULT-NEXT: } +// CPP-DEFAULT-NEXT: size_t [[V12:[^ ]*]] = 0; +// CPP-DEFAULT-NEXT: int32_t [[V13:[^ ]*]]; +// CPP-DEFAULT-NEXT: [[V13]] = [[V4]][[[V12]]]; +// CPP-DEFAULT-NEXT: double [[V14:[^ ]*]]; +// CPP-DEFAULT-NEXT: [[V14]] = [[V5]][[[V12]]]; // CPP-DEFAULT-NEXT: return; -// CPP-DECLTOP: void test_if_yield(bool [[V0:[^ ]*]], float [[V1:[^ ]*]]) { -// CPP-DECLTOP-NEXT: int8_t [[V2:[^ ]*]]; -// CPP-DECLTOP-NEXT: int32_t [[V3:[^ ]*]]; -// CPP-DECLTOP-NEXT: double [[V4:[^ ]*]]; -// CPP-DECLTOP-NEXT: int32_t [[V5:[^ ]*]]; -// CPP-DECLTOP-NEXT: double [[V6:[^ ]*]]; -// CPP-DECLTOP-NEXT: int32_t [[V7:[^ ]*]]; -// CPP-DECLTOP-NEXT: double [[V8:[^ ]*]]; -// CPP-DECLTOP-NEXT: [[V2]] = 0; +// CPP-DECLTOP: void test_if_yield(bool [[V1:[^ ]*]], float [[V2:[^ ]*]]) { +// CPP-DECLTOP-NEXT: int8_t [[V3:[^ ]*]]; +// CPP-DECLTOP-NEXT: int32_t [[V4:[^ ]*]][1]; +// CPP-DECLTOP-NEXT: double [[V5:[^ ]*]][1]; +// CPP-DECLTOP-NEXT: int32_t [[V6:[^ ]*]]; +// CPP-DECLTOP-NEXT: double [[V7:[^ ]*]]; +// CPP-DECLTOP-NEXT: size_t [[V8:[^ ]*]]; +// CPP-DECLTOP-NEXT: int32_t [[V9:[^ ]*]]; +// CPP-DECLTOP-NEXT: double [[V10:[^ ]*]]; +// CPP-DECLTOP-NEXT: size_t [[V11:[^ ]*]]; +// CPP-DECLTOP-NEXT: size_t [[V12:[^ ]*]]; +// CPP-DECLTOP-NEXT: int32_t [[V13:[^ ]*]]; +// CPP-DECLTOP-NEXT: double [[V14:[^ ]*]]; +// CPP-DECLTOP-NEXT: [[V3]] = 0; // CPP-DECLTOP-NEXT: ; // CPP-DECLTOP-NEXT: ; -// CPP-DECLTOP-NEXT: if ([[V0]]) { -// CPP-DECLTOP-NEXT: [[V5]] = func_true_1([[V1]]); -// CPP-DECLTOP-NEXT: [[V6]] = func_true_2([[V1]]); -// CPP-DECLTOP-NEXT: [[V3]] = [[V5]]; -// CPP-DECLTOP-NEXT: [[V4]] = [[V6]]; +// CPP-DECLTOP-NEXT: if ([[V1]]) { +// CPP-DECLTOP-NEXT: [[V6]] = func_true_1([[V2]]); +// CPP-DECLTOP-NEXT: [[V7]] = func_true_2([[V2]]); +// CPP-DECLTOP-NEXT: [[V8]] = 0; +// CPP-DECLTOP-NEXT: [[V4]][[[V8]]] = [[V6]]; +// CPP-DECLTOP-NEXT: [[V5]][[[V8]]] = [[V7]]; // CPP-DECLTOP-NEXT: } else { -// CPP-DECLTOP-NEXT: [[V7]] = func_false_1([[V1]]); -// CPP-DECLTOP-NEXT: [[V8]] = func_false_2([[V1]]); -// CPP-DECLTOP-NEXT: [[V3]] = [[V7]]; -// CPP-DECLTOP-NEXT: [[V4]] = [[V8]]; +// CPP-DECLTOP-NEXT: [[V9]] = func_false_1([[V2]]); +// CPP-DECLTOP-NEXT: [[V10]] = func_false_2([[V2]]); +// CPP-DECLTOP-NEXT: [[V11]] = 0; +// CPP-DECLTOP-NEXT: [[V4]][[[V11]]] = [[V9]]; +// CPP-DECLTOP-NEXT: [[V5]][[[V11]]] = [[V10]]; // CPP-DECLTOP-NEXT: } +// CPP-DECLTOP-NEXT: [[V12]] = 0; +// CPP-DECLTOP-NEXT: ; +// CPP-DECLTOP-NEXT: [[V13]] = [[V4]][[[V12]]]; +// CPP-DECLTOP-NEXT: ; +// CPP-DECLTOP-NEXT: [[V14]] = [[V5]][[[V12]]]; // CPP-DECLTOP-NEXT: return;