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

>From 8fd4ac7c4d468f86f9eb2f37a766def27e87b0e5 Mon Sep 17 00:00:00 2001
From: Jameson Nash <[email protected]>
Date: Fri, 13 Feb 2026 16:18:13 +0000
Subject: [PATCH 1/5] [clang] Change Alloca type when non-default specified

Change alloca semantics to be taken from Sema unless the semantics say
to use the default addrspace, in which case it takes the default from
the datalayout. This lets frontends (or users) to select multiple
address spaces for alloca with some special semantics. For example, it
may be common for a GC to have a separate addrspace for GC-tracked
alloca vs all other alloca. In WASM, this is the flat vs. local address
space, for example.
---
 clang/lib/CodeGen/CGCUDANV.cpp      |  5 +++--
 clang/lib/CodeGen/CGCall.cpp        |  2 +-
 clang/lib/CodeGen/CGCleanup.cpp     |  2 +-
 clang/lib/CodeGen/CGCoroutine.cpp   |  8 ++++----
 clang/lib/CodeGen/CGException.cpp   | 11 +++++++----
 clang/lib/CodeGen/CGExpr.cpp        | 29 ++++++++++++++++++-----------
 clang/lib/CodeGen/CGExprCXX.cpp     |  3 ++-
 clang/lib/CodeGen/CGGPUBuiltin.cpp  |  2 +-
 clang/lib/CodeGen/CodeGenFunction.h |  8 +++++---
 9 files changed, 42 insertions(+), 28 deletions(-)

diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp
index 65f398af7902b..0e91e55597121 100644
--- a/clang/lib/CodeGen/CGCUDANV.cpp
+++ b/clang/lib/CodeGen/CGCUDANV.cpp
@@ -358,9 +358,10 @@ Address 
CGNVCUDARuntime::prepareKernelArgsLLVMOffload(CodeGenFunction &CGF,
   llvm::StructType *KernelLaunchParamsTy =
       llvm::StructType::create(KernelLaunchParamsTypes);
   Address KernelArgs = CGF.CreateTempAllocaWithoutCast(
-      KernelArgsTy, CharUnits::fromQuantity(16), "kernel_args");
+      KernelArgsTy, LangAS::Default, CharUnits::fromQuantity(16),
+      "kernel_args");
   Address KernelLaunchParams = CGF.CreateTempAllocaWithoutCast(
-      KernelLaunchParamsTy, CharUnits::fromQuantity(16),
+      KernelLaunchParamsTy, LangAS::Default, CharUnits::fromQuantity(16),
       "kernel_launch_params");
 
   auto KernelArgsSize = CGM.getDataLayout().getTypeAllocSize(KernelArgsTy);
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 09f6d63a36bd6..cb1aa281b96bc 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5502,7 +5502,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo 
&CallInfo,
       AI = new llvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(), "argmem",
                                 IP->getIterator());
     } else {
-      AI = CreateTempAlloca(ArgStruct, "argmem");
+      AI = CreateTempAlloca(ArgStruct, LangAS::Default, "argmem");
     }
     auto Align = CallInfo.getArgStructAlignment();
     AI->setAlignment(Align.getAsAlign());
diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index 977f81a641ff3..02c057f7fb962 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -279,7 +279,7 @@ void EHScopeStack::popNullFixups() {
 RawAddress CodeGenFunction::createCleanupActiveFlag() {
   // Create a variable to decide whether the cleanup needs to be run.
   RawAddress active = CreateTempAllocaWithoutCast(
-      Builder.getInt1Ty(), CharUnits::One(), "cleanup.cond");
+      Builder.getInt1Ty(), LangAS::Default, CharUnits::One(), "cleanup.cond");
 
   // Initialize it to false at a site that's guaranteed to be run
   // before each evaluation.
diff --git a/clang/lib/CodeGen/CGCoroutine.cpp 
b/clang/lib/CodeGen/CGCoroutine.cpp
index 700a8fd4a48c1..b41339ed48408 100644
--- a/clang/lib/CodeGen/CGCoroutine.cpp
+++ b/clang/lib/CodeGen/CGCoroutine.cpp
@@ -354,8 +354,8 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction 
&CGF, CGCoroData &Co
   CXXTryStmt *TryStmt = nullptr;
   if (Coro.ExceptionHandler && Kind == AwaitKind::Init &&
       StmtCanThrow(S.getResumeExpr())) {
-    Coro.ResumeEHVar =
-        CGF.CreateTempAlloca(Builder.getInt1Ty(), Prefix + Twine("resume.eh"));
+    Coro.ResumeEHVar = CGF.CreateTempAlloca(
+        Builder.getInt1Ty(), LangAS::Default, Prefix + Twine("resume.eh"));
     Builder.CreateFlagStore(true, Coro.ResumeEHVar);
 
     auto Loc = S.getResumeExpr()->getExprLoc();
@@ -717,8 +717,8 @@ struct GetReturnObjectManager {
     }
 
     // Set GRO flag that it is not initialized yet
-    GroActiveFlag = CGF.CreateTempAlloca(Builder.getInt1Ty(), CharUnits::One(),
-                                         "gro.active");
+    GroActiveFlag = CGF.CreateTempAlloca(Builder.getInt1Ty(), LangAS::Default,
+                                         CharUnits::One(), "gro.active");
     Builder.CreateStore(Builder.getFalse(), GroActiveFlag);
   }
 
diff --git a/clang/lib/CodeGen/CGException.cpp 
b/clang/lib/CodeGen/CGException.cpp
index 99dfaa80be429..a98fa026f5c8d 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -425,13 +425,14 @@ void CodeGenFunction::EmitAnyExprToExn(const Expr *e, 
Address addr) {
 
 Address CodeGenFunction::getExceptionSlot() {
   if (!ExceptionSlot)
-    ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot");
+    ExceptionSlot = CreateTempAlloca(Int8PtrTy, LangAS::Default, "exn.slot");
   return Address(ExceptionSlot, Int8PtrTy, getPointerAlign());
 }
 
 Address CodeGenFunction::getEHSelectorSlot() {
   if (!EHSelectorSlot)
-    EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot");
+    EHSelectorSlot =
+        CreateTempAlloca(Int32Ty, LangAS::Default, "ehselector.slot");
   return Address(EHSelectorSlot, Int32Ty, CharUnits::fromQuantity(4));
 }
 
@@ -1453,7 +1454,8 @@ void CodeGenFunction::FinallyInfo::enter(CodeGenFunction 
&CGF, const Stmt *body,
   llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
   SavedExnVar = nullptr;
   if (rethrowFnTy->getNumParams())
-    SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
+    SavedExnVar =
+        CGF.CreateTempAlloca(CGF.Int8PtrTy, LangAS::Default, "finally.exn");
 
   // A finally block is a statement which must be executed on any edge
   // out of a given scope.  Unlike a cleanup, the finally block may
@@ -1473,7 +1475,8 @@ void CodeGenFunction::FinallyInfo::enter(CodeGenFunction 
&CGF, const Stmt *body,
   RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
 
   // Whether the finally block is being executed for EH purposes.
-  ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
+  ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), LangAS::Default,
+                                  "finally.for-eh");
   CGF.Builder.CreateFlagStore(false, ForEHVar);
 
   // Enter a normal cleanup which will perform the @finally block.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index f6cb636368598..036e897c368dc 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -105,15 +105,13 @@ static llvm::StringRef 
GetUBSanTrapForHandler(SanitizerHandler ID) {
 /// CreateTempAlloca - This creates a alloca and inserts it into the entry
 /// block.
 RawAddress
-CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits Align,
-                                             const Twine &Name,
-                                             llvm::Value *ArraySize) {
+CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, LangAS 
UseAddrSpace, CharUnits Align, const Twine &Name, llvm::Value *ArraySize) {
   if (getLangOpts().EmitLogicalPointer) {
     auto Alloca = Builder.CreateStructuredAlloca(Ty, Name);
     return RawAddress(Alloca, Ty, Align, KnownNonNull);
   }
 
-  auto *Alloca = CreateTempAlloca(Ty, Name, ArraySize);
+  auto *Alloca = CreateTempAlloca(Ty, UseAddrSpace, Name, ArraySize);
   Alloca->setAlignment(Align.getAsAlign());
   return RawAddress(Alloca, Ty, Align, KnownNonNull);
 }
@@ -147,7 +145,8 @@ RawAddress CodeGenFunction::CreateTempAlloca(llvm::Type 
*Ty, LangAS DestLangAS,
                                              CharUnits Align, const Twine 
&Name,
                                              llvm::Value *ArraySize,
                                              RawAddress *AllocaAddr) {
-  RawAddress Alloca = CreateTempAllocaWithoutCast(Ty, Align, Name, ArraySize);
+  RawAddress Alloca =
+      CreateTempAllocaWithoutCast(Ty, DestLangAS, Align, Name, ArraySize);
   if (AllocaAddr)
     *AllocaAddr = Alloca;
   return MaybeCastStackAddressSpace(Alloca, DestLangAS, ArraySize);
@@ -157,15 +156,21 @@ RawAddress CodeGenFunction::CreateTempAlloca(llvm::Type 
*Ty, LangAS DestLangAS,
 /// block if \p ArraySize is nullptr, otherwise inserts it at the current
 /// insertion point of the builder.
 llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty,
+                                                    LangAS UseLangAS,
                                                     const Twine &Name,
                                                     llvm::Value *ArraySize) {
+  // Determine the address space for the alloca, whether marked as default
+  // or specified explicitly
+  unsigned AllocaAS = UseLangAS == LangAS::Default
+                          ? CGM.getDataLayout().getAllocaAddrSpace()
+                          : getContext().getTargetAddressSpace(UseLangAS);
+
   llvm::AllocaInst *Alloca;
   if (ArraySize)
-    Alloca = Builder.CreateAlloca(Ty, ArraySize, Name);
+    Alloca = Builder.CreateAlloca(Ty, AllocaAS, ArraySize, Name);
   else
-    Alloca =
-        new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(),
-                             ArraySize, Name, AllocaInsertPt->getIterator());
+    Alloca = new llvm::AllocaInst(Ty, AllocaAS, ArraySize, Name,
+                                  AllocaInsertPt->getIterator());
   if (SanOpts.Mask & SanitizerKind::Address) {
     Alloca->addAnnotationMetadata({"alloca_name_altered", Name.str()});
   }
@@ -189,7 +194,8 @@ RawAddress 
CodeGenFunction::CreateDefaultAlignTempAlloca(llvm::Type *Ty,
 RawAddress CodeGenFunction::CreateIRTempWithoutCast(QualType Ty,
                                                     const Twine &Name) {
   CharUnits Align = getContext().getTypeAlignInChars(Ty);
-  return CreateTempAllocaWithoutCast(ConvertType(Ty), Align, Name, nullptr);
+  return CreateTempAllocaWithoutCast(ConvertType(Ty), Ty.getAddressSpace(),
+                                     Align, Name, nullptr);
 }
 
 RawAddress CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name,
@@ -225,7 +231,8 @@ RawAddress CodeGenFunction::CreateMemTemp(QualType Ty, 
CharUnits Align,
 RawAddress CodeGenFunction::CreateMemTempWithoutCast(QualType Ty,
                                                      CharUnits Align,
                                                      const Twine &Name) {
-  return CreateTempAllocaWithoutCast(ConvertTypeForMem(Ty), Align, Name);
+  return CreateTempAllocaWithoutCast(ConvertTypeForMem(Ty),
+                                     Ty.getAddressSpace(), Align, Name);
 }
 
 RawAddress CodeGenFunction::CreateMemTempWithoutCast(QualType Ty,
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 0dc2e0bb82114..68514dcbc924a 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1815,7 +1815,8 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl 
*DeleteFD,
     assert(!TagAlloca);
     llvm::Type *Ty = getTypes().ConvertType(TagType);
     CharUnits Align = CGM.getNaturalTypeAlignment(TagType);
-    llvm::AllocaInst *TagAllocation = CreateTempAlloca(Ty, TagName);
+    llvm::AllocaInst *TagAllocation =
+        CreateTempAlloca(Ty, TagType.getAddressSpace(), TagName);
     TagAllocation->setAlignment(Align.getAsAlign());
     DeleteArgs.add(RValue::getAggregate(Address(TagAllocation, Ty, Align)),
                    TagType);
diff --git a/clang/lib/CodeGen/CGGPUBuiltin.cpp 
b/clang/lib/CodeGen/CGGPUBuiltin.cpp
index 47cac03b64532..6b0cebdac1960 100644
--- a/clang/lib/CodeGen/CGGPUBuiltin.cpp
+++ b/clang/lib/CodeGen/CGGPUBuiltin.cpp
@@ -90,7 +90,7 @@ packArgsIntoNVPTXFormatBuffer(CodeGenFunction *CGF, const 
CallArgList &Args) {
     // that the alignment of the llvm type was the same as the alignment of the
     // clang type.
     llvm::Type *AllocaTy = llvm::StructType::create(ArgTypes, "printf_args");
-    llvm::Value *Alloca = CGF->CreateTempAlloca(AllocaTy);
+    llvm::Value *Alloca = CGF->CreateTempAlloca(AllocaTy, LangAS::Default);
 
     for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I) {
       llvm::Value *P = Builder.CreateStructGEP(AllocaTy, Alloca, I - 1);
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index aeace0d789a61..86e46b84f992e 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -2892,7 +2892,8 @@ class CodeGenFunction : public CodeGenTypeCache {
   ///
   /// The cast is not performed in CreateTempAllocaWithoutCast. This is
   /// more efficient if the caller knows that the address will not be exposed.
-  llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp",
+  llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, LangAS UseAddrSpace,
+                                     const Twine &Name = "tmp",
                                      llvm::Value *ArraySize = nullptr);
 
   /// CreateTempAlloca - This creates a alloca and inserts it into the entry
@@ -2916,7 +2917,8 @@ class CodeGenFunction : public CodeGenTypeCache {
                             Alloca);
   }
 
-  RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align,
+  RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, LangAS UseAddrSpace,
+                                         CharUnits align,
                                          const Twine &Name = "tmp",
                                          llvm::Value *ArraySize = nullptr);
 
@@ -5651,7 +5653,7 @@ DominatingLLVMValue::save(CodeGenFunction &CGF, 
llvm::Value *value) {
                    CGF.CGM.getDataLayout().getPrefTypeAlign(value->getType()))
                    .getAsAlign();
   llvm::AllocaInst *AI =
-      CGF.CreateTempAlloca(value->getType(), "cond-cleanup.save");
+      CGF.CreateTempAlloca(value->getType(), LangAS::Default, 
"cond-cleanup.save");
   AI->setAlignment(align);
   CGF.Builder.CreateAlignedStore(value, AI, align);
 

>From 3bee32afe8b4cff1a53dac7ab19c1d7b82d6d6b9 Mon Sep 17 00:00:00 2001
From: Jameson Nash <[email protected]>
Date: Thu, 29 Jan 2026 17:20:00 +0000
Subject: [PATCH 2/5] [Clang][WebAssembly] Move reference type alloca handling
 to frontend

Move WebAssembly reference type alloca address space selection from the
WebAssemblyRefTypeMem2Local LLVM pass into Clang's Sema definition. This
is a semantic requirement (essentially there are two alloca space
here--flat memory and local memory), so it doesn't seem to make sense
for LLVM to try to recover this information late, and especially to
assume getAllocatedType can provide this information.

Similar to global, the key idea here is to use the user's specified
address space for creating an alloca, instead of doing an addrspace cast
to that. That especially allows a frontend to force the alloca to live
in an addrspace that isn't the default one.

This then lets us delete the IR pass from LLVM that relies on bypassing
the validator (which only happened to work since it only fed a load or
store instruction in the test) and using the non-semantic
getAllocatedType to recover and fix the incorrect alloca addrspace
originally set by Seme.

Building upon that, this then defines an addrspace for the WebAssembly
local semantics LangAS::wasm_var, matching WASM_ADDRESS_SPACE_VAR, for
pointers to reference types (externref / funcref).

Example:
  __externref_t x;       // ptr addrspace(10)
  __externref_t *px;     // ptr addrspace(1) in AST (points to ptr 
addrspace(10))
  __externref_t &rx = x; // ptr addrspace(1) in AST

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
---
 clang/include/clang/Basic/AddressSpaces.h     |  1 +
 clang/include/clang/Sema/Sema.h               |  1 +
 clang/lib/AST/ASTContext.cpp                  |  9 ++
 clang/lib/AST/Decl.cpp                        | 10 ++-
 clang/lib/AST/TypePrinter.cpp                 |  2 +
 clang/lib/Basic/TargetInfo.cpp                |  1 +
 clang/lib/Basic/Targets/AArch64.h             |  3 +-
 clang/lib/Basic/Targets/AMDGPU.cpp            |  4 +
 clang/lib/Basic/Targets/DirectX.h             |  3 +-
 clang/lib/Basic/Targets/NVPTX.h               |  3 +-
 clang/lib/Basic/Targets/SPIR.h                | 11 ++-
 clang/lib/Basic/Targets/SystemZ.h             |  3 +-
 clang/lib/Basic/Targets/TCE.h                 |  3 +-
 clang/lib/Basic/Targets/WebAssembly.h         |  1 +
 clang/lib/Basic/Targets/X86.h                 |  3 +-
 clang/lib/CodeGen/CGDecl.cpp                  | 10 +--
 clang/lib/Sema/SemaDecl.cpp                   | 86 ++++++++++---------
 .../WebAssembly/reference-type-alloca.c       | 35 ++++++++
 .../test/CodeGen/WebAssembly/wasm-externref.c |  6 +-
 clang/test/CodeGen/WebAssembly/wasm-funcref.c | 18 ++--
 .../test/CodeGenCXX/wasm-reftypes-mangle.cpp  |  4 +-
 clang/test/Sema/wasm-refs-and-tables.c        | 18 ++--
 .../SemaTemplate/address_space-dependent.cpp  |  4 +-
 23 files changed, 160 insertions(+), 79 deletions(-)
 create mode 100644 clang/test/CodeGen/WebAssembly/reference-type-alloca.c

diff --git a/clang/include/clang/Basic/AddressSpaces.h 
b/clang/include/clang/Basic/AddressSpaces.h
index a941805423bca..1bffb13bcdc94 100644
--- a/clang/include/clang/Basic/AddressSpaces.h
+++ b/clang/include/clang/Basic/AddressSpaces.h
@@ -67,6 +67,7 @@ enum class LangAS : unsigned {
 
   // Wasm specific address spaces.
   wasm_funcref,
+  wasm_var,
 
   // This denotes the count of language-specific address spaces and also
   // the offset added to the target-specific address spaces, which are usually
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b8d760e7e0975..ec50948bfff23 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4702,6 +4702,7 @@ class Sema final : public SemaBase {
 
   void deduceOpenCLAddressSpace(VarDecl *decl);
   void deduceHLSLAddressSpace(VarDecl *decl);
+  void deduceWasmAddressSpace(VarDecl *Decl);
 
   /// Adjust the \c DeclContext for a function or variable that might be a
   /// function-local external declaration.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index abf0cd5e18c2b..6d2b717ce71b6 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -15099,6 +15099,15 @@ LangAS 
ASTContext::getLangASForBuiltinAddressSpace(unsigned AS) const {
   if (LangOpts.CUDA)
     return getTargetInfo().getCUDABuiltinAddressSpace(AS);
 
+  if (getTargetInfo().getTriple().isWasm()) {
+    switch (AS) {
+    case 1:
+      return LangAS::wasm_var;
+    case 20:
+      return LangAS::wasm_funcref;
+    }
+  }
+
   return getLangASFromTargetAS(AS);
 }
 
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index b797ebfa1a7e1..4a800453e9ca2 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2919,9 +2919,17 @@ void VarDecl::assignAddressSpace(const ASTContext &Ctxt, 
LangAS AS) {
 }
 
 void VarDecl::deduceParmAddressSpace(const ASTContext &Ctxt) {
-  assert(isa<ParmVarDecl>(this) || isa<ImplicitParamDecl>(this));
   if (Ctxt.getLangOpts().OpenCL)
     assignAddressSpace(Ctxt, LangAS::opencl_private);
+  if (Ctxt.getTargetInfo().getTriple().isWasm()) {
+    // For WebAssembly, variables holding reference types must have a special
+    // address space when taking their reference.
+    QualType Type = getType();
+    if (const auto *ATy = dyn_cast<ArrayType>(Type))
+      Type = ATy->getElementType();
+    if (Type.isWebAssemblyReferenceType())
+      assignAddressSpace(Ctxt, LangAS::wasm_var);
+  }
 }
 
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index d85ed244f643a..4c51754a2282f 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2720,6 +2720,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
     return "hlsl_push_constant";
   case LangAS::wasm_funcref:
     return "__funcref";
+  case LangAS::wasm_var:
+    return "__externref";
   default:
     return std::to_string(toTargetAddressSpace(AS));
   }
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 854d23cadaea2..41ea62152aafb 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -55,6 +55,7 @@ static const LangASMap FakeAddrSpaceMap = {
     18, // hlsl_output
     19, // hlsl_push_constant
     20, // wasm_funcref
+    21, // wasm_externref
 };
 
 // TargetInfo Constructor.
diff --git a/clang/lib/Basic/Targets/AArch64.h 
b/clang/lib/Basic/Targets/AArch64.h
index 0a29bad81939b..5bbda7313cc1c 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -53,7 +53,8 @@ static const unsigned ARM64AddrSpaceMap[] = {
     0, // hlsl_push_constant
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
-    20, // wasm_funcref
+    0, // wasm_funcref
+    0,  // wasm_var
 };
 
 using AArch64FeatureSet = llvm::SmallDenseSet<StringRef, 32>;
diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp 
b/clang/lib/Basic/Targets/AMDGPU.cpp
index bfa956fa9a4e3..ecd0fed5f5530 100644
--- a/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -56,6 +56,10 @@ const LangASMap AMDGPUTargetInfo::AMDGPUAddrSpaceMap = {
     llvm::AMDGPUAS::PRIVATE_ADDRESS, // hlsl_input
     llvm::AMDGPUAS::PRIVATE_ADDRESS, // hlsl_output
     llvm::AMDGPUAS::GLOBAL_ADDRESS,  // hlsl_push_constant
+    // Wasm address space values for this target are dummy values,
+    // as it is only enabled for Wasm targets.
+    llvm::AMDGPUAS::FLAT_ADDRESS, // wasm_funcref
+    llvm::AMDGPUAS::FLAT_ADDRESS, // wasm_var
 };
 
 } // namespace targets
diff --git a/clang/lib/Basic/Targets/DirectX.h 
b/clang/lib/Basic/Targets/DirectX.h
index 8b21b86bac264..7eeb169299fd3 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -50,7 +50,8 @@ static const unsigned DirectXAddrSpaceMap[] = {
     0, // hlsl_push_constant
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
-    20, // wasm_funcref
+    0, // wasm_funcref
+    0,  // wasm_var
 };
 
 class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index 69ee20f38343b..ecce7f05dcd6c 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -54,7 +54,8 @@ static const unsigned NVPTXAddrSpaceMap[] = {
     0, // hlsl_push_constant
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
-    20, // wasm_funcref
+    0, // wasm_funcref
+    0,  // wasm_var
 };
 
 /// The DWARF address class. Taken from
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 389cc075a3a0b..798389dba4b33 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -58,7 +58,8 @@ static const unsigned SPIRDefIsPrivMap[] = {
     13, // hlsl_push_constant
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
-    20, // wasm_funcref
+    0, // wasm_funcref
+    0,  // wasm_var
 };
 
 // Used by both the SPIR and SPIR-V targets.
@@ -96,7 +97,8 @@ static const unsigned SPIRDefIsGenMap[] = {
     13, // hlsl_push_constant
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
-    20, // wasm_funcref
+    0, // wasm_funcref
+    0,  // wasm_var
 };
 
 // Base class for SPIR and SPIR-V target info.
@@ -213,7 +215,10 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public 
TargetInfo {
   }
 
   void setAddressSpaceMap(bool DefaultIsGeneric) {
-    AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;
+    if (DefaultIsGeneric)
+      AddrSpaceMap = &SPIRDefIsGenMap;
+    else
+      AddrSpaceMap = &SPIRDefIsPrivMap;
   }
 
   void adjust(DiagnosticsEngine &Diags, LangOptions &Opts,
diff --git a/clang/lib/Basic/Targets/SystemZ.h 
b/clang/lib/Basic/Targets/SystemZ.h
index 00f7d7a055b24..40376f6e50f5d 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -48,7 +48,8 @@ static const unsigned ZOSAddressMap[] = {
     0, // hlsl_input
     0, // hlsl_output
     0, // hlsl_push_constant
-    0  // wasm_funcref
+    0, // wasm_funcref
+    0  // wasm_var
 };
 
 class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h
index 1360298de9794..c7d25a3d696fd 100644
--- a/clang/lib/Basic/Targets/TCE.h
+++ b/clang/lib/Basic/Targets/TCE.h
@@ -59,7 +59,8 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
     0, // hlsl_push_constant
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
-    20, // wasm_funcref
+    0, // wasm_funcref
+    0,  // wasm_var
 };
 
 class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo {
diff --git a/clang/lib/Basic/Targets/WebAssembly.h 
b/clang/lib/Basic/Targets/WebAssembly.h
index 6085197498163..f407c32ee27f2 100644
--- a/clang/lib/Basic/Targets/WebAssembly.h
+++ b/clang/lib/Basic/Targets/WebAssembly.h
@@ -49,6 +49,7 @@ static const unsigned WebAssemblyAddrSpaceMap[] = {
     0,  // hlsl_output
     0,  // hlsl_push_constant
     20, // wasm_funcref
+    1,  // wasm_var
 };
 
 class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index c8c5d280754b4..4dbc631742099 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -54,7 +54,8 @@ static const unsigned X86AddrSpaceMap[] = {
     0,   // hlsl_push_constant
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
-    20, // wasm_funcref
+    0, // wasm_funcref
+    0,  // wasm_var
 };
 
 // X86 target abstract base class; x86-32 and x86-64 are very close, so
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 7608f8cb6fc7a..917a53b47736f 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1482,9 +1482,11 @@ static bool shouldExtendLifetime(const ASTContext 
&Context,
 CodeGenFunction::AutoVarEmission
 CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
   QualType Ty = D.getType();
-  assert(
-      Ty.getAddressSpace() == LangAS::Default ||
-      (Ty.getAddressSpace() == LangAS::opencl_private && 
getLangOpts().OpenCL));
+  assert(Ty.getAddressSpace() == LangAS::Default ||
+         (Ty.getAddressSpace() == LangAS::opencl_private &&
+          getLangOpts().OpenCL) ||
+         (Ty.getAddressSpace() == LangAS::wasm_var &&
+          getTarget().getTriple().isWasm()));
 
   AutoVarEmission emission(D);
 
@@ -2684,8 +2686,6 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, 
ParamValue Arg,
     Arg.getAnyValue()->setName(D.getName());
 
   QualType Ty = D.getType();
-  assert((getLangOpts().OpenCL || Ty.getAddressSpace() == LangAS::Default) &&
-         "parameter has non-default address space in non-OpenCL mode");
 
   // Use better IR generation for certain implicit parameters.
   if (auto IPD = dyn_cast<ImplicitParamDecl>(&D)) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index cddcf3a010279..d354465f4185a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -29,6 +29,7 @@
 #include "clang/AST/Randstruct.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/Type.h"
+#include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/DiagnosticComment.h"
 #include "clang/Basic/HLSLRuntime.h"
@@ -7108,6 +7109,11 @@ void Sema::deduceOpenCLAddressSpace(VarDecl *Var) {
   Var->assignAddressSpace(Context, ImplAS);
 }
 
+void Sema::deduceWasmAddressSpace(VarDecl *Var) {
+  if (Context.getTargetInfo().getTriple().isWasm())
+    Var->deduceParmAddressSpace(Context);
+}
+
 static void checkWeakAttr(Sema &S, NamedDecl &ND) {
   // 'weak' only applies to declarations with external linkage.
   if (WeakAttr *Attr = ND.getAttr<WeakAttr>()) {
@@ -8226,17 +8232,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
     }
   }
 
-  // WebAssembly tables are always in address space 1 (wasm_var). Don't apply
-  // address space if the table has local storage (semantic checks elsewhere
-  // will produce an error anyway).
-  if (const auto *ATy = dyn_cast<ArrayType>(NewVD->getType())) {
-    if (ATy && ATy->getElementType().isWebAssemblyReferenceType() &&
-        !NewVD->hasLocalStorage()) {
-      QualType Type = Context.getAddrSpaceQualType(
-          NewVD->getType(), Context.getLangASForBuiltinAddressSpace(1));
-      NewVD->setType(Type);
-    }
-  }
+  deduceWasmAddressSpace(NewVD);
 
   LoadExternalExtnameUndeclaredIdentifiers();
 
@@ -8926,12 +8922,45 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) 
{
     NewVD->setType(T);
   }
 
+  // WebAssembly tables must be static with a zero length and can't be
+  // declared within functions.
+  if (T->isWebAssemblyTableType()) {
+    if (getCurScope()->getParent()) { // Parent is null at top-level
+      Diag(NewVD->getLocation(), diag::err_wasm_table_in_function);
+      NewVD->setInvalidDecl();
+      return;
+    }
+    if (NewVD->getStorageClass() != SC_Static) {
+      Diag(NewVD->getLocation(), diag::err_wasm_table_must_be_static);
+      NewVD->setInvalidDecl();
+      return;
+    }
+    const auto *ATy = dyn_cast<ConstantArrayType>(T.getTypePtr());
+    if (!ATy || ATy->getZExtSize() != 0) {
+      Diag(NewVD->getLocation(),
+           diag::err_typecheck_wasm_table_must_have_zero_length);
+      NewVD->setInvalidDecl();
+      return;
+    }
+  }
+
   // Emit an error if an address space was applied to decl with local storage.
   // This includes arrays of objects with address space qualifiers, but not
   // automatic variables that point to other address spaces.
   // ISO/IEC TR 18037 S5.1.2
-  if (!getLangOpts().OpenCL && NewVD->hasLocalStorage() &&
-      T.getAddressSpace() != LangAS::Default) {
+  if (T.isWebAssemblyReferenceType() &&
+      Context.getTargetInfo().getTriple().isWasm() && !T->isArrayType()) {
+    // WebAssembly: reference types must be in
+    // wasm_var address space (AS 1) so they can be stored in WebAssembly
+    // locals. Arrays of reference types (WebAssembly tables) are handled
+    // separately below.
+    if (T.getAddressSpace() != LangAS::wasm_var) {
+      Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 1;
+      NewVD->setInvalidDecl();
+      return;
+    }
+  } else if (!getLangOpts().OpenCL && NewVD->hasLocalStorage() &&
+             T.getAddressSpace() != LangAS::Default) {
     Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 0;
     NewVD->setInvalidDecl();
     return;
@@ -9059,28 +9088,6 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
     }
   }
 
-  // WebAssembly tables must be static with a zero length and can't be
-  // declared within functions.
-  if (T->isWebAssemblyTableType()) {
-    if (getCurScope()->getParent()) { // Parent is null at top-level
-      Diag(NewVD->getLocation(), diag::err_wasm_table_in_function);
-      NewVD->setInvalidDecl();
-      return;
-    }
-    if (NewVD->getStorageClass() != SC_Static) {
-      Diag(NewVD->getLocation(), diag::err_wasm_table_must_be_static);
-      NewVD->setInvalidDecl();
-      return;
-    }
-    const auto *ATy = dyn_cast<ConstantArrayType>(T.getTypePtr());
-    if (!ATy || ATy->getZExtSize() != 0) {
-      Diag(NewVD->getLocation(),
-           diag::err_typecheck_wasm_table_must_have_zero_length);
-      NewVD->setInvalidDecl();
-      return;
-    }
-  }
-
   // zero sized static arrays are not allowed in HIP device functions
   if (getLangOpts().HIP && LangOpts.CUDAIsDevice) {
     if (FunctionDecl *FD = getCurFunctionDecl();
@@ -13476,6 +13483,8 @@ bool Sema::DeduceVariableDeclarationType(VarDecl 
*VDecl, bool DirectInit,
   if (getLangOpts().HLSL)
     HLSL().deduceAddressSpace(VDecl);
 
+  deduceWasmAddressSpace(VDecl);
+
   // If this is a redeclaration, check that the type we just deduced matches
   // the previously declared type.
   if (VarDecl *Old = VDecl->getPreviousDecl()) {
@@ -15955,10 +15964,9 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 
SourceLocation StartLoc,
       // to be qualified with an address space.
       !(getLangOpts().OpenCL &&
         (T->isArrayType() || T.getAddressSpace() == LangAS::opencl_private)) &&
-      // WebAssembly allows reference types as parameters. Funcref in 
particular
-      // lives in a different address space.
-      !(T->isFunctionPointerType() &&
-        T.getAddressSpace() == LangAS::wasm_funcref) &&
+      // WebAssembly reference types like __externref_t must be in wasm_var.
+      !(T.isWebAssemblyReferenceType() &&
+        T.getAddressSpace() == LangAS::wasm_var) &&
       // HLSL allows function arguments to be qualified with an address space
       // if the groupshared annotation is used.
       !(getLangOpts().HLSL &&
diff --git a/clang/test/CodeGen/WebAssembly/reference-type-alloca.c 
b/clang/test/CodeGen/WebAssembly/reference-type-alloca.c
new file mode 100644
index 0000000000000..79fa7a19e26c4
--- /dev/null
+++ b/clang/test/CodeGen/WebAssembly/reference-type-alloca.c
@@ -0,0 +1,35 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 6
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature 
+reference-types -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define ptr addrspace(10) @test_externref(
+// CHECK-SAME: ptr addrspace(10) [[INPUT:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[INPUT_ADDR:%.*]] = alloca ptr addrspace(10), align 1, 
addrspace(1)
+// CHECK-NEXT:    [[LOCAL:%.*]] = alloca ptr addrspace(10), align 1, 
addrspace(1)
+// CHECK-NEXT:    store ptr addrspace(10) [[INPUT]], ptr addrspace(1) 
[[INPUT_ADDR]], align 1
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(10), ptr addrspace(1) 
[[INPUT_ADDR]], align 1
+// CHECK-NEXT:    store ptr addrspace(10) [[TMP0]], ptr addrspace(1) 
[[LOCAL]], align 1
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr addrspace(10), ptr addrspace(1) 
[[LOCAL]], align 1
+// CHECK-NEXT:    ret ptr addrspace(10) [[TMP1]]
+//
+__externref_t test_externref(__externref_t input) {
+  __externref_t local = input;
+  return local;
+}
+
+typedef void (*__funcref funcref_t)();
+// CHECK-LABEL: define ptr addrspace(20) @test_funcref(
+// CHECK-SAME: ptr addrspace(20) noundef [[INPUT:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[INPUT_ADDR:%.*]] = alloca ptr addrspace(20), align 4, 
addrspace(1)
+// CHECK-NEXT:    [[LOCAL:%.*]] = alloca ptr addrspace(20), align 4, 
addrspace(1)
+// CHECK-NEXT:    store ptr addrspace(20) [[INPUT]], ptr addrspace(1) 
[[INPUT_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(20), ptr addrspace(1) 
[[INPUT_ADDR]], align 4
+// CHECK-NEXT:    store ptr addrspace(20) [[TMP0]], ptr addrspace(1) 
[[LOCAL]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr addrspace(20), ptr addrspace(1) 
[[LOCAL]], align 4
+// CHECK-NEXT:    ret ptr addrspace(20) [[TMP1]]
+//
+funcref_t test_funcref(funcref_t input) {
+  funcref_t local = input;
+  return local;
+}
diff --git a/clang/test/CodeGen/WebAssembly/wasm-externref.c 
b/clang/test/CodeGen/WebAssembly/wasm-externref.c
index 788438bb4a86a..c3f337b2b22b4 100644
--- a/clang/test/CodeGen/WebAssembly/wasm-externref.c
+++ b/clang/test/CodeGen/WebAssembly/wasm-externref.c
@@ -7,9 +7,9 @@ void helper(externref_t);
 
 // CHECK-LABEL: @handle(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[OBJ_ADDR:%.*]] = alloca ptr addrspace(10), align 1
-// CHECK-NEXT:    store ptr addrspace(10) [[OBJ:%.*]], ptr [[OBJ_ADDR]], align 
1
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(10), ptr [[OBJ_ADDR]], 
align 1
+// CHECK-NEXT:    [[OBJ_ADDR:%.*]] = alloca ptr addrspace(10), align 1, 
addrspace(1)
+// CHECK-NEXT:    store ptr addrspace(10) [[OBJ:%.*]], ptr addrspace(1) 
[[OBJ_ADDR]], align 1
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(10), ptr addrspace(1) 
[[OBJ_ADDR]], align 1
 // CHECK-NEXT:    call void @helper(ptr addrspace(10) [[TMP0]])
 // CHECK-NEXT:    ret void
 //
diff --git a/clang/test/CodeGen/WebAssembly/wasm-funcref.c 
b/clang/test/CodeGen/WebAssembly/wasm-funcref.c
index f01af0db321dd..c1006893e3d4f 100644
--- a/clang/test/CodeGen/WebAssembly/wasm-funcref.c
+++ b/clang/test/CodeGen/WebAssembly/wasm-funcref.c
@@ -29,9 +29,9 @@ fn_funcref_t get_null_ii() {
 // Identity function for funcref.
 // CHECK-LABEL: @identity(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[FN_ADDR:%.*]] = alloca ptr addrspace(20), align 4
-// CHECK-NEXT:    store ptr addrspace(20) [[FN:%.*]], ptr [[FN_ADDR]], align 4
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(20), ptr [[FN_ADDR]], 
align 4
+// CHECK-NEXT:    [[FN_ADDR:%.*]] = alloca ptr addrspace(20), align 4, 
addrspace(1)
+// CHECK-NEXT:    store ptr addrspace(20) [[FN:%.*]], ptr addrspace(1) 
[[FN_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(20), ptr addrspace(1) 
[[FN_ADDR]], align 4
 // CHECK-NEXT:    ret ptr addrspace(20) [[TMP0]]
 //
 funcref_t identity(funcref_t fn) {
@@ -43,9 +43,9 @@ void helper(funcref_t);
 // Pass funcref ref as an argument to a helper function.
 // CHECK-LABEL: @handle(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[FN_ADDR:%.*]] = alloca ptr addrspace(20), align 4
-// CHECK-NEXT:    store ptr addrspace(20) [[FN:%.*]], ptr [[FN_ADDR]], align 4
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(20), ptr [[FN_ADDR]], 
align 4
+// CHECK-NEXT:    [[FN_ADDR:%.*]] = alloca ptr addrspace(20), align 4, 
addrspace(1)
+// CHECK-NEXT:    store ptr addrspace(20) [[FN:%.*]], ptr addrspace(1) 
[[FN_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(20), ptr addrspace(1) 
[[FN_ADDR]], align 4
 // CHECK-NEXT:    call void @helper(ptr addrspace(20) noundef [[TMP0]])
 // CHECK-NEXT:    ret i32 0
 //
@@ -70,11 +70,11 @@ fn_funcref_t get_ref(fn_t fnptr) {
 // Call funcref
 // CHECK-LABEL: @call_fn(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[REF_ADDR:%.*]] = alloca ptr addrspace(20), align 4
+// CHECK-NEXT:    [[REF_ADDR:%.*]] = alloca ptr addrspace(20), align 4, 
addrspace(1)
 // CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store ptr addrspace(20) [[REF:%.*]], ptr [[REF_ADDR]], align 
4
+// CHECK-NEXT:    store ptr addrspace(20) [[REF:%.*]], ptr addrspace(1) 
[[REF_ADDR]], align 4
 // CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(20), ptr [[REF_ADDR]], 
align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr addrspace(20), ptr addrspace(1) 
[[REF_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[CALL:%.*]] = call addrspace(20) i32 [[TMP0]](i32 noundef 
[[TMP1]])
 // CHECK-NEXT:    ret i32 [[CALL]]
diff --git a/clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp 
b/clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
index 20e33cfdaa31c..e736732ac87a9 100644
--- a/clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
+++ b/clang/test/CodeGenCXX/wasm-reftypes-mangle.cpp
@@ -7,10 +7,10 @@
 typedef void (*__funcref funcref_t)();
 
 // Global funcref variables - test that codegen doesn't crash.
-// CHECK-DAG: @fptr = global ptr addrspace(20) null
+// CHECK-DAG: @fptr = addrspace(1) global ptr addrspace(20) null
 funcref_t fptr;
 
-// CHECK-DAG: @fpt2 = global ptr addrspace(20) null
+// CHECK-DAG: @fpt2 = addrspace(1) global ptr addrspace(20) null
 void (*__funcref fpt2)();
 
 // CHECK-DAG: _Z2f1u11externref_t
diff --git a/clang/test/Sema/wasm-refs-and-tables.c 
b/clang/test/Sema/wasm-refs-and-tables.c
index dd8536c52cd03..35a7aeea4b79e 100644
--- a/clang/test/Sema/wasm-refs-and-tables.c
+++ b/clang/test/Sema/wasm-refs-and-tables.c
@@ -63,7 +63,7 @@ __externref_t func(__externref_t ref) {
   int foo = 40;
   (__externref_t *)(&foo);     // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
   (__externref_t ****)(&foo);  // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
-  sizeof(ref);                 // expected-error {{invalid application of 
'sizeof' to sizeless type '__externref_t'}}
+  sizeof(ref);                 // expected-error {{invalid application of 
'sizeof' to sizeless type '__externref __externref_t'}}
   sizeof(__externref_t);       // expected-error {{invalid application of 
'sizeof' to sizeless type '__externref_t'}}
   sizeof(__externref_t[0]);    // expected-error {{invalid application of 
'sizeof' to WebAssembly table}}
   sizeof(table);               // expected-error {{invalid application of 
'sizeof' to WebAssembly table}}
@@ -71,7 +71,7 @@ __externref_t func(__externref_t ref) {
   sizeof(__externref_t *);     // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
   sizeof(__externref_t ***);   // expected-error {{pointer to WebAssembly 
reference type is not allowed}};
   // expected-warning@+1 {{'_Alignof' applied to an expression is a GNU 
extension}}
-  _Alignof(ref);                 // expected-error {{invalid application of 
'alignof' to sizeless type '__externref_t'}}
+  _Alignof(ref);                 // expected-error {{invalid application of 
'alignof' to sizeless type '__externref __externref_t'}}
   _Alignof(__externref_t);       // expected-error {{invalid application of 
'alignof' to sizeless type '__externref_t'}}
   _Alignof(__externref_t[]);     // expected-error {{invalid application of 
'alignof' to sizeless type '__externref_t'}}
   _Alignof(__externref_t[0]);    // expected-error {{invalid application of 
'alignof' to sizeless type '__externref_t'}}
@@ -89,13 +89,13 @@ __externref_t func(__externref_t ref) {
   // cpp-error@+1 {{no matching function for call to 'illegal_argument_1'}}
   illegal_argument_1(table);
   varargs(1, table);              // expected-error {{cannot use WebAssembly 
table as a function parameter}}
-  table == 1;                     // expected-error {{invalid operands to 
binary expression ('__attribute__((address_space(1))) __externref_t[0]' and 
'int')}}
-  1 >= table;                     // expected-error {{invalid operands to 
binary expression ('int' and '__attribute__((address_space(1))) 
__externref_t[0]')}}
-  table == other_table;           // expected-error {{invalid operands to 
binary expression ('__attribute__((address_space(1))) __externref_t[0]' and 
'__attribute__((address_space(1))) __externref_t[0]')}}
-  table !=- table;                // expected-error {{invalid argument type 
'__attribute__((address_space(1))) __externref_t *' to unary expression}}
-  !table;                         // expected-error {{invalid argument type 
'__attribute__((address_space(1))) __externref_t *' to unary expression}}
-  1 && table;                     // expected-error {{invalid operands to 
binary expression ('int' and '__attribute__((address_space(1))) 
__externref_t[0]')}}
-  table || 1;                     // expected-error {{invalid operands to 
binary expression ('__attribute__((address_space(1))) __externref_t[0]' and 
'int')}}
+  table == 1;                     // expected-error {{invalid operands to 
binary expression ('__externref __externref_t[0]' and 'int')}}
+  1 >= table;                     // expected-error {{invalid operands to 
binary expression ('int' and '__externref __externref_t[0]')}}
+  table == other_table;           // expected-error {{invalid operands to 
binary expression ('__externref __externref_t[0]' and '__externref 
__externref_t[0]')}}
+  table !=- table;                // expected-error {{invalid argument type 
'__externref __externref_t *' to unary expression}}
+  !table;                         // expected-error {{invalid argument type 
'__externref __externref_t *' to unary expression}}
+  1 && table;                     // expected-error {{invalid operands to 
binary expression ('int' and '__externref __externref_t[0]')}}
+  table || 1;                     // expected-error {{invalid operands to 
binary expression ('__externref __externref_t[0]' and 'int')}}
   1 ? table : table;              // expected-error {{cannot use a WebAssembly 
