[llvm] f00941e - [DSE] Support opaque pointers

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 27 08:41:49 PDT 2021


Author: Nikita Popov
Date: 2021-06-27T17:41:40+02:00
New Revision: f00941e061f39646b05fcab93f892fc793845da1

URL: https://github.com/llvm/llvm-project/commit/f00941e061f39646b05fcab93f892fc793845da1
DIFF: https://github.com/llvm/llvm-project/commit/f00941e061f39646b05fcab93f892fc793845da1.diff

LOG: [DSE] Support opaque pointers

For the start shortening optimization, always use a i8 type for
the GEP, as it is a raw offset calculation.

Handling of non-i8* memset/memcpy arguments requires insertion
of casts. These cases were previously miscompiled, as the offset
calculation was performed on the wrong type.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
    llvm/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 4e840f6c03a19..5d45c20c22e57 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -642,12 +642,20 @@ static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierStart,
   EarlierIntrinsic->setDestAlignment(PrefAlign);
 
   if (!IsOverwriteEnd) {
+    Type *Int8PtrTy = Type::getInt8PtrTy(EarlierIntrinsic->getContext());
+    Value *OrigDest = EarlierIntrinsic->getRawDest();
+    Value *Dest = OrigDest;
+    if (OrigDest->getType() != Int8PtrTy)
+      Dest = CastInst::CreatePointerCast(OrigDest, Int8PtrTy, "", EarlierWrite);
     Value *Indices[1] = {
         ConstantInt::get(EarlierWriteLength->getType(), ToRemoveSize)};
-    GetElementPtrInst *NewDestGEP = GetElementPtrInst::CreateInBounds(
-        EarlierIntrinsic->getRawDest()->getType()->getPointerElementType(),
-        EarlierIntrinsic->getRawDest(), Indices, "", EarlierWrite);
+    Instruction *NewDestGEP = GetElementPtrInst::CreateInBounds(
+        Type::getInt8Ty(EarlierIntrinsic->getContext()),
+        Dest, Indices, "", EarlierWrite);
     NewDestGEP->setDebugLoc(EarlierIntrinsic->getDebugLoc());
+    if (NewDestGEP->getType() != OrigDest->getType())
+      NewDestGEP = CastInst::CreatePointerCast(NewDestGEP, OrigDest->getType(),
+                                               "", EarlierWrite);
     EarlierIntrinsic->setDest(NewDestGEP);
   }
 

diff  --git a/llvm/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll b/llvm/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll
index 2e53a5693b299..47bdd6132236d 100644
--- a/llvm/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll
+++ b/llvm/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll
@@ -21,6 +21,46 @@ entry:
   ret void
 }
 
+define void @write4to7_opaque_ptr(ptr nocapture %p) {
+; CHECK-LABEL: @write4to7_opaque_ptr(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast ptr [[ARRAYIDX0]] to i8*
+; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4
+; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to ptr
+; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[TMP2]], i8 0, i64 24, i1 false)
+; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
+; CHECK-NEXT:    store i32 1, ptr [[ARRAYIDX1]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
+  call void @llvm.memset.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i1 false)
+  %arrayidx1 = getelementptr inbounds i32, ptr %p, i64 1
+  store i32 1, ptr %arrayidx1, align 4
+  ret void
+}
+
+define void @write4to7_weird_element_type(i32* nocapture %p) {
+; CHECK-LABEL: @write4to7_weird_element_type(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
+; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4
+; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
+; CHECK-NEXT:    call void @llvm.memset.p0i32.i64(i32* align 4 [[TMP2]], i8 0, i64 24, i1 false)
+; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
+  call void @llvm.memset.p0i32.i64(i32* align 4 %arrayidx0, i8 0, i64 28, i1 false)
+  %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1
+  store i32 1, i32* %arrayidx1, align 4
+  ret void
+}
+
 define void @write4to7_atomic(i32* nocapture %p) {
 ; CHECK-LABEL: @write4to7_atomic(
 ; CHECK-NEXT:  entry:
@@ -291,8 +331,8 @@ define void @write8To15AndThen0To7(i64* nocapture %P) {
 ; CHECK-NEXT:    tail call void @llvm.memset.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i1 false)
 ; CHECK-NEXT:    [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
 ; CHECK-NEXT:    [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
-; CHECK-NEXT:    store i64 1, i64* [[BASE64_1]]
-; CHECK-NEXT:    store i64 2, i64* [[BASE64_0]]
+; CHECK-NEXT:    store i64 1, i64* [[BASE64_1]], align 4
+; CHECK-NEXT:    store i64 2, i64* [[BASE64_0]], align 4
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -391,6 +431,8 @@ entry:
 }
 
 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
+declare void @llvm.memset.p0i32.i64(i32* nocapture, i8, i64, i1) nounwind
+declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind
 declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture, i8, i64, i32) nounwind
 
 define void @ow_begin_align1(i8* nocapture %p) {


        


More information about the llvm-commits mailing list