Assert in Mem2Reg.cpp due to pointer address space mismatch
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 624
- Forks
- 170
- PR merge metrics
- No merged PRs in 30d
Description
func @_ZN2cl4sycl6detail7declptrINS0_4itemILi2ELb1EEEEEPT_v() -> !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>> attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
%false = arith.constant false
%true = arith.constant true
%0 = memref.alloca() : memref<i1>
memref.store %true, %0[] : memref<i1>
%1 = memref.alloca() : memref<!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>>
%2 = memref.load %0[] : memref<i1>
%3 = memref.load %1[] : memref<!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>>
%4:2 = scf.if %true -> (i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>) {
%6 = memref.load %0[] : memref<i1>
%7:2 = scf.if %true -> (i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>) {
%8 = llvm.mlir.null : !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>
memref.store %8, %1[] : memref<!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>>
memref.store %false, %0[] : memref<i1>
scf.yield %false, %8 : i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>
} else {
scf.yield %true, %3 : i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>
}
scf.yield %7#0, %7#1 : i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>
} else {
scf.yield %true, %3 : i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>
}
%5 = memref.load %1[] : memref<!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>>
return %5 : !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>
}
The above MLIR representation is related to below code, dumped at the entry to the first call to Mem2Reg pass.
template <typename T> T *declptr() { return static_cast<T *>(nullptr); }
processing the function using Mem2Reg results in below assert.
!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>> - !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>
mlir-clang: /home/m/Polygeist/lib/polygeist/Passes/Mem2Reg.cpp:641: {anonymous}::Mem2Reg::forwardStoreToLoad(mlir::Value, std::vector<long int, std::allocator<long int> >, llvm::SmallVectorImpl<mlir::Operation*>&)::<lambda(mlir::Block&, mlir::Value)>: Assertion `loadOp.getType() == lastVal.getType() && "mismatched load type"' failed.
The assert is related to mismatch between the address space of the pointer types in lastVal.getType() and loadType.getType.
Processing above as a stand alone C++ function does not result in the above assert. The assert is due to the pointer type being cached with address space of 4 in CodegenTypes::ConvertTypes while processing an earlier function.
To handle the assert above I considering 2 possible approaches:
-
To limit the comparison to ElementType of the pointers and ignore the Address space of the pointer types. Something like below:
Check equality and assert on loadOp.getType()->getElementType() == lastVal.getType()->getElementType(). -
We could also consider applying the optimisation only when pointers at both load / store share similar address space.
I would appreciate any suggestions on above potential solutions or any other viable solution.
Regards,
Moadeli
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at lib/polygeist/Passes/Mem2Reg.cpp:641 and trace forwardStoreToLoad, then inspect how CodegenTypes::ConvertTypes cached the pointer address space. Reproduce the supplied MLIR case and compare it with the standalone C++ function; done means the Mem2Reg pass handles the pointer address-space mismatch without triggering the assertion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100