table within a branch of a conditional expression}}
   table ? : other_table;          // expected-error {{cannot use a WebAssembly 
table within a branch of a conditional expression}}
   (void *)table;                  // expected-error {{cannot cast from a 
WebAssembly table}}
diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp 
b/clang/test/SemaTemplate/address_space-dependent.cpp
index 3fdccb2c71a76..d6f25923b69b5 100644
--- a/clang/test/SemaTemplate/address_space-dependent.cpp
+++ b/clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@ void neg() {
 
 template <long int I>
 void tooBig() {
-  __attribute__((address_space(I))) int *bounds; // expected-error {{address 
space is larger than the maximum supported (8388580)}}
+  __attribute__((address_space(I))) int *bounds; // expected-error {{address 
space is larger than the maximum supported (8388579)}}
 }
 
 template <long int I>
@@ -101,7 +101,7 @@ int main() {
   car<1, 2, 3>(); // expected-note {{in instantiation of function template 
specialization 'car<1, 2, 3>' requested here}}
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template 
specialization 'neg<-1>' requested here}}
-  correct<0x7FFFE4>();
+  correct<0x7FFFE3>();
   tooBig<8388650>(); // expected-note {{in instantiation of function template 
specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;

>From fa09443d4545c01ef7578c3b989c43fd1a94ab28 Mon Sep 17 00:00:00 2001
From: Jameson Nash <[email protected]>
Date: Wed, 3 Jun 2026 17:13:57 +0000
Subject: [PATCH 3/5] review

