[PATCH] D59000: [SROA] Fix a crash when trying to convert a memset to an non-integral pointer type

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 5 14:57:01 PST 2019


reames created this revision.
reames added reviewers: chandlerc, cherry, rnk.
Herald added subscribers: bollu, mcrosier.
Herald added a project: LLVM.

The included test case currently crashes on tip of tree.  Rather than adding a bailout, I chose to restructure the code so that the existing helper function could be used.  Given that, the majority of the diff is NFC-ish, but the key difference is that canConvertValue returns false when only one side is a non-integral pointer.

Thanks to Cherry Zhang for the test case.


Repository:
  rL LLVM

https://reviews.llvm.org/D59000

Files:
  lib/Transforms/Scalar/SROA.cpp
  test/Transforms/SROA/non-integral-pointers.ll


Index: test/Transforms/SROA/non-integral-pointers.ll
===================================================================
--- test/Transforms/SROA/non-integral-pointers.ll
+++ test/Transforms/SROA/non-integral-pointers.ll
@@ -44,3 +44,45 @@
 alwaysTaken:
   ret i64 42
 }
+
+define i64 addrspace(4)* @memset(i1 %alwaysFalse) {
+; CHECK-LABEL: @memset(
+; CHECK-NOT: inttoptr
+; CHECK-NOT: ptrtoint
+entry:
+  %x = alloca i64 addrspace(4)*
+  %cast.0 = bitcast i64 addrspace(4)** %x to i8*
+  call void @llvm.memset.p0i8.i64(i8* align 8 %cast.0, i8 5, i64 16, i1 false)
+  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
+
+neverTaken:
+  %x.field.ld.0 = load i64 addrspace(4)*, i64 addrspace(4)** %x
+  ret i64 addrspace(4)* %x.field.ld.0
+  
+alwaysTaken:
+  ret i64 addrspace(4)* null
+}
+
+;; TODO: This one demonstrates a missed oppurtunity.  The only known bit
+;; pattern for a non-integral bit pattern is that null is zero.  As such
+;; we could do SROA and replace the memset w/a null store.  This will
+;; usually be gotten by instcombine.
+define i64 addrspace(4)* @memset_null(i1 %alwaysFalse) {
+; CHECK-LABEL: @memset_null(
+; CHECK-NOT: inttoptr
+; CHECK-NOT: ptrtoint
+entry:
+  %x = alloca i64 addrspace(4)*
+  %cast.0 = bitcast i64 addrspace(4)** %x to i8*
+  call void @llvm.memset.p0i8.i64(i8* align 8 %cast.0, i8 0, i64 16, i1 false)
+  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
+
+neverTaken:
+  %x.field.ld.0 = load i64 addrspace(4)*, i64 addrspace(4)** %x
+  ret i64 addrspace(4)* %x.field.ld.0
+  
+alwaysTaken:
+  ret i64 addrspace(4)* null
+}
+
+declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i1)
Index: lib/Transforms/Scalar/SROA.cpp
===================================================================
--- lib/Transforms/Scalar/SROA.cpp
+++ lib/Transforms/Scalar/SROA.cpp
@@ -2727,15 +2727,26 @@
 
     Type *AllocaTy = NewAI.getAllocatedType();
     Type *ScalarTy = AllocaTy->getScalarType();
+    
+    const bool CanContinue = [&]() {
+      if (VecTy || IntTy)
+        return true;
+      if (BeginOffset > NewAllocaBeginOffset ||
+          EndOffset < NewAllocaEndOffset)
+        return false;
+      auto *C = cast<ConstantInt>(II.getLength());
+      if (C->getBitWidth() > 64)
+        return false;
+      const auto Len = C->getZExtValue();
+      auto *Int8Ty = IntegerType::getInt8Ty(NewAI.getContext());
+      auto *SrcTy = VectorType::get(Int8Ty, Len);
+      return canConvertValue(DL, SrcTy, AllocaTy) &&
+        DL.isLegalInteger(DL.getTypeSizeInBits(ScalarTy));
+    }();
 
     // If this doesn't map cleanly onto the alloca type, and that type isn't
     // a single value type, just emit a memset.
-    if (!VecTy && !IntTy &&
-        (BeginOffset > NewAllocaBeginOffset || EndOffset < NewAllocaEndOffset ||
-         SliceSize != DL.getTypeStoreSize(AllocaTy) ||
-         !AllocaTy->isSingleValueType() ||
-         !DL.isLegalInteger(DL.getTypeSizeInBits(ScalarTy)) ||
-         DL.getTypeSizeInBits(ScalarTy) % 8 != 0)) {
+    if (!CanContinue) {
       Type *SizeTy = II.getLength()->getType();
       Constant *Size = ConstantInt::get(SizeTy, NewEndOffset - NewBeginOffset);
       CallInst *New = IRB.CreateMemSet(


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D59000.189404.patch
Type: text/x-patch
Size: 3204 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190305/9416f40d/attachment.bin>


More information about the llvm-commits mailing list