diff --git a/enzyme/Enzyme/MLIR/Analysis/AliasAnalysis.cpp b/enzyme/Enzyme/MLIR/Analysis/AliasAnalysis.cpp index 1ed8349d15d9..611e57cc788a 100644 --- a/enzyme/Enzyme/MLIR/Analysis/AliasAnalysis.cpp +++ b/enzyme/Enzyme/MLIR/Analysis/AliasAnalysis.cpp @@ -371,6 +371,19 @@ void enzyme::PointsToPointerAnalysis::visitOperation(Operation *op, SmallVector effects; memory.getEffects(effects); + + // If the operation allocates fresh memory and doesn't write into it, that + // memory is known not to point to any known alias class. + if (effects.size() == 1 && + isa(effects.front().getEffect()) && + effects.front().getValue()) { + const auto *destClasses = + getOrCreateFor(op, effects.front().getValue()); + propagateIfChanged( + after, after->setPointingToEmpty(destClasses->getAliasClassesObject())); + return; + } + for (const auto &effect : effects) { if (!isa(effect.getEffect())) continue; @@ -865,14 +878,6 @@ void enzyme::AliasAnalysis::transfer( result->getPoint(), originalClasses.getOriginalClass(result->getPoint(), debugLabel)); propagateIfChanged(result, result->join(fresh)); - - // The pointer to freshly allocated memory is known not to point to - // anything. - // TODO(zinenko): this is a bit strange to update _another_ lattice - // here. - auto *pointsTo = getOrCreate(op); - propagateIfChanged(pointsTo, pointsTo->setPointingToEmpty( - fresh.getAliasClassesObject())); } } } else if (isa(effect.getEffect())) { diff --git a/enzyme/test/MLIR/AliasAnalysis/func_attributes.mlir b/enzyme/test/MLIR/AliasAnalysis/func_attributes.mlir index 87c7e4105a2b..e1f4b74a21f4 100644 --- a/enzyme/test/MLIR/AliasAnalysis/func_attributes.mlir +++ b/enzyme/test/MLIR/AliasAnalysis/func_attributes.mlir @@ -115,7 +115,7 @@ func.func private @callee(%ptr : !llvm.ptr {llvm.readonly}) attributes { } // CHECK: points-to-pointer sets -// CHECK-NEXT: +// CHECK: // CHECK-LABEL @call_other_none_arg_rw_readonly func.func @call_other_none_arg_rw_readonly(%input: !llvm.ptr {enzyme.tag = "input"}) { call @callee(%input) : (!llvm.ptr) -> ()