109df2b066221d869f17f4b5762405f111a65f983Tim Northover// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify %s
209df2b066221d869f17f4b5762405f111a65f983Tim Northover
309df2b066221d869f17f4b5762405f111a65f983Tim Northoverstruct Simple {
409df2b066221d869f17f4b5762405f111a65f983Tim Northover  char a, b;
509df2b066221d869f17f4b5762405f111a65f983Tim Northover};
609df2b066221d869f17f4b5762405f111a65f983Tim Northover
709df2b066221d869f17f4b5762405f111a65f983Tim Northoverint test_ldrex(char *addr) {
809df2b066221d869f17f4b5762405f111a65f983Tim Northover  int sum = 0;
909df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex(addr);
1009df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((short *)addr);
1109df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((int *)addr);
1209df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((long long *)addr);
1309df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((float *)addr);
1409df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((double *)addr);
1509df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += *__builtin_arm_ldrex((int **)addr);
1609df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((struct Simple **)addr)->a;
1709df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((volatile char *)addr);
1809df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((const volatile char *)addr);
1909df2b066221d869f17f4b5762405f111a65f983Tim Northover
2009df2b066221d869f17f4b5762405f111a65f983Tim Northover  // In principle this might be valid, but stick to ints and floats for scalar
2109df2b066221d869f17f4b5762405f111a65f983Tim Northover  // types at the moment.
2209df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((struct Simple *)addr).a; // expected-error {{address argument to atomic builtin must be a pointer to}}
2309df2b066221d869f17f4b5762405f111a65f983Tim Northover
2409df2b066221d869f17f4b5762405f111a65f983Tim Northover  sum += __builtin_arm_ldrex((__int128 *)addr); // expected-error {{__int128 is not supported on this target}} expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2,4 or 8 byte type}}
2509df2b066221d869f17f4b5762405f111a65f983Tim Northover
2609df2b066221d869f17f4b5762405f111a65f983Tim Northover  __builtin_arm_ldrex(); // expected-error {{too few arguments to function call}}
2709df2b066221d869f17f4b5762405f111a65f983Tim Northover  __builtin_arm_ldrex(1, 2); // expected-error {{too many arguments to function call}}
2809df2b066221d869f17f4b5762405f111a65f983Tim Northover  return sum;
2909df2b066221d869f17f4b5762405f111a65f983Tim Northover}
3009df2b066221d869f17f4b5762405f111a65f983Tim Northover
3109df2b066221d869f17f4b5762405f111a65f983Tim Northoverint test_strex(char *addr) {
3209df2b066221d869f17f4b5762405f111a65f983Tim Northover  int res = 0;
3309df2b066221d869f17f4b5762405f111a65f983Tim Northover  struct Simple var = {0};
3409df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(4, addr);
3509df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(42, (short *)addr);
3609df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(42, (int *)addr);
3709df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(42, (long long *)addr);
3809df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(2.71828f, (float *)addr);
3909df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(3.14159, (double *)addr);
4009df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(&var, (struct Simple **)addr);
4109df2b066221d869f17f4b5762405f111a65f983Tim Northover
4209df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(42, (volatile char *)addr);
4309df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(42, (char *const)addr);
4409df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(42, (const char *)addr); // expected-warning {{passing 'const char *' to parameter of type 'volatile char *' discards qualifiers}}
4509df2b066221d869f17f4b5762405f111a65f983Tim Northover
4609df2b066221d869f17f4b5762405f111a65f983Tim Northover
4709df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(var, (struct Simple *)addr); // expected-error {{address argument to atomic builtin must be a pointer to}}
4809df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(var, (struct Simple **)addr); // expected-error {{passing 'struct Simple' to parameter of incompatible type 'struct Simple *'}}
4909df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(&var, (struct Simple **)addr).a; // expected-error {{is not a structure or union}}
5009df2b066221d869f17f4b5762405f111a65f983Tim Northover
5109df2b066221d869f17f4b5762405f111a65f983Tim Northover  res |= __builtin_arm_strex(1, (__int128 *)addr); // expected-error {{__int128 is not supported on this target}} expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2,4 or 8 byte type}}
5209df2b066221d869f17f4b5762405f111a65f983Tim Northover
5309df2b066221d869f17f4b5762405f111a65f983Tim Northover  __builtin_arm_strex(1); // expected-error {{too few arguments to function call}}
5409df2b066221d869f17f4b5762405f111a65f983Tim Northover  __builtin_arm_strex(1, 2, 3); // expected-error {{too many arguments to function call}}
5509df2b066221d869f17f4b5762405f111a65f983Tim Northover  return res;
5609df2b066221d869f17f4b5762405f111a65f983Tim Northover}
5709df2b066221d869f17f4b5762405f111a65f983Tim Northover
58ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesint test_ldaex(char *addr) {
59ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  int sum = 0;
60ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex(addr);
61ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((short *)addr);
62ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((int *)addr);
63ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((long long *)addr);
64ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((float *)addr);
65ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((double *)addr);
66ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += *__builtin_arm_ldaex((int **)addr);
67ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((struct Simple **)addr)->a;
68ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((volatile char *)addr);
69ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((const volatile char *)addr);
70ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
71ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // In principle this might be valid, but stick to ints and floats for scalar
72ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // types at the moment.
73ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((struct Simple *)addr).a; // expected-error {{address argument to atomic builtin must be a pointer to}}
74ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
75ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  sum += __builtin_arm_ldaex((__int128 *)addr); // expected-error {{__int128 is not supported on this target}} expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2,4 or 8 byte type}}
76ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
77ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  __builtin_arm_ldaex(); // expected-error {{too few arguments to function call}}
78ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  __builtin_arm_ldaex(1, 2); // expected-error {{too many arguments to function call}}
79ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return sum;
80ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}
81ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
82ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesint test_stlex(char *addr) {
83ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  int res = 0;
84ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  struct Simple var = {0};
85ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(4, addr);
86ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(42, (short *)addr);
87ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(42, (int *)addr);
88ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(42, (long long *)addr);
89ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(2.71828f, (float *)addr);
90ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(3.14159, (double *)addr);
91ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(&var, (struct Simple **)addr);
92ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
93ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(42, (volatile char *)addr);
94ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(42, (char *const)addr);
95ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(42, (const char *)addr); // expected-warning {{passing 'const char *' to parameter of type 'volatile char *' discards qualifiers}}
96ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
97ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
98ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(var, (struct Simple *)addr); // expected-error {{address argument to atomic builtin must be a pointer to}}
99ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(var, (struct Simple **)addr); // expected-error {{passing 'struct Simple' to parameter of incompatible type 'struct Simple *'}}
100ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(&var, (struct Simple **)addr).a; // expected-error {{is not a structure or union}}
101ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
102ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  res |= __builtin_arm_stlex(1, (__int128 *)addr); // expected-error {{__int128 is not supported on this target}} expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2,4 or 8 byte type}}
103ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
104ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  __builtin_arm_stlex(1); // expected-error {{too few arguments to function call}}
105ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  __builtin_arm_stlex(1, 2, 3); // expected-error {{too many arguments to function call}}
106ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return res;
107ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}
108ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
10909df2b066221d869f17f4b5762405f111a65f983Tim Northovervoid test_clrex() {
11009df2b066221d869f17f4b5762405f111a65f983Tim Northover  __builtin_arm_clrex();
11109df2b066221d869f17f4b5762405f111a65f983Tim Northover  __builtin_arm_clrex(1); // expected-error {{too many arguments to function call}}
11209df2b066221d869f17f4b5762405f111a65f983Tim Northover}
113