---
 clang/lib/AST/TypePrinter.cpp          |  2 +-
 clang/lib/Basic/TargetInfo.cpp         |  2 +-
 clang/lib/Basic/Targets/AArch64.h      |  2 +-
 clang/lib/Basic/Targets/DirectX.h      |  2 +-
 clang/lib/Basic/Targets/NVPTX.h        |  2 +-
 clang/lib/Basic/Targets/SPIR.h         |  4 ++--
 clang/lib/Basic/Targets/TCE.h          |  2 +-
 clang/lib/Basic/Targets/X86.h          |  2 +-
 clang/lib/CodeGen/CGExpr.cpp           |  5 +++--
 clang/lib/CodeGen/CodeGenFunction.h    |  4 ++--
 clang/test/Sema/wasm-refs-and-tables.c | 18 +++++++++---------
 11 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 4c51754a2282f..e7e5ece85ab02 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2721,7 +2721,7 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
   case LangAS::wasm_funcref:
     return "__funcref";
   case LangAS::wasm_var:
-    return "__externref";
+    return "__wasm_var";
   default:
     return std::to_string(toTargetAddressSpace(AS));
   }
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 41ea62152aafb..a1690b15c7367 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -55,7 +55,7 @@ static const LangASMap FakeAddrSpaceMap = {
     18, // hlsl_output
     19, // hlsl_push_constant
     20, // wasm_funcref
-    21, // wasm_externref
+    21, // wasm_var
 };
 
 // TargetInfo Constructor.
