Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions clang/lib/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H

#include "Targets.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/Support/Compiler.h"
Expand Down Expand Up @@ -317,6 +318,16 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {
return Feature == "spirv";
}

virtual bool isAddressSpaceSupersetOf(LangAS A, LangAS B) const override {
// The generic space AS(4) is a superset of all the other address
// spaces used by the backend target.
return A == B || ((A == LangAS::Default ||
(isTargetAddressSpace(A) &&
toTargetAddressSpace(A) == /*Generic=*/4)) &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use enum?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SPIR-V doesn't have any enums for this, their backend just hard-codes is everywhere AFAICT so fixing that is a little out of scope.

isTargetAddressSpace(B) &&
toTargetAddressSpace(B) <= /*Generic=*/4);
}

void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
Expand Down
21 changes: 21 additions & 0 deletions clang/test/Sema/spirv-address-space.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %clang_cc1 %s -triple spirv64 -fsyntax-only -verify

#define _AS0 __attribute__((address_space(0)))
#define _AS1 __attribute__((address_space(1)))
#define _AS2 __attribute__((address_space(2)))
#define _AS3 __attribute__((address_space(3)))
#define _AS4 __attribute__((address_space(4)))
#define _AS5 __attribute__((address_space(5)))
#define _AS999 __attribute__((address_space(999)))

void *p1(void _AS1 *p) { return p; }
void *p2(void _AS2 *p) { return p; }
void *p3(void _AS3 *p) { return p; }
void *p4(void _AS4 *p) { return p; }
void *p5(void _AS5 *p) { return p; } // expected-error {{returning '_AS5 void *' from a function with result type 'void *' changes address space of pointer}}
void *pi(void _AS999 *p) { return p; } // expected-error {{returning '_AS999 void *' from a function with result type 'void *' changes address space of pointer}}
void *pc(void __attribute__((opencl_local)) *p) { return p; } // expected-error {{returning '__local void *' from a function with result type 'void *' changes address space of pointer}}
void _AS1 *r0(void _AS1 *p) { return p; }
void _AS1 *r1(void *p) { return p; } // expected-error {{returning 'void *' from a function with result type '_AS1 void *' changes address space of pointer}}
void _AS1 *r2(void *p) { return (void _AS1 *)p; }