[PATCH] D115167: [DSE] Use precise loc for memset_chk writing to local objects.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 6 09:53:01 PST 2021


fhahn created this revision.
fhahn added reviewers: nikic, ab, efriedma, asbirlea.
Herald added a subscriber: hiraditya.
fhahn requested review of this revision.
Herald added a project: LLVM.

memset_chk may not write the number of bytes specified by the third
argument, if it is larger than the destination size (specified as 4th
argument).

If the accessed object is not visible to the caller at all or does not
escape before the call, we should be able to assume that it writes
precisely the number of bytes specified in the 3rd argument. If it
writes less and aborts, no-one will be able to access the memory
afterwards.

If the object escapes or is visible to the caller, then a different
thread might access the memory after memset_chk aborts the current
thread.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115167

Files:
  llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
  llvm/test/Transforms/DeadStoreElimination/libcalls.ll


Index: llvm/test/Transforms/DeadStoreElimination/libcalls.ll
===================================================================
--- llvm/test/Transforms/DeadStoreElimination/libcalls.ll
+++ llvm/test/Transforms/DeadStoreElimination/libcalls.ll
@@ -494,7 +494,6 @@
 ; CHECK-LABEL: @dse_memset_chk_eliminates_store_local_object_escapes_after(
 ; CHECK-NEXT:    [[A:%.*]] = alloca [200 x i8], align 1
 ; CHECK-NEXT:    [[OUT:%.*]] = bitcast [200 x i8]* [[A]] to i8*
-; CHECK-NEXT:    store i8 10, i8* [[OUT]], align 1
 ; CHECK-NEXT:    [[OUT_100:%.*]] = getelementptr i8, i8* [[OUT]], i64 100
 ; CHECK-NEXT:    store i8 10, i8* [[OUT_100]], align 1
 ; CHECK-NEXT:    [[CALL_2:%.*]] = tail call i8* @__memset_chk(i8* [[OUT]], i32 42, i64 100, i64 [[N:%.*]])
@@ -516,7 +515,6 @@
 ; CHECK-NEXT:    [[A:%.*]] = alloca [200 x i8], align 1
 ; CHECK-NEXT:    [[OUT:%.*]] = bitcast [200 x i8]* [[A]] to i8*
 ; CHECK-NEXT:    call void @use(i8* [[OUT]])
-; CHECK-NEXT:    store i8 10, i8* [[OUT]], align 1
 ; CHECK-NEXT:    [[OUT_100:%.*]] = getelementptr i8, i8* [[OUT]], i64 100
 ; CHECK-NEXT:    store i8 0, i8* [[OUT_100]], align 1
 ; CHECK-NEXT:    [[CALL_2:%.*]] = tail call i8* @__memset_chk(i8* [[OUT]], i32 42, i64 100, i64 [[N:%.*]])
Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -1022,7 +1022,7 @@
     return I.first->second;
   }
 
-  Optional<MemoryLocation> getLocForWriteEx(Instruction *I) const {
+  Optional<MemoryLocation> getLocForWriteEx(Instruction *I) {
     if (!I->mayWriteToMemory())
       return None;
 
@@ -1032,6 +1032,22 @@
           !CB->onlyAccessesInaccessibleMemOrArgMem())
         return None;
 
+      LibFunc F;
+      if (TLI.getLibFunc(*CB, F) && TLI.has(F) && F == LibFunc_memset_chk) {
+        // Use the precise location size specified by the 3rd argument, if the
+        // accessed object is not visible to the caller at all or does not
+        // escape before the call. Even if memset_chk terminates, no-one will be
+        // able to read the accessed memory.
+        if (const auto *Len = dyn_cast<ConstantInt>(CB->getArgOperand(2))) {
+          Value *Ptr = CB->getArgOperand(0);
+          const Value *UO = getUnderlyingObject(Ptr);
+          if (isInvisibleToCallerAfterRet(UO) ||
+              EI.isNotCapturedBeforeOrAt(UO, CB))
+            return MemoryLocation(Ptr,
+                                  LocationSize::precise(Len->getZExtValue()),
+                                  CB->getAAMetadata());
+        }
+      }
       return MemoryLocation::getForDest(CB, TLI);
     }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D115167.392112.patch
Type: text/x-patch
Size: 2735 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211206/2e0e260f/attachment.bin>


More information about the llvm-commits mailing list