[llvm] [DRAFT][SROA] Promote aggregates as integers if they only have intrinsic users (PR #173117)

Yonah Goldberg via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 19 15:08:23 PST 2025


https://github.com/YonahGoldberg created https://github.com/llvm/llvm-project/pull/173117

None

>From f6ee220bf007cb8cddafb52b30ac55040349c067 Mon Sep 17 00:00:00 2001
From: Yonah Goldberg <ygoldberg at nvidia.com>
Date: Fri, 19 Dec 2025 22:24:18 +0000
Subject: [PATCH 1/2] findCommonType

---
 llvm/lib/Transforms/Scalar/SROA.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index f2a85cc7af441..0fee8108c1126 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -1523,12 +1523,14 @@ 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 std::pair<Type *, IntegerType *>
+/// Returns: {CommonType, LargestIntegerType, OnlyIntrinsicUsers}
+static std::tuple<Type *, IntegerType *, bool>
 findCommonType(AllocaSlices::const_iterator B, AllocaSlices::const_iterator E,
                uint64_t EndOffset) {
   Type *Ty = nullptr;
   bool TyIsCommon = true;
   IntegerType *ITy = nullptr;
+  bool OnlyIntrinsicUsers = true;
 
   // Note that we need to look at *every* alloca slice's Use to ensure we
   // always get consistent results regardless of the order of slices.
@@ -1536,6 +1538,8 @@ findCommonType(AllocaSlices::const_iterator B, AllocaSlices::const_iterator E,
     Use *U = I->getUse();
     if (isa<IntrinsicInst>(*U->getUser()))
       continue;
+    // We found a non-intrinsic user
+    OnlyIntrinsicUsers = false;
     if (I->beginOffset() != B->beginOffset() || I->endOffset() != EndOffset)
       continue;
 
@@ -1569,7 +1573,7 @@ findCommonType(AllocaSlices::const_iterator B, AllocaSlices::const_iterator E,
       Ty = UserTy;
   }
 
-  return {TyIsCommon ? Ty : nullptr, ITy};
+  return {TyIsCommon ? Ty : nullptr, ITy, OnlyIntrinsicUsers};
 }
 
 /// PHI instructions that use an alloca and are subsequently loaded can be

>From 34e09177daf3b16c234222c68f50c2fce9a1c5cb Mon Sep 17 00:00:00 2001
From: Yonah Goldberg <ygoldberg at nvidia.com>
Date: Fri, 19 Dec 2025 22:34:37 +0000
Subject: [PATCH 2/2] fix

---
 llvm/lib/Transforms/Scalar/SROA.cpp | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index 0fee8108c1126..0673360abaef3 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -5261,7 +5261,7 @@ selectPartitionType(Partition &P, const DataLayout &DL, AllocaInst &AI,
 
   // Check if there is a common type that all slices of the partition use that
   // spans the partition.
-  auto [CommonUseTy, LargestIntTy] =
+  auto [CommonUseTy, LargestIntTy, OnlyIntrinsicUsers] =
       findCommonType(P.begin(), P.end(), P.endOffset());
   if (CommonUseTy) {
     TypeSize CommonUseSize = DL.getTypeAllocSize(CommonUseTy);
@@ -5299,6 +5299,15 @@ selectPartitionType(Partition &P, const DataLayout &DL, AllocaInst &AI,
         isIntegerWideningViable(P, LargestIntTy, DL))
       return {LargestIntTy, true, nullptr};
 
+    // If there are only intrinsic users of an aggregate type, try to
+    // represent as a legal integer type because we are probably just copying
+    // data around and the integer can be promoted.
+    if (OnlyIntrinsicUsers && DL.isLegalInteger(P.size() * 8) &&
+        TypePartitionTy->isAggregateType())
+      auto *IntNTy = Type::getIntNTy(*C, P.size() * 8);
+      return {IntNTy, isIntegerWideningViable(P, IntNTy, DL), nullptr};
+    }
+
     // Fallback to TypePartitionTy and we probably won't promote.
     return {TypePartitionTy, false, nullptr};
   }



More information about the llvm-commits mailing list