diff --git a/clang/lib/Basic/Targets/AArch64.h 
b/clang/lib/Basic/Targets/AArch64.h
index 5bbda7313cc1c..6ed82e76f25cc 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -54,7 +54,7 @@ static const unsigned ARM64AddrSpaceMap[] = {
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
     0, // wasm_funcref
-    0,  // wasm_var
+    0, // wasm_var
 };
 
 using AArch64FeatureSet = llvm::SmallDenseSet<StringRef, 32>;
diff --git a/clang/lib/Basic/Targets/DirectX.h 
b/clang/lib/Basic/Targets/DirectX.h
index 7eeb169299fd3..bfac11e7da675 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -51,7 +51,7 @@ static const unsigned DirectXAddrSpaceMap[] = {
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
     0, // wasm_funcref
-    0,  // wasm_var
+    0, // wasm_var
 };
 
 class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index ecce7f05dcd6c..5e1322a1119cd 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -55,7 +55,7 @@ static const unsigned NVPTXAddrSpaceMap[] = {
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
     0, // wasm_funcref
-    0,  // wasm_var
+    0, // wasm_var
 };
 
 /// The DWARF address class. Taken from
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 798389dba4b33..28b8905e5844c 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -59,7 +59,7 @@ static const unsigned SPIRDefIsPrivMap[] = {
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
     0, // wasm_funcref
-    0,  // wasm_var
+    0, // wasm_var
 };
 
 // Used by both the SPIR and SPIR-V targets.
