[Mlir-commits] [mlir] [mlir][affine]if the result of a Pure operation that whose operands are dimensional identifiers, then their results are dimensional identifiers. (PR #123542)
lonely eagle
llvmlistbot at llvm.org
Sun Jan 26 06:49:37 PST 2025
linuxlonelyeagle wrote:
> > > This would make:
> > > ```
> > > affine.for %i = 0 to 100 {
> > > %i2 = arith.muli %i, %i
> > > affine.load[%i2]
> > > }
> > > ```
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > valid right? But in reality, this loop isn't affine anymore. My understanding is that the result of affine.apply with only dimensional identifiers is always a valid dimension for a affine loop, because the operation restricts what it can do. Allowing any pure operation breaks this.
> > > You can see it happening in the tests that you removed:
> > > ```
> > > func.func @store_non_affine_index(%arg0 : index) {
> > > %0 = memref.alloc() : memref<10xf32>
> > > %1 = arith.constant 11.0 : f32
> > > affine.for %i0 = 0 to 10 {
> > > %2 = arith.muli %i0, %arg0 : index
> > > // expected-error at +1 {{op index must be a valid dimension or symbol identifier}}
> > > affine.store %1, %0[%2] : memref<10xf32>
> > > }
> > > return
> > > }
> > > ```
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > This loop isn't always affine depending on the actual value of arg0.
> >
> >
> > I did get your point, my understanding is that the IR you gave is actually generated due to the following IR.I think this is correct.
> > ```
> > affine.for %i = 0 to 100 {
> > %i2 = arith.muli %i, %i
> > affine.load[%i2]
> > }
> > ```
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > ```
> > #map = affine_map<(d0, d1) -> ()>
> > affine.for %i = 0 to 100 {
> > %i2 = affine.apply #map (%i, %i)
> > affine.load[%i2]
> > }
> > ```
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > I didn't look at the test very carefully, ok, but I think it is missing some checks.
> > ```
> > func.func @store_non_affine_index(%arg0 : index) {
> > %0 = memref.alloc() : memref<10xf32>
> > %1 = arith.constant 11.0 : f32
> > affine.for %i0 = 0 to 10 {
> > %2 = arith.muli %i0, %arg0 : index
> > // expected-error at +1 {{op index must be a valid dimension or symbol identifier}}
> > affine.store %1, %0[%2] : memref<10xf32>
> > }
> > return
> > }
> > ```
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > Thanks for pointing that out.
>
> No, the IR in that loop is:
>
> ```mlir
> #map = affine_map<(d0, d1) -> (d0 * d1)>
> affine.for %i = 0 to 100 {
> %i2 = affine.apply #map (%i, %i)
> affine.load[%i2]
> }
> ```
>
> This will fail the verifier for affine_map, because the map is not affine: https://mlir.llvm.org/docs/Dialects/Affine/#affine-expressions (You cannot multiply dimensions).
>
> The error:
>
> ```mlir
> error: non-affine expression: at least one of the multiply operands has to be either a constant or symbolic
> #map = affine_map<(d0, d1) -> (d0 * d1)>
> ```
Thanks, I think I've learned something new.Maybe I should read more about Affine optimization to understand why it is defined that way, I'm very interested in this piece . I'll close it.
https://github.com/llvm/llvm-project/pull/123542
More information about the Mlir-commits
mailing list