My proposal didn’t have omp.transform_loop, but that approach looks interesting.
It wouldn’t. Generic passes are not required to check if an operation implements an interface, and are not even expected to know about dialect-specific interfaces. I am also not entirely convinced that having a different operation is sufficient by itself to prevent all transformations.
I am rather repulsed by the idea of giving omp.tile optional loop semantics just to prevent some transformations. Maybe we could have an omp.canonical_loop that matches the definition in the spec and have frontends emit that instead of scf.for / fir.do_loop (potentially via an internal transform before any other passes can run).