[Pass] Operand does not dominate this use
zzzDavid opened this issue · 2 comments
zzzDavid commented
This threads records some issues I met lowering reverse bit operation on LLVM backend.
The original program:
module {
func @top(%arg0: memref<10xi8>, %arg1: memref<10xi8>) attributes {bit, itypes = "uu", otypes = ""} {
affine.for %arg2 = 0 to 10 {
%0 = affine.load %arg0[%arg2] {from = "compute_0", unsigned} : memref<10xi8>
%1 = hcl.bit_reverse(%0 : i8) {unsigned}
%2 = affine.load %arg1[%arg2] {from = "compute_1", unsigned} : memref<10xi8>
%c7 = arith.constant 7 : index
%c0 = arith.constant 0 : index
hcl.set_slice(%2 : i8, %c7, %c0, %1 : i8)
affine.store %2, %arg1[%arg2] {to = "compute_1", unsigned} : memref<10xi8>
} {loop_name = "loop_0"}
return
}
}
I lowered hcl.bit_reverse
as getting and setting each bit:
module {
func @top_lowered(%arg0: memref<10xi8>, %arg1: memref<10xi8>) attributes {bit, itypes = "uu", otypes = ""} {
affine.for %arg2 = 0 to 10 {
%0 = affine.load %arg0[%arg2] {from = "compute_0", unsigned} : memref<10xi8>
%const_8 = arith.constant 8 : index
%const_0 = arith.constant 0 : i8
%1 = arith.addi %0, %const_0 : i8
affine.for %bit_idx = 0 to 8 {
%bit = hcl.get_bit(%0 : i8, %bit_idx) -> i1
%reverse_idx = arith.subi %const_8, %bit_idx : index
hcl.set_bit(%1 : i8, %reverse_idx, %bit : i1)
}
%2 = affine.load %arg1[%arg2] {from = "compute_1", unsigned} : memref<10xi8>
%c7 = arith.constant 7 : index
%c0 = arith.constant 0 : index
hcl.set_slice(%2 : i8, %c7, %c0, %1 : i8) // On this line the error occurs
affine.store %2, %arg1[%arg2] {to = "compute_1", unsigned} : memref<10xi8>
} {loop_name = "loop_0"}
return
}
}
But running this program with hcl-opt %s --lower-to-llvm
, I get this error:
error: operand #0 does not dominate this use
zzzDavid commented
My understanding is that, %1
is updated in the affine.for
blocks, so the hcl.set_slice
's usage of %1
is not dominated by %1 = arith.addi %0, %const_0 : i8
zzzDavid commented
A solution to the dominance issue is to use a memref:
module {
func @top_lowered(%arg0: memref<10xi8>, %arg1: memref<10xi8>) attributes {bit, itypes = "uu", otypes = ""} {
affine.for %arg2 = 0 to 10 {
%0 = affine.load %arg0[%arg2] {from = "compute_0", unsigned} : memref<10xi8>
%const_8 = arith.constant 8 : index
%const_0 = arith.constant 0 : index
%res_memref = memref.alloc() : memref<1xi8>
affine.for %bit_idx = 0 to 8 {
%res = affine.load %res_memref[%const_0] : memref<1xi8>
%bit = hcl.get_bit(%0 : i8, %bit_idx) -> i1
%reverse_idx = arith.subi %const_8, %bit_idx : index
hcl.set_bit(%res : i8, %reverse_idx, %bit : i1)
affine.store %res, %res_memref[%const_0] : memref<1xi8>
}
%1 = affine.load %res_memref[%const_0] : memref<1xi8>
%2 = affine.load %arg1[%arg2] {from = "compute_1", unsigned} : memref<10xi8>
%c7 = arith.constant 7 : index
%c0 = arith.constant 0 : index
hcl.set_slice(%2 : i8, %c7, %c0, %1 : i8)
affine.store %2, %arg1[%arg2] {to = "compute_1", unsigned} : memref<10xi8>
} {loop_name = "loop_0"}
return
}
}