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
5809df2b066221d869f17f4b5762405f111a65f983Tim Northovervoid test_clrex() {
5909df2b066221d869f17f4b5762405f111a65f983Tim Northover  __builtin_arm_clrex();
6009df2b066221d869f17f4b5762405f111a65f983Tim Northover  __builtin_arm_clrex(1); // expected-error {{too many arguments to function call}}
6109df2b066221d869f17f4b5762405f111a65f983Tim Northover}
62