Skip to content

Commit 231338d

Browse files
authored
[SYCL][FPGA] Update __builtin_intel_fpga_mem (#6357)
This is a continuation of @Fznamznon's PR #5002. Most of the changes here are from there. According to #4980 this built-in should take four more constant integer parameters with following default values: const int32_t AnchorID = -1 const int32_t TargetAnchor = 0 const int32_t Type = 0 const int32_t Cycle = 0 The old variant is still allowed for backward compatibility. In case some parameters are not provided - default value will be emitted in annotation string. In addition to the state of PR #5002, this PR makes minor changes. It incorporates @mlychkov's code review comments there and modifies the CodeGenSYCL test to accept both opaque and non-opaque pointers.
1 parent a678bff commit 231338d

File tree

5 files changed

+214
-16
lines changed

5 files changed

+214
-16
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21044,22 +21044,36 @@ RValue CodeGenFunction::EmitIntelFPGAMemBuiltin(const CallExpr *E) {
2104421044
// Arguments
2104521045
const Expr *PtrArg = E->getArg(0);
2104621046
Value *PtrVal = EmitScalarExpr(PtrArg);
21047+
ASTContext &Ctx = getContext();
2104721048

2104821049
// Create the pointer annotation
2104921050
Function *F =
2105021051
CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation, PtrVal->getType());
2105121052
SmallString<256> AnnotStr;
2105221053
llvm::raw_svector_ostream Out(AnnotStr);
2105321054

21054-
Optional<llvm::APSInt> Params =
21055-
E->getArg(1)->getIntegerConstantExpr(getContext());
21056-
assert(Params.hasValue() && "Constant arg isn't actually constant?");
21057-
Out << "{params:" << toString(*Params, 10) << "}";
21055+
auto AddArgValue = [&E, &Ctx, &Out](unsigned NumOfArg, StringRef StringToAdd,
21056+
int DefaultValue = INT_MIN) {
21057+
Optional<llvm::APSInt> IntVal =
21058+
(E->getNumArgs() > NumOfArg)
21059+
? E->getArg(NumOfArg)->getIntegerConstantExpr(Ctx)
21060+
: APSInt::get(DefaultValue);
21061+
assert(IntVal.hasValue() && "Constant arg isn't actually constant?");
21062+
Out << "{" << StringToAdd << ":" << toString(*IntVal, 10) << "}";
21063+
};
2105821064

21059-
Optional<llvm::APSInt> CacheSize =
21060-
E->getArg(2)->getIntegerConstantExpr(getContext());
21061-
assert(CacheSize.hasValue() && "Constant arg isn't actually constant?");
21062-
Out << "{cache-size:" << toString(*CacheSize, 10) << "}";
21065+
AddArgValue(1, "params");
21066+
AddArgValue(2, "cache-size");
21067+
// There are four optional arguments with the following default values:
21068+
// const int32_t AnchorID = -1
21069+
// const int32_t TargetAnchor = 0
21070+
// const int32_t Type = 0
21071+
// const int32_t Cycle = 0
21072+
// Emit default values or use provided.
21073+
AddArgValue(3, "anchor-id", -1);
21074+
AddArgValue(4, "target-anchor", 0);
21075+
AddArgValue(5, "type", 0);
21076+
AddArgValue(6, "cycle", 0);
2106321077

2106421078
llvm::Value *Ann = EmitAnnotationCall(F, PtrVal, AnnotStr, SourceLocation());
2106521079

clang/lib/Sema/SemaChecking.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5485,9 +5485,23 @@ bool Sema::CheckIntelFPGARegBuiltinFunctionCall(unsigned BuiltinID,
54855485
}
54865486

54875487
bool Sema::CheckIntelFPGAMemBuiltinFunctionCall(CallExpr *TheCall) {
5488-
// Make sure we have exactly 3 arguments
5489-
if (checkArgCount(*this, TheCall, 3))
5490-
return true;
5488+
const unsigned MinNumArgs = 3;
5489+
const unsigned MaxNumArgs = 7;
5490+
unsigned NumArgs = TheCall->getNumArgs();
5491+
5492+
// Make sure we have the minimum number of provided arguments.
5493+
if (NumArgs < MinNumArgs)
5494+
return Diag(TheCall->getEndLoc(),
5495+
diag::err_typecheck_call_too_few_args_at_least)
5496+
<< 0 /* function call */ << MinNumArgs << NumArgs
5497+
<< TheCall->getSourceRange();
5498+
5499+
// Make sure we don't have too many arguments.
5500+
if (NumArgs > MaxNumArgs)
5501+
return Diag(TheCall->getEndLoc(),
5502+
diag::err_typecheck_call_too_many_args_at_most)
5503+
<< 0 /*function call*/ << MaxNumArgs << NumArgs
5504+
<< TheCall->getSourceRange();
54915505

54925506
Expr *PointerArg = TheCall->getArg(0);
54935507
QualType PointerArgType = PointerArg->getType();
@@ -5523,6 +5537,12 @@ bool Sema::CheckIntelFPGAMemBuiltinFunctionCall(CallExpr *TheCall) {
55235537
return Diag(TheCall->getArg(2)->getBeginLoc(),
55245538
diag::err_intel_fpga_mem_arg_mismatch) << 1;
55255539

5540+
// The last four optional arguments must be signed constant integers.
5541+
for (unsigned I = MinNumArgs; I != NumArgs; ++I) {
5542+
if (SemaBuiltinConstantArg(TheCall, I, Result))
5543+
return true;
5544+
}
5545+
55265546
// Set the return type to be the same as the type of the first argument
55275547
// (pointer argument)
55285548
TheCall->setType(PointerArgType);

clang/test/CodeGenSYCL/intel-fpga-mem-builtin.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,21 @@
33
#define PARAM_1 1U << 7
44
#define PARAM_2 1U << 8
55

6+
// This test checks that using of __builtin_intel_fpga_mem results in correct
7+
// generation of annotations in LLVM IR.
8+
69
// CHECK: [[STRUCT:%.*]] = type { i32, float }
710
struct State {
811
int x;
912
float y;
1013
};
1114

12-
// CHECK: [[ANN1:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:0}
13-
// CHECK: [[ANN2:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:127}
15+
// CHECK: [[ANN1:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:0}{anchor-id:-1}{target-anchor:0}{type:0}{cycle:0}
16+
// CHECK: [[ANN2:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:127}{anchor-id:-1}{target-anchor:0}{type:0}{cycle:0}
17+
// CHECK: [[ANN3:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:127}{anchor-id:10}{target-anchor:20}{type:30}{cycle:40}
18+
// CHECK: [[ANN4:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:127}{anchor-id:11}{target-anchor:12}{type:0}{cycle:0}
19+
// CHECK: [[ANN5:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:127}{anchor-id:100}{target-anchor:0}{type:0}{cycle:0}
20+
// CHECK: [[ANN6:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:128}{anchor-id:4}{target-anchor:7}{type:8}{cycle:0}
1421

1522
// CHECK: define {{.*}}spir_func void @{{.*}}(ptr addrspace(4) noundef %A, ptr addrspace(4) noundef %B, ptr addrspace(4) noundef %C, ptr addrspace(4){{.*}}%D)
1623
void foo(float *A, int *B, State *C, State &D) {
@@ -65,6 +72,29 @@ void foo(float *A, int *B, State *C, State &D) {
6572
// CHECK-DAG: [[PTR8:%[0-9]+]] = call ptr addrspace(4) @llvm.ptr.annotation{{.*}}[[F]]{{.*}}[[ANN2]]{{.*}}[[ATT:#[0-9]+]]
6673
// CHECK-DAG: store ptr addrspace(4) [[PTR8]], ptr addrspace(4) %f
6774
f = __builtin_intel_fpga_mem(&F, PARAM_1 | PARAM_2, 127);
75+
76+
// CHECK-DAG: [[A3:%[0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[Aaddr]]
77+
// CHECK-DAG: [[PTR9:%[0-9]+]] = call ptr addrspace(4) @llvm.ptr.annotation{{.*}}[[A3]]{{.*}}[[ANN3]]{{.*}}[[ATT:#[0-9]+]]
78+
// CHECK-DAG: store ptr addrspace(4) [[PTR9]], ptr addrspace(4) %x
79+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 127, 10, 20, 30, 40);
80+
81+
// CHECK-DAG: [[A4:%[0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[Aaddr]]
82+
// CHECK-DAG: [[PTR10:%[0-9]+]] = call ptr addrspace(4) @llvm.ptr.annotation{{.*}}[[A4]]{{.*}}[[ANN4]]{{.*}}[[ATT:#[0-9]+]]
83+
// CHECK-DAG: store ptr addrspace(4) [[PTR10]], ptr addrspace(4) %x
84+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 127, 11, 12);
85+
86+
// CHECK-DAG: [[B3:%[0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[Baddr]]
87+
// CHECK-DAG: [[PTR11:%[0-9]+]] = call ptr addrspace(4) @llvm.ptr.annotation{{.*}}[[B3]]{{.*}}[[ANN5]]{{.*}}[[ATT:#[0-9]+]]
88+
// CHECK-DAG: store ptr addrspace(4) [[PTR11]], ptr addrspace(4) %y
89+
y = __builtin_intel_fpga_mem(B, PARAM_1 | PARAM_2, 127, 100);
90+
91+
constexpr int TestVal1 = 7;
92+
constexpr int TestVal2 = 8;
93+
94+
// CHECK-DAG: [[D1:%[0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[Daddr]]
95+
// CHECK-DAG: [[PTR12:%[0-9]+]] = call ptr addrspace(4) @llvm.ptr.annotation{{.*}}[[D1]]{{.*}}[[ANN6]]{{.*}}[[ATT:#[0-9]+]]
96+
// CHECK-DAG: store ptr addrspace(4) [[PTR12]], ptr addrspace(4) %z
97+
z = __builtin_intel_fpga_mem(&D, PARAM_1 | PARAM_2, 128, 4, TestVal1, TestVal2);
6898
}
6999

70100
// CHECK-DAG: attributes [[ATT]] = { readnone }
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-linux -std=c++11 -disable-llvm-passes -S -no-opaque-pointers -emit-llvm -x c++ %s -o - | FileCheck %s
2+
3+
#define PARAM_1 1U << 7
4+
#define PARAM_2 1U << 8
5+
6+
// This test checks that using of __builtin_intel_fpga_mem results in correct
7+
// generation of annotations in LLVM IR.
8+
9+
// CHECK: [[STRUCT:%.*]] = type { i32, float }
10+
struct State {
11+
int x;
12+
float y;
13+
};
14+
15+
// CHECK: [[ANN1:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:0}{anchor-id:-1}{target-anchor:0}{type:0}{cycle:0}
16+
// CHECK: [[ANN2:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:127}{anchor-id:-1}{target-anchor:0}{type:0}{cycle:0}
17+
// CHECK: [[ANN3:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:127}{anchor-id:10}{target-anchor:20}{type:30}{cycle:40}
18+
// CHECK: [[ANN4:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:127}{anchor-id:11}{target-anchor:12}{type:0}{cycle:0}
19+
// CHECK: [[ANN5:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:127}{anchor-id:100}{target-anchor:0}{type:0}{cycle:0}
20+
// CHECK: [[ANN6:@.str[\.]*[0-9]*]] = {{.*}}{params:384}{cache-size:128}{anchor-id:4}{target-anchor:7}{type:8}{cycle:0}
21+
22+
// CHECK: define {{.*}}spir_func void @{{.*}}(float addrspace(4)* noundef %A, i32 addrspace(4)* noundef %B, [[STRUCT]] addrspace(4)* noundef %C, [[STRUCT]] addrspace(4)*{{.*}}%D)
23+
void foo(float *A, int *B, State *C, State &D) {
24+
float *x;
25+
int *y;
26+
State *z;
27+
double F = 0.0;
28+
double *f;
29+
30+
// CHECK-DAG: [[Aaddr:%.*]] = alloca float addrspace(4)*
31+
// CHECK-DAG: [[Baddr:%.*]] = alloca i32 addrspace(4)*
32+
// CHECK-DAG: [[Caddr:%.*]] = alloca [[STRUCT]] addrspace(4)*
33+
// CHECK-DAG: [[Daddr:%.*]] = alloca [[STRUCT]] addrspace(4)*
34+
// CHECK-DAG: [[F:%.*]] = alloca double
35+
// CHECK-DAG: [[f:%.*]] = alloca double addrspace(4)*
36+
37+
// CHECK-DAG: [[A:%[0-9]+]] = load float addrspace(4)*, float addrspace(4)* addrspace(4)* [[Aaddr]]
38+
// CHECK-DAG: [[PTR1:%[0-9]+]] = call float addrspace(4)* @llvm.ptr.annotation{{.*}}[[A]]{{.*}}[[ANN1]]{{.*}}[[ATT:#[0-9]+]]
39+
// CHECK-DAG: store float addrspace(4)* [[PTR1]], float addrspace(4)* addrspace(4)* %x
40+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 0);
41+
42+
// CHECK-DAG: [[B:%[0-9]+]] = load i32 addrspace(4)*, i32 addrspace(4)* addrspace(4)* [[Baddr]]
43+
// CHECK-DAG: [[PTR2:%[0-9]+]] = call i32 addrspace(4)* @llvm.ptr.annotation{{.*}}[[B]]{{.*}}[[ANN1]]{{.*}}[[ATT:#[0-9]+]]
44+
// CHECK-DAG: store i32 addrspace(4)* [[PTR2]], i32 addrspace(4)* addrspace(4)* %y
45+
y = __builtin_intel_fpga_mem(B, PARAM_1 | PARAM_2, 0);
46+
47+
// CHECK-DAG: [[C:%[0-9]+]] = load [[STRUCT]] addrspace(4)*, [[STRUCT]] addrspace(4)* addrspace(4)* [[Caddr]]
48+
// CHECK-DAG: [[PTR3:%[0-9]+]] = call [[STRUCT]] addrspace(4)* @llvm.ptr.annotation{{.*}}[[C]]{{.*}}[[ANN1]]{{.*}}[[ATT:#[0-9]+]]
49+
// CHECK-DAG: store [[STRUCT]] addrspace(4)* [[PTR3]], [[STRUCT]] addrspace(4)* addrspace(4)* %z
50+
z = __builtin_intel_fpga_mem(C, PARAM_1 | PARAM_2, 0);
51+
52+
// CHECK-DAG: [[A2:%[0-9]+]] = load float addrspace(4)*, float addrspace(4)* addrspace(4)* [[Aaddr]]
53+
// CHECK-DAG: [[PTR4:%[0-9]+]] = call float addrspace(4)* @llvm.ptr.annotation{{.*}}[[A2]]{{.*}}[[ANN2]]{{.*}}[[ATT:#[0-9]+]]
54+
// CHECK-DAG: store float addrspace(4)* [[PTR4]], float addrspace(4)* addrspace(4)* %x
55+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 127);
56+
57+
// CHECK-DAG: [[B2:%[0-9]+]] = load i32 addrspace(4)*, i32 addrspace(4)* addrspace(4)* [[Baddr]]
58+
// CHECK-DAG: [[PTR5:%[0-9]+]] = call i32 addrspace(4)* @llvm.ptr.annotation{{.*}}[[B2]]{{.*}}[[ANN2]]{{.*}}[[ATT:#[0-9]+]]
59+
// CHECK-DAG: store i32 addrspace(4)* [[PTR5]], i32 addrspace(4)* addrspace(4)* %y
60+
y = __builtin_intel_fpga_mem(B, PARAM_1 | PARAM_2, 127);
61+
62+
// CHECK-DAG: [[C2:%[0-9]+]] = load [[STRUCT]] addrspace(4)*, [[STRUCT]] addrspace(4)* addrspace(4)* [[Caddr]]
63+
// CHECK-DAG: [[PTR6:%[0-9]+]] = call [[STRUCT]] addrspace(4)* @llvm.ptr.annotation{{.*}}[[C2]]{{.*}}[[ANN2]]{{.*}}[[ATT:#[0-9]+]]
64+
// CHECK-DAG: store [[STRUCT]] addrspace(4)* [[PTR6]], [[STRUCT]] addrspace(4)* addrspace(4)* %z
65+
z = __builtin_intel_fpga_mem(C, PARAM_1 | PARAM_2, 127);
66+
67+
// CHECK-DAG: [[D:%[0-9]+]] = load [[STRUCT]] addrspace(4)*, [[STRUCT]] addrspace(4)* addrspace(4)* [[Daddr]]
68+
// CHECK-DAG: [[PTR7:%[0-9]+]] = call [[STRUCT]] addrspace(4)* @llvm.ptr.annotation{{.*}}[[D]]{{.*}}[[ANN2]]{{.*}}[[ATT:#[0-9]+]]
69+
// CHECK-DAG: store [[STRUCT]] addrspace(4)* [[PTR7]], [[STRUCT]] addrspace(4)* addrspace(4)* %z
70+
z = __builtin_intel_fpga_mem(&D, PARAM_1 | PARAM_2, 127);
71+
72+
// CHECK-DAG: [[PTR8:%[0-9]+]] = call double addrspace(4)* @llvm.ptr.annotation{{.*}}[[F]]{{.*}}[[ANN2]]{{.*}}[[ATT:#[0-9]+]]
73+
// CHECK-DAG: store double addrspace(4)* [[PTR8]], double addrspace(4)* addrspace(4)* %f
74+
f = __builtin_intel_fpga_mem(&F, PARAM_1 | PARAM_2, 127);
75+
76+
// CHECK-DAG: [[A3:%[0-9]+]] = load float addrspace(4)*, float addrspace(4)* addrspace(4)* [[Aaddr]]
77+
// CHECK-DAG: [[PTR9:%[0-9]+]] = call float addrspace(4)* @llvm.ptr.annotation{{.*}}[[A3]]{{.*}}[[ANN3]]{{.*}}[[ATT:#[0-9]+]]
78+
// CHECK-DAG: store float addrspace(4)* [[PTR9]], float addrspace(4)* addrspace(4)* %x
79+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 127, 10, 20, 30, 40);
80+
81+
// CHECK-DAG: [[A4:%[0-9]+]] = load float addrspace(4)*, float addrspace(4)* addrspace(4)* [[Aaddr]]
82+
// CHECK-DAG: [[PTR10:%[0-9]+]] = call float addrspace(4)* @llvm.ptr.annotation{{.*}}[[A4]]{{.*}}[[ANN4]]{{.*}}[[ATT:#[0-9]+]]
83+
// CHECK-DAG: store float addrspace(4)* [[PTR10]], float addrspace(4)* addrspace(4)* %x
84+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 127, 11, 12);
85+
86+
// CHECK-DAG: [[B3:%[0-9]+]] = load i32 addrspace(4)*, i32 addrspace(4)* addrspace(4)* [[Baddr]]
87+
// CHECK-DAG: [[PTR11:%[0-9]+]] = call i32 addrspace(4)* @llvm.ptr.annotation{{.*}}[[B3]]{{.*}}[[ANN5]]{{.*}}[[ATT:#[0-9]+]]
88+
// CHECK-DAG: store i32 addrspace(4)* [[PTR11]], i32 addrspace(4)* addrspace(4)* %y
89+
y = __builtin_intel_fpga_mem(B, PARAM_1 | PARAM_2, 127, 100);
90+
91+
constexpr int TestVal1 = 7;
92+
constexpr int TestVal2 = 8;
93+
94+
// CHECK-DAG: [[D1:%[0-9]+]] = load [[STRUCT]] addrspace(4)*, [[STRUCT]] addrspace(4)* addrspace(4)* [[Daddr]]
95+
// CHECK-DAG: [[PTR12:%[0-9]+]] = call [[STRUCT]] addrspace(4)* @llvm.ptr.annotation{{.*}}[[D1]]{{.*}}[[ANN6]]{{.*}}[[ATT:#[0-9]+]]
96+
// CHECK-DAG: store [[STRUCT]] addrspace(4)* [[PTR12]], [[STRUCT]] addrspace(4)* addrspace(4)* %z
97+
z = __builtin_intel_fpga_mem(&D, PARAM_1 | PARAM_2, 128, 4, TestVal1, TestVal2);
98+
}
99+
100+
// CHECK-DAG: attributes [[ATT]] = { readnone }
101+
102+
template <typename name, typename Func>
103+
__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
104+
kernelFunc();
105+
}
106+
107+
int main() {
108+
kernel_single_task<class fake_kernel>([]() {
109+
float *A;
110+
int *B;
111+
State *C;
112+
State D;
113+
foo(A, B, C, D); });
114+
return 0;
115+
}

