[PATCH] D135783: [FunctionAttrs] Account for memory effects of inalloca/preallocated

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 12 08:28:02 PDT 2022


nikic created this revision.
nikic added a reviewer: rnk.
Herald added subscribers: ormris, JDevlieghere, hiraditya.
Herald added a project: All.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

The code for inferring memory attributes on arguments claims that inalloca/preallocated arguments are always clobbered: https://github.com/llvm/llvm-project/blob/d71ad4108056d685f48407447095d8d92fd7685d/llvm/lib/Transforms/IPO/FunctionAttrs.cpp#L640-L642

However, we would still infer memory attributes for the whole function without taking this into account, so we could still end up inferring `readnone` for the function. This adds an argument clobber if there are any inalloca/preallocated arguments.

Disclaimer: I'm completely trusting the existing comment here, I'm not familiar with inalloc/preallocated arguments and why they're special in this regard.


https://reviews.llvm.org/D135783

Files:
  llvm/lib/Transforms/IPO/FunctionAttrs.cpp
  llvm/test/Transforms/FunctionAttrs/readattrs.ll


Index: llvm/test/Transforms/FunctionAttrs/readattrs.ll
===================================================================
--- llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -81,9 +81,9 @@
 
 ; inalloca parameters are always considered written
 define void @test7_1(i32* inalloca(i32) %a) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn
+; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn
 ; CHECK-LABEL: define {{[^@]+}}@test7_1
-; CHECK-SAME: (i32* nocapture inalloca(i32) [[A:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (i32* nocapture inalloca(i32) [[A:%.*]]) #[[ATTR5:[0-9]+]] {
 ; CHECK-NEXT:    ret void
 ;
   ret void
@@ -91,9 +91,9 @@
 
 ; preallocated parameters are always considered written
 define void @test7_2(i32* preallocated(i32) %a) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn
+; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn
 ; CHECK-LABEL: define {{[^@]+}}@test7_2
-; CHECK-SAME: (i32* nocapture preallocated(i32) [[A:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (i32* nocapture preallocated(i32) [[A:%.*]]) #[[ATTR5]] {
 ; CHECK-NEXT:    ret void
 ;
   ret void
@@ -130,7 +130,7 @@
 define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) {
 ; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn writeonly
 ; CHECK-LABEL: define {{[^@]+}}@test9
-; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR6:[0-9]+]] {
+; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR7:[0-9]+]] {
 ; CHECK-NEXT:    call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>)
 ; CHECK-NEXT:    ret void
 ;
@@ -142,7 +142,7 @@
 define <4 x i32> @test10(<4 x i32*> %ptrs) {
 ; CHECK: Function Attrs: mustprogress nofree nosync nounwind readonly willreturn
 ; CHECK-LABEL: define {{[^@]+}}@test10
-; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR8:[0-9]+]] {
+; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR9:[0-9]+]] {
 ; CHECK-NEXT:    [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef)
 ; CHECK-NEXT:    ret <4 x i32> [[RES]]
 ;
@@ -154,7 +154,7 @@
 define <4 x i32> @test11_2(<4 x i32*> %ptrs) {
 ; CHECK: Function Attrs: argmemonly nofree nounwind readonly
 ; CHECK-LABEL: define {{[^@]+}}@test11_2
-; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR10:[0-9]+]] {
+; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR11:[0-9]+]] {
 ; CHECK-NEXT:    [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]])
 ; CHECK-NEXT:    ret <4 x i32> [[RES]]
 ;
@@ -166,7 +166,7 @@
 define <4 x i32> @test12_2(<4 x i32*> %ptrs) {
 ; CHECK: Function Attrs: argmemonly nounwind
 ; CHECK-LABEL: define {{[^@]+}}@test12_2
-; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR11:[0-9]+]] {
+; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR12:[0-9]+]] {
 ; CHECK-NEXT:    [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]])
 ; CHECK-NEXT:    ret <4 x i32> [[RES]]
 ;
@@ -177,7 +177,7 @@
 define i32 @volatile_load(i32* %p) {
 ; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn
 ; CHECK-LABEL: define {{[^@]+}}@volatile_load
-; CHECK-SAME: (i32* [[P:%.*]]) #[[ATTR12:[0-9]+]] {
+; CHECK-SAME: (i32* [[P:%.*]]) #[[ATTR13:[0-9]+]] {
 ; CHECK-NEXT:    [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4
 ; CHECK-NEXT:    ret i32 [[LOAD]]
 ;
Index: llvm/lib/Transforms/IPO/FunctionAttrs.cpp
===================================================================
--- llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -133,13 +133,18 @@
   if (!ThisBody)
     return OrigMRB;
 
-  // Scan the function body for instructions that may read or write memory.
   FunctionModRefBehavior MRB = FunctionModRefBehavior::none();
+  // Inalloca and preallocated arguments are always clobbered by the call.
+  if (F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) ||
+      F.getAttributes().hasAttrSomewhere(Attribute::Preallocated))
+    MRB |= FunctionModRefBehavior::argMemOnly(ModRefInfo::ModRef);
+
   // Returns true if Ptr is not based on a function argument.
   auto IsArgumentOrAlloca = [](const Value *Ptr) {
     const Value *UO = getUnderlyingObject(Ptr);
     return isa<Argument>(UO) || isa<AllocaInst>(UO);
   };
+  // Scan the function body for instructions that may read or write memory.
   for (Instruction &I : instructions(F)) {
     // Some instructions can be ignored even if they read or write memory.
     // Detect these now, skipping to the next instruction if one is found.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D135783.467157.patch
Type: text/x-patch
Size: 4802 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221012/9bb37bce/attachment.bin>


More information about the llvm-commits mailing list