[StackSafety] Fix byval handling
authorVitaly Buka <vitalybuka@google.com>
Fri, 12 Jun 2020 01:56:20 +0000 (18:56 -0700)
committerVitaly Buka <vitalybuka@google.com>
Fri, 12 Jun 2020 03:58:36 +0000 (20:58 -0700)
We don't need process paramenters which marked as
byval as we are not going to pass interested allocas
without copying.

If we pass value into byval argument, we just handle that
as Load of corresponding type and stop that branch of analysis.

llvm/lib/Analysis/StackSafetyAnalysis.cpp
llvm/test/Analysis/StackSafetyAnalysis/local.ll

index f2c2bfd..853707e 100644 (file)
@@ -341,6 +341,13 @@ bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr,
           return false;
         }
 
+        unsigned ArgNo = CB.getArgOperandNo(&UI);
+        if (CB.isByValArgument(ArgNo)) {
+          US.updateRange(getAccessRange(
+              UI, Ptr, DL.getTypeStoreSize(CB.getParamByValType(ArgNo))));
+          break;
+        }
+
         // FIXME: consult devirt?
         // Do not follow aliases, otherwise we could inadvertently follow
         // dso_preemptable aliases or aliases with interposable linkage.
@@ -352,8 +359,7 @@ bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr,
         }
 
         assert(isa<Function>(Callee) || isa<GlobalAlias>(Callee));
-        US.Calls.emplace_back(Callee, CB.getArgOperandNo(&UI),
-                              offsetFrom(UI, Ptr));
+        US.Calls.emplace_back(Callee, ArgNo, offsetFrom(UI, Ptr));
         break;
       }
 
@@ -382,7 +388,9 @@ FunctionInfo<GlobalValue> StackSafetyLocalAnalysis::run() {
   }
 
   for (Argument &A : make_range(F.arg_begin(), F.arg_end())) {
-    if (A.getType()->isPointerTy()) {
+    // Non pointers and bypass arguments are not going to be used in any global
+    // processing.
+    if (A.getType()->isPointerTy() && !A.hasByValAttr()) {
       auto &UI = Info.Params.emplace(A.getArgNo(), PointerSize).first->second;
       analyzeAllUses(&A, UI);
     }
index 1b067fa..75cf64f 100644 (file)
@@ -416,3 +416,47 @@ entry:
   call void @LeakAddress() ["unknown"(i32* %a)]
   ret void
 }
+
+define void @ByVal(i16* byval %p) {
+  ; CHECK-LABEL: @ByVal dso_preemptable{{$}}
+  ; CHECK-NEXT: args uses:
+  ; CHECK-NEXT: allocas uses:
+  ; CHECK-NOT: ]:
+entry:
+  ret void
+}
+
+define void @TestByVal() {
+; CHECK-LABEL: @TestByVal dso_preemptable{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: allocas uses:
+; CHECK-NEXT: x[2]: [0,2)
+; CHECK-NEXT: y[8]: [0,2)
+; CHECK-NOT: ]:
+entry:
+  %x = alloca i16, align 4
+  call void @ByVal(i16* byval %x)
+
+  %y = alloca i64, align 4
+  %y1 = bitcast i64* %y to i16*
+  call void @ByVal(i16* byval %y1)
+  
+  ret void
+}
+
+declare void @ByValArray([100000 x i64]* byval %p)
+
+define void @TestByValArray() {
+; CHECK-LABEL: @TestByValArray dso_preemptable{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: allocas uses:
+; CHECK-NEXT: z[800000]: [500000,1300000)
+; CHECK-NOT: ]:
+entry:
+  %z = alloca [100000 x i64], align 4
+  %z1 = bitcast [100000 x i64]* %z to i8*
+  %z2 = getelementptr i8, i8* %z1, i64 500000
+  %z3 = bitcast i8* %z2 to [100000 x i64]*
+  call void @ByValArray([100000 x i64]* byval %z3)
+  ret void
+}
\ No newline at end of file