[Mlir-commits] [mlir] [mlir][emitc] Lower SCF using memrefs (PR #93371)

Gil Rapaport llvmlistbot at llvm.org
Fri May 24 22:25:21 PDT 2024


https://github.com/aniragil created https://github.com/llvm/llvm-project/pull/93371

The SCF-to-EmitC lowering of yielded values currently generates
emitc.{variable,assign} ops implemeting the yield logic via memory. This
patch replaces these ops with memref.{alloc, load, store} ops in order
to separate the usage of memory from its concrete modeling in EmitC,
which is left for the memref-to-emitc conversion pass.
Since EmitC currently doesn't support lowering zero-rank memref types,
this patch uses 1D memrefs which translate to C arrays.


>From f17b94c8c242a1a2b8a62cef501c0bda3b353af3 Mon Sep 17 00:00:00 2001
From: Gil Rapaport <gil.rapaport at mobileye.com>
Date: Fri, 24 May 2024 19:50:48 +0300
Subject: [PATCH] [mlir][emitc] Lower SCF using memrefs

The SCF-to-EmitC lowering of yielded values currently generates
emitc.{variable,assign} ops implemeting the yield logic via memory. This
patch replaces these ops with memref.{alloc, load, store} ops in order
to separate the usage of memory from its concrete modeling in EmitC,
which is left for the memref-to-emitc conversion pass.
Since EmitC currently doesn't support lowering zero-rank memref types,
this patch uses 1D memrefs which translate to C arrays.
---
 mlir/include/mlir/Conversion/Passes.td        |   2 +-
 mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp |  52 +++--
 mlir/test/Conversion/SCFToEmitC/for.mlir      |  64 +++---
 mlir/test/Conversion/SCFToEmitC/if.mlir       |  21 +-
 mlir/test/Target/Cpp/for.mlir                 | 204 ++++++++++--------
 mlir/test/Target/Cpp/if.mlir                  | 114 ++++++----
 6 files changed, 282 insertions(+), 175 deletions(-)

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..26fe8ba20c36f 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<Value> createVariablesForResults(T op,
 
   for (OpResult result : op.getResults()) {
     Type resultType = result.getType();
-    emitc::OpaqueAttr noInit = emitc::OpaqueAttr::get(context, "");
-    emitc::VariableOp var =
-        rewriter.create<emitc::VariableOp>(loc, resultType, noInit);
+    SmallVector<OpFoldResult> dimensions = {rewriter.getIndexAttr(1)};
+    memref::AllocaOp var =
+        rewriter.create<memref::AllocaOp>(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<Value> readValues(SmallVector<Value> &variables,
+                                     PatternRewriter &rewriter, Location loc) {
+  Value zero;
+  if (variables.size() > 0)
+    zero = rewriter.create<arith::ConstantOp>(loc, rewriter.getIndexAttr(0));
+  SmallVector<Value> values;
+  SmallVector<Value> indices = {zero};
+  for (Value var : variables)
+    values.push_back(
+        rewriter.create<memref::LoadOp>(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<Value> &variables,
                          PatternRewriter &rewriter, Location loc) {
-  for (auto [value, var] : llvm::zip(values, variables))
-    rewriter.create<emitc::AssignOp>(loc, var, value);
+  Value zero;
+  if (variables.size() > 0)
+    zero = rewriter.create<arith::ConstantOp>(loc, rewriter.getIndexAttr(0));
+  for (auto [value, var] : llvm::zip(values, variables)) {
+    SmallVector<Value> indices = {zero};
+    rewriter.create<memref::StoreOp>(loc, value, var, indices);
+  }
 }
 
 static void lowerYield(SmallVector<Value> &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<Value> resultVariables =
-      createVariablesForResults(forOp, rewriter);
   SmallVector<Value> 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<Value> iterArgsValues =
+      readValues(iterArgsVariables, rewriter, loc);
+  rewriter.restoreInsertionPoint(ip);
+
   SmallVector<Value> 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<scf::YieldOp>(loweredBody->getTerminator()));
 
   // Copy iterArgs into results after the for loop.
-  assignValues(iterArgsVariables, resultVariables, rewriter, loc);
+  SmallVector<Value> 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<emitc::IfOp>(loc, ifOp.getCondition(), false, false);
+  SmallVector<Value> 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;



More information about the Mlir-commits mailing list