clang/test/SemaSYCL/intel-fpga-mem-builtin.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#define PARAM_1 1U << 7
55
#define PARAM_2 1U << 8
66

7+
// This test makes sure that the compiler checks the semantics of
8+
// __builtin_intel_fpga_mem built-in function arguments correctly.
9+
710
#ifdef __SYCL_DEVICE_ONLY__
811
static_assert(__has_builtin(__builtin_intel_fpga_mem), "");
912
struct State {
@@ -29,9 +32,7 @@ void foo(float *A, int *B, State *C) {
2932
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, -1);
3033
// expected-error@-1{{builtin parameter must be a non-negative integer constant}}
3134
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2);
32-
// expected-error@-1{{too few arguments to function call, expected 3, have 2}}
33-
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, 1);
34-
// expected-error@-1{{too many arguments to function call, expected 3, have 4}}
35+
// expected-error@-1{{too few arguments to function call, expected at least 3, have 2}}
3536
y = __builtin_intel_fpga_mem(B, 0, i);
3637
// expected-error@-1{{argument to '__builtin_intel_fpga_mem' must be a constant integer}}
3738
z = __builtin_intel_fpga_mem(C, i, 0);
@@ -53,6 +54,24 @@ void foo(float *A, int *B, State *C) {
5354
struct outer *iii;
5455
struct outer *iv = __builtin_intel_fpga_mem(iii, 0, 0);
5556
// expected-error@-1{{illegal field in type pointed to by pointer argument to __builtin_intel_fpga_mem; only pointers to a first class lvalue or to an rvalue are allowed}}
57+
58+
// Up to 7 parameters is ok.
59+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, 1);
60+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, 1, 10);
61+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, 1, 10, 20);
62+
x = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, 1, -1, 10, 20);
63+
64+
z = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, B, -1, 1, 1);
65+
// expected-error@-1{{argument to '__builtin_intel_fpga_mem' must be a constant integer}}
66+
z = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, 1, U, 10, 20);
67+
// expected-error@-1{{argument to '__builtin_intel_fpga_mem' must be a constant integer}}
68+
z = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, 1, -1, C, 300);
69+
// expected-error@-1{{argument to '__builtin_intel_fpga_mem' must be a constant integer}}
70+
z = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, 1, -1, 1, i);
71+
// expected-error@-1{{argument to '__builtin_intel_fpga_mem' must be a constant integer}}
72+
73+
y = __builtin_intel_fpga_mem(A, PARAM_1 | PARAM_2, 1, 1, -1, 10, 20, 30);
74+
// expected-error@-1{{too many arguments to function call, expected at most 7, have 8}}
5675
}
5776

5877
template <typename name, typename Func>

0 commit comments

Comments
 (0)