[llvm] [GlobalISel] Add SVE support for alloca (PR #178976)

Jameson Nash via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 31 12:48:59 PST 2026


https://github.com/vtjnash updated https://github.com/llvm/llvm-project/pull/178976

>From 7698a351138b40fa459170c16cb5efd4335beacb Mon Sep 17 00:00:00 2001
From: Jameson Nash <vtjnash at gmail.com>
Date: Wed, 28 Jan 2026 19:22:07 +0000
Subject: [PATCH] [GlobalISel] Add SVE support for alloca

Complementary to the same handling in SelectionDAG.

Co-Authored-By: Claude Sonnet 4.5 <noreply at anthropic.com>
---
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  | 29 +++++++++++++++----
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |  5 ----
 .../irtranslator-dynamic-alloca-scalable.ll   | 14 +++++++++
 .../RISCV/GlobalISel/irtranslator/alloca.ll   | 15 ++++++++++
 .../RISCV/GlobalISel/irtranslator/fallback.ll | 11 -------
 5 files changed, 53 insertions(+), 21 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-dynamic-alloca-scalable.ll
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/alloca.ll
 delete mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll

diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index a0fe900778cca..a4e26628fe6ff 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -258,14 +258,24 @@ int IRTranslator::getOrCreateFrameIndex(const AllocaInst &AI) {
   if (!Inserted)
     return MapEntry->second;
 
-  uint64_t Size =
-      AI.getAllocationSize(*DL).value_or(TypeSize::getZero()).getFixedValue();
+  TypeSize TySize = AI.getAllocationSize(*DL).value_or(TypeSize::getZero());
+  uint64_t Size = TySize.getKnownMinValue();
 
   // Always allocate at least one byte.
   Size = std::max<uint64_t>(Size, 1u);
 
   int &FI = MapEntry->second;
   FI = MF->getFrameInfo().CreateStackObject(Size, AI.getAlign(), false, &AI);
+
+  // Scalable vectors and structures that contain scalable vectors may
+  // need a special StackID to distinguish them from other (fixed size)
+  // stack objects.
+  if (TySize.isScalable()) {
+    auto StackID =
+        MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
+    MF->getFrameInfo().setStackID(FI, StackID);
+  }
+
   return FI;
 }
 
@@ -3197,11 +3207,20 @@ bool IRTranslator::translateAlloca(const User &U,
   }
 
   Type *Ty = AI.getAllocatedType();
+  TypeSize TySize = DL->getTypeAllocSize(Ty);
 
   Register AllocSize = MRI->createGenericVirtualRegister(IntPtrTy);
-  Register TySize =
-      getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, DL->getTypeAllocSize(Ty)));
-  MIRBuilder.buildMul(AllocSize, NumElts, TySize);
+  Register TySizeReg;
+  if (TySize.isScalable()) {
+    // For scalable types, use vscale * min_value
+    TySizeReg = MRI->createGenericVirtualRegister(IntPtrTy);
+    MIRBuilder.buildVScale(TySizeReg, TySize.getKnownMinValue());
+  } else {
+    // For fixed types, use a constant
+    TySizeReg =
+        getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.getFixedValue()));
+  }
+  MIRBuilder.buildMul(AllocSize, NumElts, TySizeReg);
 
   // Round the size of the allocation up to the stack alignment size
   // by add SA-1 to the size. This doesn't overflow because we're computing
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 90809828e9653..742c5bc4372b2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -25934,11 +25934,6 @@ bool RISCVTargetLowering::fallBackToDAGISel(const Instruction &Inst) const {
         !isa<ReturnInst>(&Inst))
       return true;
 
-  if (const AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
-    if (AI->getAllocatedType()->isScalableTy())
-      return true;
-  }
-
   return false;
 }
 
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-dynamic-alloca-scalable.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-dynamic-alloca-scalable.ll
new file mode 100644
index 0000000000000..04bf589a17505
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-dynamic-alloca-scalable.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -mtriple=aarch64 -mattr=+sve -global-isel -aarch64-enable-gisel-sve %s -o - -stop-after=irtranslator | FileCheck %s
+; Tests for scalable vector allocas in GlobalISel
+
+; Test basic scalable vector alloca (single allocation)
+define ptr @test_single_scalable_alloca() {
+  ; CHECK-LABEL: name: test_single_scalable_alloca
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.local0
+  ; CHECK-NEXT:   $x0 = COPY [[FRAME_INDEX]](p0)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $x0
+  %local0 = alloca <vscale x 16 x i8>
+  ret ptr %local0
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/alloca.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/alloca.ll
new file mode 100644
index 0000000000000..127ba6b804864
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/alloca.ll
@@ -0,0 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -mtriple=riscv64 -mattr=+v -global-isel %s -o - -stop-after=irtranslator | FileCheck %s
+
+; Test that single scalable vector alloca works and store
+define void @test_single_scalable_alloca() {
+  ; CHECK-LABEL: name: test_single_scalable_alloca
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+  ; CHECK-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.local0
+  ; CHECK-NEXT:   G_STORE [[C]](s64), [[FRAME_INDEX]](p0) :: (volatile store (s64) into %ir.local0)
+  ; CHECK-NEXT:   PseudoRET
+  %local0 = alloca <vscale x 16 x i8>
+  store volatile i64 1, ptr %local0
+  ret void
+}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll
deleted file mode 100644
index 8e43e044b7ee5..0000000000000
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll
+++ /dev/null
@@ -1,11 +0,0 @@
-; RUN: llc -mtriple=riscv64 -mattr='+v' -O0 -global-isel -global-isel-abort=2 -pass-remarks-missed='gisel*' -verify-machineinstrs %s -o %t.out 2> %t.err
-; RUN: FileCheck %s --check-prefix=FALLBACK-WITH-REPORT-OUT < %t.out
-; RUN: FileCheck %s --check-prefix=FALLBACK-WITH-REPORT-ERR < %t.err
-
-; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: alloca:
-; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_alloca
-define void @scalable_alloca() #1 {
-  %local0 = alloca <vscale x 16 x i8>
-  load volatile <vscale x 16 x i8>, ptr %local0
-  ret void
-}



More information about the llvm-commits mailing list