@@ -98,7 +98,7 @@ static const unsigned SPIRDefIsGenMap[] = {
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
     0, // wasm_funcref
-    0,  // wasm_var
+    0, // wasm_var
 };
 
 // Base class for SPIR and SPIR-V target info.
diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h
index c7d25a3d696fd..37637fa0f92e7 100644
--- a/clang/lib/Basic/Targets/TCE.h
+++ b/clang/lib/Basic/Targets/TCE.h
@@ -60,7 +60,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
     0, // wasm_funcref
-    0,  // wasm_var
+    0, // wasm_var
 };
 
 class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo {
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 4dbc631742099..f211113ab3bc8 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -55,7 +55,7 @@ static const unsigned X86AddrSpaceMap[] = {
     // Wasm address space values for this target are dummy values,
     // as it is only enabled for Wasm targets.
     0, // wasm_funcref
-    0,  // wasm_var
+    0, // wasm_var
 };
 
 // X86 target abstract base class; x86-32 and x86-64 are very close, so
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 036e897c368dc..582be4f8b991a 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -104,8 +104,9 @@ static llvm::StringRef 
GetUBSanTrapForHandler(SanitizerHandler ID) {
 
 /// CreateTempAlloca - This creates a alloca and inserts it into the entry
 /// block.
-RawAddress
-CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, LangAS 
UseAddrSpace, CharUnits Align, const Twine &Name, llvm::Value *ArraySize) {
+RawAddress CodeGenFunction::CreateTempAllocaWithoutCast(
+    llvm::Type *Ty, LangAS UseAddrSpace, CharUnits Align, const Twine &Name,
+    llvm::Value *ArraySize) {
   if (getLangOpts().EmitLogicalPointer) {
     auto Alloca = Builder.CreateStructuredAlloca(Ty, Name);
     return RawAddress(Alloca, Ty, Align, KnownNonNull);
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 86e46b84f992e..c72332abe7a50 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -5652,8 +5652,8 @@ DominatingLLVMValue::save(CodeGenFunction &CGF, 
llvm::Value *value) {
   auto align = CharUnits::fromQuantity(
                    CGF.CGM.getDataLayout().getPrefTypeAlign(value->getType()))
                    .getAsAlign();
-  llvm::AllocaInst *AI =
-      CGF.CreateTempAlloca(value->getType(), LangAS::Default, 
"cond-cleanup.save");
+  llvm::AllocaInst *AI = CGF.CreateTempAlloca(value->getType(), 
LangAS::Default,
+                                              "cond-cleanup.save");
   AI->setAlignment(align);
   CGF.Builder.CreateAlignedStore(value, AI, align);
 
diff --git a/clang/test/Sema/wasm-refs-and-tables.c 
b/clang/test/Sema/wasm-refs-and-tables.c
index 35a7aeea4b79e..f078208e35f5a 100644
--- a/clang/test/Sema/wasm-refs-and-tables.c
+++ b/clang/test/Sema/wasm-refs-and-tables.c
@@ -63,7 +63,7 @@ __externref_t func(__externref_t ref) {
   int foo = 40;
   (__externref_t *)(&foo);     // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
   (__externref_t ****)(&foo);  // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
-  sizeof(ref);                 // expected-error {{invalid application of 
'sizeof' to sizeless type '__externref __externref_t'}}
+  sizeof(ref);                 // expected-error {{invalid application of 
'sizeof' to sizeless type '__wasm_var __externref_t'}}
   sizeof(__externref_t);       // expected-error {{invalid application of 
'sizeof' to sizeless type '__externref_t'}}
   sizeof(__externref_t[0]);    // expected-error {{invalid application of 
