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/MemRefToEmitC/MemRefToEmitC.cpp b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp index e0c421741b305..2d2c8f988fdc5 100644 --- a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp +++ b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp @@ -15,6 +15,7 @@ #include "mlir/Dialect/EmitC/IR/EmitC.h" #include "mlir/Dialect/MemRef/IR/MemRef.h" #include "mlir/IR/Builders.h" +#include "mlir/IR/Location.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Transforms/DialectConversion.h" @@ -90,6 +91,12 @@ struct ConvertGlobal final : public OpConversionPattern { if (isa_and_present(initialValue)) initialValue = {}; + // If converted type is a scalar, extract the splatted initial value. + if (initialValue && !isa(resultTy)) { + auto elementsAttr = llvm::cast(initialValue); + initialValue = elementsAttr.getSplatValue(); + } + rewriter.replaceOpWithNewOp( op, operands.getSymName(), resultTy, initialValue, externSpecifier, staticSpecifier, operands.getConstant()); @@ -116,6 +123,19 @@ struct ConvertGetGlobal final } }; +template +static Value getMemoryAccess(Value memref, Location loc, + typename T::Adaptor operands, + ConversionPatternRewriter &rewriter) { + // If MemRef is an array, access location using array subscripts. + if (auto arrayValue = dyn_cast>(memref)) + return rewriter.create(loc, arrayValue, + operands.getIndices()); + + // MemRef is a scalar, access location using variable's name. + return memref; +} + struct ConvertLoad final : public OpConversionPattern { using OpConversionPattern::OpConversionPattern; @@ -128,20 +148,13 @@ struct ConvertLoad final : public OpConversionPattern { return rewriter.notifyMatchFailure(op.getLoc(), "cannot convert type"); } - auto arrayValue = - dyn_cast>(operands.getMemref()); - if (!arrayValue) { - return rewriter.notifyMatchFailure(op.getLoc(), "expected array type"); - } - - auto subscript = rewriter.create( - op.getLoc(), arrayValue, operands.getIndices()); - + Value lvalue = getMemoryAccess( + operands.getMemref(), op.getLoc(), operands, rewriter); auto noInit = emitc::OpaqueAttr::get(getContext(), ""); auto var = rewriter.create(op.getLoc(), resultTy, noInit); - rewriter.create(op.getLoc(), var, subscript); + rewriter.create(op.getLoc(), var, lvalue); rewriter.replaceOp(op, var); return success(); } @@ -153,15 +166,10 @@ struct ConvertStore final : public OpConversionPattern { LogicalResult matchAndRewrite(memref::StoreOp op, OpAdaptor operands, ConversionPatternRewriter &rewriter) const override { - auto arrayValue = - dyn_cast>(operands.getMemref()); - if (!arrayValue) { - return rewriter.notifyMatchFailure(op.getLoc(), "expected array type"); - } + Value lvalue = getMemoryAccess( + operands.getMemref(), op.getLoc(), operands, rewriter); - auto subscript = rewriter.create( - op.getLoc(), arrayValue, operands.getIndices()); - rewriter.replaceOpWithNewOp(op, subscript, + rewriter.replaceOpWithNewOp(op, lvalue, operands.getValue()); return success(); } @@ -172,13 +180,15 @@ void mlir::populateMemRefToEmitCTypeConversion(TypeConverter &typeConverter) { typeConverter.addConversion( [&](MemRefType memRefType) -> std::optional { if (!memRefType.hasStaticShape() || - !memRefType.getLayout().isIdentity() || memRefType.getRank() == 0) { + !memRefType.getLayout().isIdentity()) { return {}; } Type convertedElementType = typeConverter.convertType(memRefType.getElementType()); if (!convertedElementType) return {}; + if (memRefType.getRank() == 0) + return convertedElementType; return emitc::ArrayType::get(memRefType.getShape(), convertedElementType); }); diff --git a/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp b/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp index 367142a520742..e4aa10f4cf208 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,31 @@ 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; // Zero rank for scalar memref. + 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) { + SmallVector values; + for (Value var : variables) + values.push_back(rewriter.create(loc, var).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); + rewriter.create(loc, value, var); } static void lowerYield(SmallVector &resultVariables, @@ -100,8 +112,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 +125,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 +186,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 +196,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/MemRefToEmitC/memref-to-emitc-failed.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir index 89dafa7529ed5..0cb33034680d8 100644 --- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir +++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir @@ -33,13 +33,5 @@ func.func @non_identity_layout() { // ----- -func.func @zero_rank() { - // expected-error@+1 {{failed to legalize operation 'memref.alloca'}} - %0 = memref.alloca() : memref - return -} - -// ----- - // expected-error@+1 {{failed to legalize operation 'memref.global'}} memref.global "nested" constant @nested_global : memref<3x7xf32> diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir index bc40ef48268eb..aafaf9810711b 100644 --- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir +++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir @@ -4,11 +4,15 @@ // CHECK-SAME: %[[v:.*]]: f32, %[[i:.*]]: index, %[[j:.*]]: index func.func @memref_store(%v : f32, %i: index, %j: index) { // CHECK: %[[ALLOCA:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<4x8xf32> + // CHECK: %[[SCALAR:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 %0 = memref.alloca() : memref<4x8xf32> + %s = memref.alloca() : memref // CHECK: %[[SUBSCRIPT:.*]] = emitc.subscript %[[ALLOCA]][%[[i]], %[[j]]] : (!emitc.array<4x8xf32>, index, index) -> f32 // CHECK: emitc.assign %[[v]] : f32 to %[[SUBSCRIPT:.*]] : f32 memref.store %v, %0[%i, %j] : memref<4x8xf32> + // CHECK: emitc.assign %[[v]] : f32 to %[[SCALAR]] : f32 + memref.store %v, %s[] : memref return } @@ -16,16 +20,21 @@ func.func @memref_store(%v : f32, %i: index, %j: index) { // CHECK-LABEL: memref_load // CHECK-SAME: %[[i:.*]]: index, %[[j:.*]]: index -func.func @memref_load(%i: index, %j: index) -> f32 { +func.func @memref_load(%i: index, %j: index) -> (f32, f32) { // CHECK: %[[ALLOCA:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.array<4x8xf32> %0 = memref.alloca() : memref<4x8xf32> + // CHECK: %[[SCALAR:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + %s = memref.alloca() : memref // CHECK: %[[LOAD:.*]] = emitc.subscript %[[ALLOCA]][%[[i]], %[[j]]] : (!emitc.array<4x8xf32>, index, index) -> f32 // CHECK: %[[VAR:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 // CHECK: emitc.assign %[[LOAD]] : f32 to %[[VAR]] : f32 %1 = memref.load %0[%i, %j] : memref<4x8xf32> - // CHECK: return %[[VAR]] : f32 - return %1 : f32 + // CHECK: %[[VAR_S:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + // CHECK: emitc.assign %[[SCALAR]] : f32 to %[[VAR_S]] : f32 + %sv = memref.load %s[] : memref + // CHECK: return %[[VAR]], %[[VAR_S]] : f32, f32 + return %1, %sv : f32, f32 } // ----- @@ -38,10 +47,13 @@ module @globals { // CHECK: emitc.global extern @public_global : !emitc.array<3x7xf32> memref.global @uninitialized_global : memref<3x7xf32> = uninitialized // CHECK: emitc.global extern @uninitialized_global : !emitc.array<3x7xf32> + memref.global "private" constant @internal_global_scalar : memref = dense<4.0> + // CHECK: emitc.global static const @internal_global_scalar : f32 = 4.000000e+00 func.func @use_global() { // CHECK: emitc.get_global @public_global : !emitc.array<3x7xf32> %0 = memref.get_global @public_global : memref<3x7xf32> + %1 = memref.get_global @internal_global_scalar : memref return } } diff --git a/mlir/test/Conversion/SCFToEmitC/for.mlir b/mlir/test/Conversion/SCFToEmitC/for.mlir index 7f90310af2189..d4e211b7a5950 100644 --- a/mlir/test/Conversion/SCFToEmitC/for.mlir +++ b/mlir/test/Conversion/SCFToEmitC/for.mlir @@ -47,20 +47,20 @@ 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 +// CHECK-NEXT: %[[VAL_6:.*]] = memref.alloca() : memref +// CHECK-NEXT: memref.store %[[VAL_3]], %[[VAL_5]][] : memref +// CHECK-NEXT: memref.store %[[VAL_4]], %[[VAL_6]][] : memref +// CHECK-NEXT: emitc.for %[[VAL_7:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] { +// CHECK-NEXT: %[[VAL_8:.*]] = memref.load %[[VAL_5]][] : memref +// CHECK-NEXT: %[[VAL_9:.*]] = memref.load %[[VAL_6]][] : memref +// CHECK-NEXT: %[[VAL_10:.*]] = arith.addf %[[VAL_8]], %[[VAL_9]] : f32 +// CHECK-NEXT: memref.store %[[VAL_10]], %[[VAL_5]][] : memref +// CHECK-NEXT: memref.store %[[VAL_10]], %[[VAL_6]][] : memref // 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_11:.*]] = memref.load %[[VAL_5]][] : memref +// CHECK-NEXT: %[[VAL_12:.*]] = memref.load %[[VAL_6]][] : memref +// CHECK-NEXT: return %[[VAL_11]], %[[VAL_12]] : f32, f32 // CHECK-NEXT: } func.func @nested_for_yield(%arg0 : index, %arg1 : index, %arg2 : index) -> f32 { @@ -77,20 +77,20 @@ 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: 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_4:.*]] = memref.alloca() : memref +// CHECK-NEXT: memref.store %[[VAL_3]], %[[VAL_4]][] : memref +// CHECK-NEXT: emitc.for %[[VAL_5:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] { +// CHECK-NEXT: %[[VAL_6:.*]] = memref.load %[[VAL_4]][] : memref +// CHECK-NEXT: %[[VAL_7:.*]] = memref.alloca() : memref +// CHECK-NEXT: memref.store %[[VAL_6]], %[[VAL_7]][] : memref +// CHECK-NEXT: emitc.for %[[VAL_8:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] { +// CHECK-NEXT: %[[VAL_9:.*]] = memref.load %[[VAL_7]][] : memref +// CHECK-NEXT: %[[VAL_10:.*]] = arith.addf %[[VAL_9]], %[[VAL_9]] : f32 +// CHECK-NEXT: memref.store %[[VAL_10]], %[[VAL_7]][] : memref // 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_11:.*]] = memref.load %[[VAL_7]][] : memref +// CHECK-NEXT: memref.store %[[VAL_11]], %[[VAL_4]][] : memref // CHECK-NEXT: } -// CHECK-NEXT: emitc.assign %[[VAL_5]] : f32 to %[[VAL_4]] : f32 -// CHECK-NEXT: return %[[VAL_4]] : f32 +// CHECK-NEXT: %[[VAL_12:.*]] = memref.load %[[VAL_4]][] : memref +// CHECK-NEXT: return %[[VAL_12]] : f32 // CHECK-NEXT: } diff --git a/mlir/test/Conversion/SCFToEmitC/if.mlir b/mlir/test/Conversion/SCFToEmitC/if.mlir index afc9abc761eb4..0753d9eda3283 100644 --- a/mlir/test/Conversion/SCFToEmitC/if.mlir +++ b/mlir/test/Conversion/SCFToEmitC/if.mlir @@ -53,18 +53,20 @@ 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 +// CHECK-NEXT: %[[VAL_4:.*]] = memref.alloca() : memref // 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: memref.store %[[VAL_5]], %[[VAL_3]][] : memref +// CHECK-NEXT: memref.store %[[VAL_6]], %[[VAL_4]][] : memref // 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: memref.store %[[VAL_7]], %[[VAL_3]][] : memref +// CHECK-NEXT: memref.store %[[VAL_8]], %[[VAL_4]][] : memref // CHECK-NEXT: } +// CHECK-NEXT: %[[VAL_9:.*]] = memref.load %[[VAL_3]][] : memref +// CHECK-NEXT: %[[VAL_10:.*]] = memref.load %[[VAL_4]][] : memref // CHECK-NEXT: return // CHECK-NEXT: } diff --git a/mlir/test/Target/Cpp/for.mlir b/mlir/test/Target/Cpp/for.mlir index 60988bcb46556..2e9a14b973e64 100644 --- a/mlir/test/Target/Cpp/for.mlir +++ b/mlir/test/Target/Cpp/for.mlir @@ -42,19 +42,23 @@ func.func @test_for_yield() { %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.assign %s0 : i32 to %0 : i32 + emitc.assign %p0 : f32 to %1 : f32 emitc.for %iter = %start to %stop step %step { + %2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 + emitc.assign %0 : i32 to %2 : i32 + %3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %1 : f32 to %3 : f32 %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.assign %sn : i32 to %0 : i32 + emitc.assign %pn : f32 to %1 : f32 emitc.yield } - emitc.assign %2 : i32 to %0 : i32 - emitc.assign %3 : f32 to %1 : f32 + %2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 + emitc.assign %0 : i32 to %2 : i32 + %3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %1 : f32 to %3 : f32 return } @@ -64,19 +68,23 @@ func.func @test_for_yield() { // 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: int32_t [[SL:[^ ]*]]; +// CPP-DEFAULT-NEXT: [[SL]] = [[SI]]; +// CPP-DEFAULT-NEXT: float [[PL:[^ ]*]]; +// CPP-DEFAULT-NEXT: [[PL]] = [[PI]]; +// CPP-DEFAULT-NEXT: int32_t [[SN:[^ ]*]] = add([[SL]], [[ITER]]); +// CPP-DEFAULT-NEXT: float [[PN:[^ ]*]] = mul([[PL]], [[ITER]]); // CPP-DEFAULT-NEXT: [[SI]] = [[SN]]; // CPP-DEFAULT-NEXT: [[PI]] = [[PN]]; // CPP-DEFAULT-NEXT: } +// CPP-DEFAULT-NEXT: int32_t [[SE:[^ ]*]]; // CPP-DEFAULT-NEXT: [[SE]] = [[SI]]; +// CPP-DEFAULT-NEXT: float [[PE:[^ ]*]]; // CPP-DEFAULT-NEXT: [[PE]] = [[PI]]; // CPP-DEFAULT-NEXT: return; @@ -86,12 +94,14 @@ func.func @test_for_yield() { // 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 [[SL:[^ ]*]]; +// CPP-DECLTOP-NEXT: float [[PL:[^ ]*]]; // CPP-DECLTOP-NEXT: int32_t [[SN:[^ ]*]]; // CPP-DECLTOP-NEXT: float [[PN:[^ ]*]]; +// CPP-DECLTOP-NEXT: int32_t [[SE:[^ ]*]]; +// CPP-DECLTOP-NEXT: float [[PE:[^ ]*]]; // CPP-DECLTOP-NEXT: [[START]] = 0; // CPP-DECLTOP-NEXT: [[STOP]] = 10; // CPP-DECLTOP-NEXT: [[STEP]] = 1; @@ -99,17 +109,21 @@ func.func @test_for_yield() { // CPP-DECLTOP-NEXT: [[P0]] = 1.000000000e+00f; // CPP-DECLTOP-NEXT: ; // CPP-DECLTOP-NEXT: ; -// CPP-DECLTOP-NEXT: ; -// 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: ; +// CPP-DECLTOP-NEXT: [[SL]] = [[SI]]; +// CPP-DECLTOP-NEXT: ; +// CPP-DECLTOP-NEXT: [[PL]] = [[PI]]; +// CPP-DECLTOP-NEXT: [[SN]] = add([[SL]], [[ITER]]); +// CPP-DECLTOP-NEXT: [[PN]] = mul([[PL]], [[ITER]]); // CPP-DECLTOP-NEXT: [[SI]] = [[SN]]; // CPP-DECLTOP-NEXT: [[PI]] = [[PN]]; // CPP-DECLTOP-NEXT: } +// CPP-DECLTOP-NEXT: ; // CPP-DECLTOP-NEXT: [[SE]] = [[SI]]; +// CPP-DECLTOP-NEXT: ; // CPP-DECLTOP-NEXT: [[PE]] = [[PI]]; // CPP-DECLTOP-NEXT: return; @@ -123,19 +137,23 @@ func.func @test_for_yield_2() { %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.assign %s0 : i32 to %0 : i32 + emitc.assign %p0 : f32 to %1 : f32 emitc.for %iter = %start to %stop step %step { + %2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 + emitc.assign %0 : i32 to %2 : i32 + %3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %1 : f32 to %3 : f32 %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.assign %sn : i32 to %0 : i32 + emitc.assign %pn : f32 to %1 : f32 emitc.yield } - emitc.assign %2 : i32 to %0 : i32 - emitc.assign %3 : f32 to %1 : f32 + %2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 + emitc.assign %0 : i32 to %2 : i32 + %3 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32 + emitc.assign %1 : f32 to %3 : f32 return } diff --git a/mlir/test/Target/Cpp/if.mlir b/mlir/test/Target/Cpp/if.mlir index 7b0e2da85d0eb..30422409e149c 100644 --- a/mlir/test/Target/Cpp/if.mlir +++ b/mlir/test/Target/Cpp/if.mlir @@ -63,6 +63,10 @@ func.func @test_if_yield(%arg0: i1, %arg1: f32) { emitc.assign %1 : i32 to %x : i32 emitc.assign %2 : f64 to %y : f64 } + %r1 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32 + emitc.assign %x : i32 to %r1 : i32 + %r2 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f64 + emitc.assign %y : f64 to %r2 : f64 return } // CPP-DEFAULT: void test_if_yield(bool [[V0:[^ ]*]], float [[V1:[^ ]*]]) { @@ -80,6 +84,10 @@ func.func @test_if_yield(%arg0: i1, %arg1: f32) { // CPP-DEFAULT-NEXT: [[V3]] = [[V7]]; // CPP-DEFAULT-NEXT: [[V4]] = [[V8]]; // CPP-DEFAULT-NEXT: } +// CPP-DEFAULT-NEXT: int32_t [[V5:[^ ]*]]; +// CPP-DEFAULT-NEXT: [[V5]] = [[V3]]; +// CPP-DEFAULT-NEXT: double [[V6:[^ ]*]]; +// CPP-DEFAULT-NEXT: [[V6]] = [[V4]]; // CPP-DEFAULT-NEXT: return; // CPP-DECLTOP: void test_if_yield(bool [[V0:[^ ]*]], float [[V1:[^ ]*]]) { @@ -90,6 +98,8 @@ func.func @test_if_yield(%arg0: i1, %arg1: f32) { // CPP-DECLTOP-NEXT: double [[V6:[^ ]*]]; // CPP-DECLTOP-NEXT: int32_t [[V7:[^ ]*]]; // CPP-DECLTOP-NEXT: double [[V8:[^ ]*]]; +// CPP-DECLTOP-NEXT: int32_t [[V9:[^ ]*]]; +// CPP-DECLTOP-NEXT: double [[V10:[^ ]*]]; // CPP-DECLTOP-NEXT: [[V2]] = 0; // CPP-DECLTOP-NEXT: ; // CPP-DECLTOP-NEXT: ; @@ -104,4 +114,8 @@ func.func @test_if_yield(%arg0: i1, %arg1: f32) { // CPP-DECLTOP-NEXT: [[V3]] = [[V7]]; // CPP-DECLTOP-NEXT: [[V4]] = [[V8]]; // CPP-DECLTOP-NEXT: } +// CPP-DECLTOP-NEXT: ; +// CPP-DECLTOP-NEXT: [[V9]] = [[V3]]; +// CPP-DECLTOP-NEXT: ; +// CPP-DECLTOP-NEXT: [[V10]] = [[V4]]; // CPP-DECLTOP-NEXT: return;