Assignment issue in MLIR inside loop

Hi,

I am trying to assign a value after some calculation inside a for loop. However, the generated MLIR is creating a new memory.

Here is the cpp code -

Value rev = builder.create<arith::ConstantOp>(loc, builder.getF64FloatAttr(0));

    builder.create<scf::ForOp>(loc, lb, ub, step, ValueRange{},
......
b.create<scf::IfOp>(
                             loc, cond,
                             [&](OpBuilder &b, Location loc)
                                  {
                                  Value res = b.create<arith::MulFOp>(loc, var3, var4);
                                   rev = b.create<arith::AddFOp>(loc, rev, res);
                                 });
                               b.create<scf::YieldOp>(loc);
.......
//Print outside for loop 
builder.create<vector::PrintOp>(loc, revenue);

The generated MLIR -

%8 = "arith.constant"() {value = 0.000000e+00 : f64} : () -> f64
    "scf.for"(%5, %6, %7) ({
    ^bb0(%arg0: index):
    "scf.if"(%22) ({
                %23 = "arith.mulf"(%11, %12) {fastmath = #arith.fastmath<none>} : (f64, f64) -> f64
                %24 = "arith.addf"(%8, %23) {fastmath = #arith.fastmath<none>} : (f64, f64) -> f64
              }
//outside for
"vector.print"(%24) : (f64) -> ()

My doubt is why it is not assigning the value to %8 and creating a new memory %24?

Thanks in advance.
Regards,
Sudip

I don’t quite get what you mean here?

I don’t quite get the question here either?

You can’t access SSA values outside of the region they are defined. You can either return the value through the if and through the for, or use something like a memref with loads and stores.

There seems to be confusion around SSA values.

These values are conceptually constant variables, so you can’t assign %8 a new value once it has been created. Instead you would create a value %8, then you would create an if/else block that returns either %8 or %24, then you can use the returned value. In this setup, the values are defined only once as required by SSA, and the values are not used outside of the region they are defined in as mentioned by Mehdi.

Thank you very much for your reply. I was trying to say that ‘rev (%8)’ was declared and MLIR allocate a register for it. But inside for and if while I am assigning the ‘AddF’ result to it, it was creating a new register (%24). As you and Tres explained the reason, now I understand the issue and I will work to resolve it.

Thanks,
Sudip

Hi Tres,

Thank you very much for your response. You are right, I was confused SSA values and constant op. I was thinking about doing a = a + b. But now I understand that as %8 was declared as constant, I can’t modify it further.

Thanks,
Sudip

I resolve the issue using memref load and store -

Value res = b.create<arith::MulFOp>(loc, var3, var4);
auto temp = builder.create<memref::LoadOp>(loc, rev, index.getResult());
auto v = b.create<arith::AddFOp>(loc, temp, res);
builder.create<memref::StoreOp>(loc, v.getResult(), rev, index.getResult());

Thanks for the hints.

Regards,
Sudip