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

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


https://github.com/wenju-he created https://github.com/llvm/llvm-project/pull/192775

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.

>From 7a0112027addd65649c075d033c22441ad7ea2e2 Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Sat, 18 Apr 2026 01:07:24 -0700
Subject: [PATCH] [ConstantFolding] Fold array to vector in
 ConstantFoldLoadThroughBitcast

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.
---
 llvm/lib/Analysis/ConstantFolding.cpp             | 15 +++++++++++++++
 .../EarlyCSE/load-constant-array-as-vector.ll     | 10 ++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 llvm/test/Transforms/EarlyCSE/load-constant-array-as-vector.ll

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
+}



More information about the llvm-commits mailing list