Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stablehlo.concatenate: error: operand #4 does not dominate this use #19570

Open
MichelBartels opened this issue Dec 30, 2024 · 2 comments
Open
Labels
bug 🐞 Something isn't working

Comments

@MichelBartels
Copy link

MichelBartels commented Dec 30, 2024

What happened?

When compiling a random number generator to StableHLO and then executing it using IREE, IREE is complaining about an operand #4 to "stablehlo.concatenate" not dominating its uses. I managed to reduce it to a simple program where it is obvious that the error message is wrong.

I am also not sure what operand #4 is referring to as there is no fourth operand.

Steps to reproduce your issue

bug.mlir (simplest case I could reduce it to):

func.func @main(%0 : tensor<1xui32>, %1: tensor<1xf32>) -> (tensor<2xf32>, tensor<1xui32>) {
%3 = "stablehlo.add"(%0, %0) : (tensor<1xui32>, tensor<1xui32>) -> (tensor<1xui32>)
%4 = "stablehlo.convert"(%3) : (tensor<1xui32>) -> (tensor<1xf32>)
%5 = "stablehlo.negate"(%4) : (tensor<1xf32>) -> (tensor<1xf32>)
%6 = "stablehlo.add"(%1, %1) : (tensor<1xf32>, tensor<1xf32>) -> (tensor<1xf32>)
%7 = "stablehlo.concatenate"(%4, %6) {
dimension = 0
} : (tensor<1xf32>, tensor<1xf32>) -> (tensor<2xf32>)
%8 = "stablehlo.add"(%0, %3) : (tensor<1xui32>, tensor<1xui32>) -> (tensor<1xui32>)
"stablehlo.return"(%7, %8) : (tensor<2xf32>, tensor<1xui32>) -> ()
}

Running iree-compile bug.mlir results in the following error message:

bug.mlir:6:6: error: operand #4 does not dominate this use
%7 = "stablehlo.concatenate"(%4, %6) {
     ^
bug.mlir:1:1: note: called from
func.func @main(%0 : tensor<1xui32>, %1: tensor<1xf32>) -> (tensor<2xf32>, tensor<1xui32>) {
^
bug.mlir:6:6: note: see current operation: %12 = "stream.async.update"(%11, %0, %3, %1, %13#2, %1) : (!stream.resource<*>, index, index, index, !stream.resource<*>, index) -> !stream.resource<*>
%7 = "stablehlo.concatenate"(%4, %6) {
     ^
bug.mlir:5:6: note: operand defined here (op in the same block)
%6 = "stablehlo.add"(%1, %1) : (tensor<1xf32>, tensor<1xf32>) -> (tensor<1xf32>)
     ^

What component(s) does this issue relate to?

No response

Version information

Version 3.0.0 of iree-compiler-base from pypi

Additional context

No response

@MichelBartels MichelBartels added the bug 🐞 Something isn't working label Dec 30, 2024
@MichelBartels
Copy link
Author

Reordering the instructions gets rid of the error message, but I don't see why this should make a difference.

func.func @main(%0 : tensor<1xui32>, %1: tensor<1xf32>) -> (tensor<2xf32>, tensor<1xui32>) {
%6 = "stablehlo.add"(%1, %1) : (tensor<1xf32>, tensor<1xf32>) -> (tensor<1xf32>)
%3 = "stablehlo.add"(%0, %0) : (tensor<1xui32>, tensor<1xui32>) -> (tensor<1xui32>)
%4 = "stablehlo.convert"(%3) : (tensor<1xui32>) -> (tensor<1xf32>)
%5 = "stablehlo.negate"(%4) : (tensor<1xf32>) -> (tensor<1xf32>)
%7 = "stablehlo.concatenate"(%4, %6) {
dimension = 0
} : (tensor<1xf32>, tensor<1xf32>) -> (tensor<2xf32>)
%8 = "stablehlo.add"(%0, %3) : (tensor<1xui32>, tensor<1xui32>) -> (tensor<1xui32>)
"stablehlo.return"(%7, %8) : (tensor<2xf32>, tensor<1xui32>) -> ()
}

@MichelBartels MichelBartels changed the title stablehlo.concate: error: operand #4 does not dominate this use stablehlo.concatenate: error: operand #4 does not dominate this use Dec 31, 2024
@IanWood1
Copy link
Contributor

Here is a reproducer that can be run with iree-opt --run-reproducer repro.mlir. The problematic pass is iree-stream-emplace-allocations. It seems to be caused by stream.async.update ops having a producer/consumer relationship. Possibly related: #14566

The pass iterates over all of the results to find updates ops to move. In the modified IR, the dispatch op is the last result so all the updates get correctly moved VS the original where only 1 of the 2 are moved. The following seems to be the cause of the difference between the 2 orderings:

auto updateOp = dyn_cast_or_null<IREE::Stream::AsyncUpdateOp>(userOp);
if (!updateOp)
break;
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants