[llvm] [ConstantFolding] Fold array to vector in ConstantFoldLoadThroughBitcast (PR #192775)

via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 18 01:09:53 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Wenju He (wenju-he)

<details>
<summary>Changes</summary>

In FoldReinterpretLoadFromConst, ReadDataFromGlobal bails out when BytesLoaded exceeds 32 bytes. This prevent folding in our downstream OpenCL case where global constant is [16 x float] array and is loaded as float16 vector, which is 64 bytes.

This PR addresses the issue in ConstantFoldLoadThroughBitcast by folding array to vector when element type and count are the same.

---
Full diff: https://github.com/llvm/llvm-project/pull/192775.diff


2 Files Affected:

- (modified) llvm/lib/Analysis/ConstantFolding.cpp (+15) 
- (added) llvm/test/Transforms/EarlyCSE/load-constant-array-as-vector.ll (+10) 


``````````diff
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index cb8ecc3872c0c..7fff92d28d03f 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -381,6 +381,21 @@ Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy,
 
       if (CastInst::castIsValid(Cast, C, DestTy))
         return ConstantFoldCastOperand(Cast, C, DestTy, DL);
+
+      // Fold [N x T] array to <N x T> vector.
+      auto *FVTy = dyn_cast<FixedVectorType>(DestTy);
+      auto *ArrTy = dyn_cast<ArrayType>(SrcTy);
+      if (FVTy && ArrTy && ArrTy->getNumElements() == FVTy->getNumElements() &&
+          ArrTy->getElementType() == FVTy->getElementType()) {
+        SmallVector<Constant *, 16> Elems;
+        for (unsigned I = 0, E = ArrTy->getNumElements(); I != E; ++I) {
+          Constant *Elt = C->getAggregateElement(I);
+          if (!Elt)
+            return nullptr;
+          Elems.push_back(Elt);
+        }
+        return ConstantVector::get(Elems);
+      }
     }
 
     // If this isn't an aggregate type, there is nothing we can do to drill down
diff --git a/llvm/test/Transforms/EarlyCSE/load-constant-array-as-vector.ll b/llvm/test/Transforms/EarlyCSE/load-constant-array-as-vector.ll
new file mode 100644
index 0000000000000..12d2f53237bf2
--- /dev/null
+++ b/llvm/test/Transforms/EarlyCSE/load-constant-array-as-vector.ll
@@ -0,0 +1,10 @@
+; RUN: opt -passes=early-cse -S < %s | FileCheck %s
+
+ at d16 = private constant [16 x double] [double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0, double 7.0, double 8.0, double 9.0, double 10.0, double 11.0, double 12.0, double 13.0, double 14.0, double 15.0, double 16.0], align 128
+
+define double @fold_16xdouble_load() {
+  ; CHECK: ret double 2.000000e+00
+  %v = load <16 x double>, ptr @d16, align 128
+  %e = extractelement <16 x double> %v, i32 1
+  ret double %e
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/192775


More information about the llvm-commits mailing list