@@ -271,37 +271,41 @@ getUnderlyingObjectSet(Value pointerValue) {
271271static void createNewAliasScopesFromNoAliasParameter (
272272 Operation *call, iterator_range<Region::iterator> inlinedBlocks) {
273273
274- // First collect all noalias parameters. These have been specially marked by
275- // the `handleArgument` implementation by using the `ssa.copy` intrinsic and
276- // attaching a `noalias` attribute to it.
277- // These are only meant to be temporary and should therefore be deleted after
278- // we're done using them here.
274+ // First, collect all ssa copy operations, which correspond to function
275+ // parameters, and additionally store the noalias parameters. All parameters
276+ // have been marked by the `handleArgument` implementation by using the
277+ // `ssa.copy` intrinsic. Additionally, noalias parameters have an attached
278+ // `noalias` attribute to the intrinsics. These intrinsics are only meant to
279+ // be temporary and should therefore be deleted after we're done using them
280+ // here.
281+ SetVector<LLVM::SSACopyOp> ssaCopies;
279282 SetVector<LLVM::SSACopyOp> noAliasParams;
280283 for (Value argument : cast<LLVM::CallOp>(call).getArgOperands ()) {
281284 for (Operation *user : argument.getUsers ()) {
282285 auto ssaCopy = llvm::dyn_cast<LLVM::SSACopyOp>(user);
283286 if (!ssaCopy)
284287 continue ;
288+ ssaCopies.insert (ssaCopy);
289+
285290 if (!ssaCopy->hasAttr (LLVM::LLVMDialect::getNoAliasAttrName ()))
286291 continue ;
287-
288292 noAliasParams.insert (ssaCopy);
289293 }
290294 }
291295
292- // If there were none, we have nothing to do here.
293- if (noAliasParams.empty ())
294- return ;
295-
296296 // Scope exit block to make it impossible to forget to get rid of the
297297 // intrinsics.
298298 auto exit = llvm::make_scope_exit ([&] {
299- for (LLVM::SSACopyOp ssaCopyOp : noAliasParams ) {
299+ for (LLVM::SSACopyOp ssaCopyOp : ssaCopies ) {
300300 ssaCopyOp.replaceAllUsesWith (ssaCopyOp.getOperand ());
301301 ssaCopyOp->erase ();
302302 }
303303 });
304304
305+ // If there were no noalias parameters, we have nothing to do here.
306+ if (noAliasParams.empty ())
307+ return ;
308+
305309 // Create a new domain for this specific inlining and a new scope for every
306310 // noalias parameter.
307311 auto functionDomain = LLVM::AliasScopeDomainAttr::get (
@@ -335,7 +339,7 @@ static void createNewAliasScopesFromNoAliasParameter(
335339 bool aliasesOtherKnownObject = false ;
336340 // Go through the based on pointers and check that they are either:
337341 // * Constants that can be ignored (undef, poison, null pointer).
338- // * Based on a noalias parameter.
342+ // * Based on a pointer parameter.
339343 // * Other pointers that we know can't alias with our noalias parameter.
340344 //
341345 // Any other value might be a pointer based on any noalias parameter that
@@ -346,11 +350,13 @@ static void createNewAliasScopesFromNoAliasParameter(
346350 if (matchPattern (object, m_Constant ()))
347351 return false ;
348352
349- if (noAliasParams.contains (object.getDefiningOp <LLVM::SSACopyOp>()))
353+ if (auto ssaCopy = object.getDefiningOp <LLVM::SSACopyOp>()) {
354+ // If that value is based on a noalias parameter, it is guaranteed
355+ // to not alias with any other object.
356+ aliasesOtherKnownObject |= !noAliasParams.contains (ssaCopy);
350357 return false ;
358+ }
351359
352- // TODO: This should include other arguments from the inlined
353- // callable.
354360 if (isa_and_nonnull<LLVM::AllocaOp, LLVM::AddressOfOp>(
355361 object.getDefiningOp ())) {
356362 aliasesOtherKnownObject = true ;
@@ -773,29 +779,25 @@ struct LLVMInlinerInterface : public DialectInlinerInterface {
773779 return handleByValArgument (builder, callable, argument, elementType,
774780 requestedAlignment);
775781 }
776- if (argumentAttrs.contains (LLVM::LLVMDialect::getNoAliasAttrName ())) {
777- if (argument.use_empty ())
778- return argument;
779-
780- // This code is essentially a workaround for deficiencies in the
781- // inliner interface: We need to transform operations *after* inlined
782- // based on the argument attributes of the parameters *before* inlining.
783- // This method runs prior to actual inlining and thus cannot transform the
784- // post-inlining code, while `processInlinedCallBlocks` does not have
785- // access to pre-inlining function arguments. Additionally, it is required
786- // to distinguish which parameter an SSA value originally came from.
787- // As a workaround until this is changed: Create an ssa.copy intrinsic
788- // with the noalias attribute that can easily be found, and is extremely
789- // unlikely to exist in the code prior to inlining, using this to
790- // communicate between this method and `processInlinedCallBlocks`.
791- // TODO: Fix this by refactoring the inliner interface.
792- auto copyOp = builder.create <LLVM::SSACopyOp>(call->getLoc (), argument);
782+
783+ // This code is essentially a workaround for deficiencies in the inliner
784+ // interface: We need to transform operations *after* inlined based on the
785+ // argument attributes of the parameters *before* inlining. This method runs
786+ // prior to actual inlining and thus cannot transform the post-inlining
787+ // code, while `processInlinedCallBlocks` does not have access to
788+ // pre-inlining function arguments. Additionally, it is required to
789+ // distinguish which parameter an SSA value originally came from. As a
790+ // workaround until this is changed: Create an ssa.copy intrinsic with the
791+ // noalias attribute (when it was present before) that can easily be found,
792+ // and is extremely unlikely to exist in the code prior to inlining, using
793+ // this to communicate between this method and `processInlinedCallBlocks`.
794+ // TODO: Fix this by refactoring the inliner interface.
795+ auto copyOp = builder.create <LLVM::SSACopyOp>(call->getLoc (), argument);
796+ if (argumentAttrs.contains (LLVM::LLVMDialect::getNoAliasAttrName ()))
793797 copyOp->setDiscardableAttr (
794798 builder.getStringAttr (LLVM::LLVMDialect::getNoAliasAttrName ()),
795799 builder.getUnitAttr ());
796- return copyOp;
797- }
798- return argument;
800+ return copyOp;
799801 }
800802
801803 void processInlinedCallBlocks (
0 commit comments