[llvm] 7fa503e - [SROA] rewritePartition()/findCommonType(): if uses have conflicting type, try getTypePartition() before falling back to largest integral use type (PR47592)

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 6 23:20:58 PDT 2020


Author: Roman Lebedev
Date: 2020-10-07T09:20:19+03:00
New Revision: 7fa503ef4aaddc1c31dd36d970aa6609383e1718

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

LOG: [SROA] rewritePartition()/findCommonType(): if uses have conflicting type, try getTypePartition() before falling back to largest integral use type (PR47592)

And another step towards transformss not introducing inttoptr and/or
ptrtoint casts that weren't there already.

In this case, when load/store uses have conflicting types,
instead of falling back to the iN, we can try to use allocated sub-type.
As disscussed, this isn't the best idea overall (we shouldn't rely on
allocated type), but it works fine as a temporary measure.

I've measured, and @ `-O3` as of vanilla llvm test-suite + RawSpeed,
this results in +0.05% more bitcasts, -5.51% less inttoptr
and -1.05% less ptrtoint (at the end of middle-end opt pipeline)

See https://bugs.llvm.org/show_bug.cgi?id=47592

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D88788

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/SROA.cpp
    llvm/test/DebugInfo/ARM/sroa-complex.ll
    llvm/test/Transforms/SROA/ppcf128-no-fold.ll
    llvm/test/Transforms/SROA/preserve-nonnull.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index 7b9ce8b2f472..09e30a46c167 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -1128,9 +1128,9 @@ LLVM_DUMP_METHOD void AllocaSlices::dump() const { print(dbgs()); }
 
 /// Walk the range of a partitioning looking for a common type to cover this
 /// sequence of slices.
