-
Notifications
You must be signed in to change notification settings - Fork 206
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
Fix issues in lift-array-alloc #2570
base: main
Are you sure you want to change the base?
Conversation
I, Anna Gringauze <[email protected]>, hereby add my Signed-off-by to this commit: c1592b8 Signed-off-by: Anna Gringauze <[email protected]>
ArrayRef<cudaq::cc::ExtractValueArg>{offset}); | ||
rewriter.replaceAllUsesWith(load, extractValue); | ||
insertOpToErase(load); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why the replaceOpWithNewOp
needs to be changed here. It will
- create the new ExtractValueOp
- replace all the users of the original LoadOp to use the new ExtractValueOp
which is exactly what your change does. Additionally, we don't need or want to aggressively delete Ops. For example, passes may not be successful, and the MLIR infrastructure is designed to allow it to cleanly back out of the changes without leaving the IR broken. We should just let MLIR do the cleanups anywhere that it can. In this case, a LoadOp with 0 users will simply be removed by the next DCE. We don't have to do anything special.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why but the original code crashes on uccsd example
@@ -160,6 +167,7 @@ class AllocaPattern : public OpRewritePattern<cudaq::cc::AllocaOp> { | |||
if (!u) | |||
return nullptr; | |||
if (auto store = dyn_cast<cudaq::cc::StoreOp>(u)) { | |||
storeSets[index].insert(u); | |||
if (op.getOperation() == store.getPtrvalue().getDefiningOp() && | |||
isa_and_present<arith::ConstantOp, complex::ConstantOp>( | |||
store.getValue().getDefiningOp())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does any of this get past the check here? This is intended to check that we do not have multiple stores to the same offset of the array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran a little test, and this check correctly blocks the transformation.
func.func @f() {
%0 = cc.alloca !cc.array<i64 x 1>
%1 = arith.constant 1 : i64
%2 = cc.compute_ptr %0[0] : (!cc.ptr<!cc.array<i64 x 1>>) -> !cc.ptr<i64>
cc.store %1, %2 : !cc.ptr<i64>
%3 = arith.constant 3 : i64
cc.store %3, %2 : !cc.ptr<i64>
return
}
Running lift-array-alloc does not change this code, which is the correct thing to happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the failing example differs on the second store not using a constant to store to a pointer
cc.store %c0_i64, %5 : !cc.ptr<i64> // Dominates the next store, don't lift | ||
|
||
// arr2[0] = t | ||
cc.store %3, %5 : !cc.ptr<i64> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pass should refuse to convert this code because there are 2 stores to the same offset. But I don't see why it wasn't already. But this is a good test to make sure it doesn't regress further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
second store is not a constant. I will update the fix
CUDA Quantum Docs Bot: A preview of the documentation can be found here. |
Description
Fix crashes and over-optimizations in lift-array-alloc:
Example:
This example generates the following IR:
And lift-array-alloc misses the second store to
arr2
below and incorrectly assumes thatarr2[0]==0
instead ofarr2[0]==1
:The fix detects that the first store dominates the second and skips the optimization.