'sizeof' to WebAssembly table}}
   sizeof(table);               // expected-error {{invalid application of 
'sizeof' to WebAssembly table}}
@@ -71,7 +71,7 @@ __externref_t func(__externref_t ref) {
   sizeof(__externref_t *);     // expected-error {{pointer to WebAssembly 
reference type is not allowed}}
   sizeof(__externref_t ***);   // expected-error {{pointer to WebAssembly 
reference type is not allowed}};
   // expected-warning@+1 {{'_Alignof' applied to an expression is a GNU 
extension}}
-  _Alignof(ref);                 // expected-error {{invalid application of 
'alignof' to sizeless type '__externref __externref_t'}}
+  _Alignof(ref);                 // expected-error {{invalid application of 
'alignof' to sizeless type '__wasm_var __externref_t'}}
   _Alignof(__externref_t);       // expected-error {{invalid application of 
'alignof' to sizeless type '__externref_t'}}
   _Alignof(__externref_t[]);     // expected-error {{invalid application of 
'alignof' to sizeless type '__externref_t'}}
   _Alignof(__externref_t[0]);    // expected-error {{invalid application of 
'alignof' to sizeless type '__externref_t'}}
@@ -89,13 +89,13 @@ __externref_t func(__externref_t ref) {
   // cpp-error@+1 {{no matching function for call to 'illegal_argument_1'}}
   illegal_argument_1(table);
   varargs(1, table);              // expected-error {{cannot use WebAssembly 
table as a function parameter}}
-  table == 1;                     // expected-error {{invalid operands to 
binary expression ('__externref __externref_t[0]' and 'int')}}
-  1 >= table;                     // expected-error {{invalid operands to 
binary expression ('int' and '__externref __externref_t[0]')}}
-  table == other_table;           // expected-error {{invalid operands to 
binary expression ('__externref __externref_t[0]' and '__externref 
__externref_t[0]')}}
-  table !=- table;                // expected-error {{invalid argument type 
'__externref __externref_t *' to unary expression}}
-  !table;                         // expected-error {{invalid argument type 
'__externref __externref_t *' to unary expression}}
-  1 && table;                     // expected-error {{invalid operands to 
binary expression ('int' and '__externref __externref_t[0]')}}
-  table || 1;                     // expected-error {{invalid operands to 
binary expression ('__externref __externref_t[0]' and 'int')}}
+  table == 1;                     // expected-error {{invalid operands to 
binary expression ('__wasm_var __externref_t[0]' and 'int')}}
+  1 >= table;                     // expected-error {{invalid operands to 
binary expression ('int' and '__wasm_var __externref_t[0]')}}
+  table == other_table;           // expected-error {{invalid operands to 
binary expression ('__wasm_var __externref_t[0]' and '__wasm_var 
__externref_t[0]')}}
+  table !=- table;                // expected-error {{invalid argument type 
'__wasm_var __externref_t *' to unary expression}}
+  !table;                         // expected-error {{invalid argument type 
'__wasm_var __externref_t *' to unary expression}}
+  1 && table;                     // expected-error {{invalid operands to 
binary expression ('int' and '__wasm_var __externref_t[0]')}}
+  table || 1;                     // expected-error {{invalid operands to 
binary expression ('__wasm_var __externref_t[0]' and 'int')}}
   1 ? table : table;              // expected-error {{cannot use a WebAssembly 
