[llvm] [SPIR-V] Preserve constexpr vectors as OpSpecConstantComposite (PR #215794)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 07:45:54 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-spir-v

Author: Arseniy Obolenskiy (aobolensk)

<details>
<summary>Changes</summary>

Let SPIRVEmitIntrinsics handle these the same as structs/arrays, instead of eagerly expanding them to runtime insertelement chains

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


2 Files Affected:

- (modified) llvm/lib/Target/SPIRV/SPIRVRegularizer.cpp (+4-41) 
- (modified) llvm/test/CodeGen/SPIRV/pointers/global-ptrtoint.ll (+19-1) 


``````````diff
diff --git a/llvm/lib/Target/SPIRV/SPIRVRegularizer.cpp b/llvm/lib/Target/SPIRV/SPIRVRegularizer.cpp
index d5e393470eae9..f8f549928d059 100644
--- a/llvm/lib/Target/SPIRV/SPIRVRegularizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVRegularizer.cpp
@@ -93,56 +93,19 @@ static void runLowerConstExpr(Function &F) {
     };
 
     WorkList.pop_front();
-    auto LowerConstantVec = [&II, &LowerOp, &WorkList,
-                             &Ctx](ConstantVector *Vec,
-                                   unsigned NumOfOp) -> Value * {
-      if (llvm::all_of(Vec->operands(), [](Value *V) {
-            return isa<ConstantExpr>(V) || isa<Function>(V);
-          })) {
-        // Expand a vector of constexprs and construct it back with
-        // series of insertelement instructions.
-        std::list<Value *> OpList;
-        llvm::transform(Vec->operands(), std::back_inserter(OpList),
-                        [LowerOp](Value *V) { return LowerOp(V); });
-        Value *Repl = nullptr;
-        unsigned Idx = 0;
-        auto *PhiII = dyn_cast<PHINode>(II);
-        Instruction *InsPoint =
-            PhiII ? &PhiII->getIncomingBlock(NumOfOp)->back() : II;
-        std::list<Instruction *> ReplList;
-        for (auto V : OpList) {
-          if (auto *Inst = dyn_cast<Instruction>(V))
-            ReplList.push_back(Inst);
-          Repl = InsertElementInst::Create(
-              (Repl ? Repl : PoisonValue::get(Vec->getType())), V,
-              ConstantInt::get(Type::getInt32Ty(Ctx), Idx++), "",
-              InsPoint->getIterator());
-        }
-        WorkList.splice(WorkList.begin(), ReplList);
-        return Repl;
-      }
-      return nullptr;
-    };
     for (unsigned OI = 0, OE = II->getNumOperands(); OI != OE; ++OI) {
       auto *Op = II->getOperand(OI);
-      if (auto *Vec = dyn_cast<ConstantVector>(Op)) {
-        Value *ReplInst = LowerConstantVec(Vec, OI);
-        if (ReplInst)
-          II->replaceUsesOfWith(Op, ReplInst);
-      } else if (auto CE = dyn_cast<ConstantExpr>(Op)) {
+      if (auto CE = dyn_cast<ConstantExpr>(Op)) {
         WorkList.push_front(cast<Instruction>(LowerOp(CE)));
       } else if (auto MDAsVal = dyn_cast<MetadataAsValue>(Op)) {
         auto ConstMD = dyn_cast<ConstantAsMetadata>(MDAsVal->getMetadata());
         if (!ConstMD)
           continue;
         Constant *C = ConstMD->getValue();
-        Value *ReplInst = nullptr;
-        if (auto *Vec = dyn_cast<ConstantVector>(C))
-          ReplInst = LowerConstantVec(Vec, OI);
-        if (auto *CE = dyn_cast<ConstantExpr>(C))
-          ReplInst = LowerOp(CE);
-        if (!ReplInst)
+        auto *CE = dyn_cast<ConstantExpr>(C);
+        if (!CE)
           continue;
+        Value *ReplInst = LowerOp(CE);
         Metadata *RepMD = ValueAsMetadata::get(ReplInst);
         Value *RepMDVal = MetadataAsValue::get(Ctx, RepMD);
         II->setOperand(OI, RepMDVal);
diff --git a/llvm/test/CodeGen/SPIRV/pointers/global-ptrtoint.ll b/llvm/test/CodeGen/SPIRV/pointers/global-ptrtoint.ll
index aa6d714e2e767..0044d15b20576 100644
--- a/llvm/test/CodeGen/SPIRV/pointers/global-ptrtoint.ll
+++ b/llvm/test/CodeGen/SPIRV/pointers/global-ptrtoint.ll
@@ -16,13 +16,31 @@
 ; CHECK-DAG: %[[UseGlobalValue:.*]] = OpSpecConstantOp %[[TyI64]] Bitcast %[[PtrToInt]]
 ; CHECK-DAG: %[[ConstComposite:.*]] = OpSpecConstantComposite %[[TyStruct]] %[[Const128]] %[[UseGlobalValue]]
 ; CHECK-DAG: %[[TyPtrStruct:.*]] = OpTypePointer CrossWorkgroup %[[TyStruct]]
-; CHECK: OpVariable %[[TyPtrStruct]] CrossWorkgroup %[[ConstComposite]]
+; CHECK-DAG: OpVariable %[[TyPtrStruct]] CrossWorkgroup %[[ConstComposite]]
+
+; CHECK-DAG: OpName %[[VecGlobal1:.*]] "vec_global1"
+; CHECK-DAG: OpName %[[VecGlobal2:.*]] "vec_global2"
+; CHECK-DAG: %[[TyVec:.*]] = OpTypeVector %[[TyI64]] 2
+; CHECK-DAG: %[[PtrToInt1:.*]] = OpSpecConstantOp %[[TyI64]] ConvertPtrToU %[[VecGlobal1]]
+; CHECK-DAG: %[[PtrToInt2:.*]] = OpSpecConstantOp %[[TyI64]] ConvertPtrToU %[[VecGlobal2]]
+; CHECK-DAG: %[[VecElt1:.*]] = OpSpecConstantOp %[[TyI64]] Bitcast %[[PtrToInt1]]
+; CHECK-DAG: %[[VecElt2:.*]] = OpSpecConstantOp %[[TyI64]] Bitcast %[[PtrToInt2]]
+; CHECK-DAG: OpSpecConstantComposite %[[TyVec]] %[[VecElt1]] %[[VecElt2]]
 ; CHECK: OpFunction
 
 @dev_global = addrspace(1) global [2 x i32] zeroinitializer
+ at vec_global1 = addrspace(1) global [2 x i32] zeroinitializer
+ at vec_global2 = addrspace(1) global [2 x i32] zeroinitializer
 @__AsanDeviceGlobalMetadata = addrspace(1) global { i64, i64 } { i64 128, i64 ptrtoint (ptr addrspace(1) @dev_global to i64) }
 
 define void @foo() {
 entry:
   ret void
 }
+
+define <2 x i64> @bar() {
+entry:
+  ret <2 x i64> <i64 ptrtoint (ptr addrspace(1) @vec_global1 to i64), i64 ptrtoint (ptr addrspace(1) @vec_global2 to i64)>
+}
+
+; CHECK-NOT: OpCompositeInsert

``````````

</details>


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


More information about the llvm-commits mailing list