-static Type *findCommonType(AllocaSlices::const_iterator B,
-                            AllocaSlices::const_iterator E,
-                            uint64_t EndOffset) {
+static std::pair<Type *, IntegerType *>
+findCommonType(AllocaSlices::const_iterator B, AllocaSlices::const_iterator E,
+               uint64_t EndOffset) {
   Type *Ty = nullptr;
   bool TyIsCommon = true;
   IntegerType *ITy = nullptr;
@@ -1174,7 +1174,7 @@ static Type *findCommonType(AllocaSlices::const_iterator B,
       Ty = UserTy;
   }
 
-  return TyIsCommon ? Ty : ITy;
+  return {TyIsCommon ? Ty : nullptr, ITy};
 }
 
 /// PHI instructions that use an alloca and are subsequently loaded can be
@@ -4264,13 +4264,21 @@ AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
   // or an i8 array of an appropriate size.
   Type *SliceTy = nullptr;
   const DataLayout &DL = AI.getModule()->getDataLayout();
-  if (Type *CommonUseTy = findCommonType(P.begin(), P.end(), P.endOffset()))
-    if (DL.getTypeAllocSize(CommonUseTy).getFixedSize() >= P.size())
-      SliceTy = CommonUseTy;
+  std::pair<Type *, IntegerType *> CommonUseTy =
+      findCommonType(P.begin(), P.end(), P.endOffset());
+  // Do all uses operate on the same type?
+  if (CommonUseTy.first)
+    if (DL.getTypeAllocSize(CommonUseTy.first).getFixedSize() >= P.size())
+      SliceTy = CommonUseTy.first;
+  // If not, can we find an appropriate subtype in the original allocated type?
   if (!SliceTy)
     if (Type *TypePartitionTy = getTypePartition(DL, AI.getAllocatedType(),
                                                  P.beginOffset(), P.size()))
       SliceTy = TypePartitionTy;
+  // If still not, can we use the largest bitwidth integer type used?
+  if (!SliceTy && CommonUseTy.second)
+    if (DL.getTypeAllocSize(CommonUseTy.second).getFixedSize() >= P.size())
+      SliceTy = CommonUseTy.second;
   if ((!SliceTy || (SliceTy->isArrayTy() &&
                     SliceTy->getArrayElementType()->isIntegerTy())) &&
       DL.isLegalInteger(P.size() * 8))

diff  --git a/llvm/test/DebugInfo/ARM/sroa-complex.ll b/llvm/test/DebugInfo/ARM/sroa-complex.ll
index 50e30ce68bbd..9c92218845c7 100644
--- a/llvm/test/DebugInfo/ARM/sroa-complex.ll
+++ b/llvm/test/DebugInfo/ARM/sroa-complex.ll
@@ -15,14 +15,13 @@ entry:
   %c.realp = getelementptr inbounds { double, double }, { double, double }* %c, i32 0, i32 0, !dbg !17
   %c.imagp = getelementptr inbounds { double, double }, { double, double }* %c, i32 0, i32 1, !dbg !17
   store double 0.000000e+00, double* %c.realp, align 8, !dbg !17
-  ; SROA will split the complex double into two i64 values, because there is
-  ; no native double data type available.
+  ; SROA will split the complex double into two double values.
   ; Test that debug info for both values survives:
-  ; CHECK: call void @llvm.dbg.value(metadata i64 0,
+  ; CHECK: call void @llvm.dbg.value(metadata double 0.000000e+00,
   ; CHECK-SAME:                      metadata ![[C:[^,]*]],
   ; CHECK-SAME:                      metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64))
   store double 0.000000e+00, double* %c.imagp, align 8, !dbg !17
-  ; CHECK: call void @llvm.dbg.value(metadata i64 0,
+  ; CHECK: call void @llvm.dbg.value(metadata double 0.000000e+00,
   ; CHECK-SAME:                      metadata ![[C]],
   ; CHECK-SAME:                      metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64))
   ret void, !dbg !18

diff  --git a/llvm/test/Transforms/SROA/ppcf128-no-fold.ll b/llvm/test/Transforms/SROA/ppcf128-no-fold.ll
index 3f2934cbe166..4981f6d77a7e 100644
--- a/llvm/test/Transforms/SROA/ppcf128-no-fold.ll
+++ b/llvm/test/Transforms/SROA/ppcf128-no-fold.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -sroa -S | FileCheck %s 
+; RUN: opt < %s -sroa -S | FileCheck %s
 target datalayout = "E-m:e-i64:64-n32:64"
 target triple = "powerpc64-unknown-linux-gnu"
 
@@ -27,8 +27,8 @@ entry:
 ; CHECK-LABEL: @foo
 ; CHECK-NOT: i128 4628293042053316608
 ; CHECK-NOT: i128 4653260752096854016
-; CHECK-DAG: i128 bitcast (ppc_fp128 0xM403B0000000000000000000000000000 to i128)
-; CHECK-DAG: i128 bitcast (ppc_fp128 0xM4093B400000000000000000000000000 to i128)
+; CHECK-DAG: bitcast ppc_fp128 0xM403B0000000000000000000000000000 to i128
+; CHECK-DAG: bitcast ppc_fp128 0xM4093B400000000000000000000000000 to i128
 ; CHECK: call void @bar(i8* %v, [2 x i128]
 ; CHECK: ret void
 

diff  --git a/llvm/test/Transforms/SROA/preserve-nonnull.ll b/llvm/test/Transforms/SROA/preserve-nonnull.ll
index 284a6154cc17..c9db06dca1dc 100644
--- a/llvm/test/Transforms/SROA/preserve-nonnull.ll
+++ b/llvm/test/Transforms/SROA/preserve-nonnull.ll
@@ -51,11 +51,10 @@ entry:
 define i8* @propagate_nonnull_to_int() {
 ; CHECK-LABEL: define i8* @propagate_nonnull_to_int(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %[[A:.*]] = alloca i64
-; CHECK-NEXT:    store i64 42, i64* %[[A]]
-; CHECK-NEXT:    %[[LOAD:.*]] = load volatile i64, i64* %[[A]]
-; CHECK-NEXT:    %[[CAST:.*]] = inttoptr i64 %[[LOAD]] to i8*
-; CHECK-NEXT:    ret i8* %[[CAST]]
+; CHECK-NEXT:    %[[A:.*]] = alloca i8*
+; CHECK-NEXT:    store i8* inttoptr (i64 42 to i8*), i8** %[[A]]
+; CHECK-NEXT:    %[[LOAD:.*]] = load volatile i8*, i8** %[[A]]
+; CHECK-NEXT:    ret i8* %[[LOAD]]
 entry:
   %a = alloca [2 x i8*]
   %a.gep0 = getelementptr [2 x i8*], [2 x i8*]* %a, i32 0, i32 0
@@ -75,8 +74,7 @@ entry:
 define i8* @propagate_nonnull_to_int_and_promote() {
 ; CHECK-LABEL: define i8* @propagate_nonnull_to_int_and_promote(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %[[PROMOTED_VALUE:.*]] = inttoptr i64 42 to i8*
-; CHECK-NEXT:    ret i8* %[[PROMOTED_VALUE]]
+; CHECK-NEXT:    ret i8* inttoptr (i64 42 to i8*)
 entry:
   %a = alloca [2 x i8*], align 8
   %a.gep0 = getelementptr [2 x i8*], [2 x i8*]* %a, i32 0, i32 0


        


More information about the llvm-commits mailing list