table within a branch of a conditional expression}}
   table ? : other_table;          // expected-error {{cannot use a WebAssembly 
table within a branch of a conditional expression}}
   (void *)table;                  // expected-error {{cannot cast from a 
WebAssembly table}}

>From a01b1d0cb25cfb17ae9ce60b9940d99fccf5255e Mon Sep 17 00:00:00 2001
From: Jameson Nash <[email protected]>
Date: Mon, 8 Jun 2026 15:20:05 +0000
Subject: [PATCH 4/5] HLSL: explicitly annotate constant-to-local copy as
 expecting a different address space output

---
 clang/lib/CodeGen/CGHLSLRuntime.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 33d76cbda494a..04b1d151f9d9a 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -1542,13 +1542,15 @@ RawAddress 
CGHLSLRuntime::createBufferMatrixTempAddress(const LValue &LV,
 
   QualType MatQualTy = LV.getType();
   llvm::Type *LayoutTy = 
HLSLBufferLayoutBuilder(CGF.CGM).layOutType(MatQualTy);
+  llvm::Type *DestTy = CGF.ConvertTypeForMem(MatQualTy);
   Address SrcAddr = LV.getAddress();
 
-  if (LayoutTy == CGF.ConvertTypeForMem(MatQualTy))
+  if (LayoutTy == DestTy)
     return SrcAddr;
 
-  RawAddress DestAlloca =
-      CGF.CreateMemTempWithoutCast(MatQualTy, "matrix.buf.copy");
+  RawAddress DestAlloca = CGF.CreateTempAllocaWithoutCast(
+      DestTy, LangAS::Default, CGF.getContext().getTypeAlignInChars(MatQualTy),
+      "matrix.buf.copy");
   emitBufferCopy(CGF, DestAlloca, SrcAddr, MatQualTy);
   return DestAlloca;
 }

>From bfe8d6bb12c93729cf4e6c597ee770b0e4b519ca Mon Sep 17 00:00:00 2001
From: Jameson Nash <[email protected]>
Date: Thu, 11 Jun 2026 13:13:36 +0000
Subject: [PATCH 5/5] review comments

---
 clang/lib/Sema/SemaDecl.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d354465f4185a..d8b1487ac9fbf 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8948,8 +8948,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
   // This includes arrays of objects with address space qualifiers, but not
   // automatic variables that point to other address spaces.
   // ISO/IEC TR 18037 S5.1.2
-  if (T.isWebAssemblyReferenceType() &&
-      Context.getTargetInfo().getTriple().isWasm() && !T->isArrayType()) {
+  if (T.isWebAssemblyReferenceType() && !T->isArrayType()) {
     // WebAssembly: reference types must be in
     // wasm_var address space (AS 1) so they can be stored in WebAssembly
     // locals. Arrays of reference types (WebAssembly tables) are handled

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to