xref: /llvm-project/clang/test/CodeGen/arm64-mte.c (revision c5de4dd1eab00df76c1a68c5f397304ceacb71f2)
1 // Test memory tagging extension intrinsics
2 // RUN: %clang_cc1 -triple aarch64 -target-feature +mte -O3 -emit-llvm -o - %s  | FileCheck %s
3 // RUN: %clang_cc1 -triple aarch64 -DMTE -O3 -emit-llvm -o - %s  | FileCheck %s
4 #include <stddef.h>
5 #include <arm_acle.h>
6 
7 #ifdef MTE
8 #define attribute  __attribute__((target("mte")))
9 #else
10 #define attribute
11 #endif
12 
13 // CHECK-LABEL: define{{.*}} ptr @create_tag1
14 attribute
create_tag1(int * a,unsigned b)15 int *create_tag1(int *a, unsigned b) {
16 // CHECK: [[T1:%[0-9]+]] = zext i32 %b to i64
17 // CHECK: [[T2:%[0-9]+]] = tail call ptr @llvm.aarch64.irg(ptr %a, i64 [[T1]])
18         return __arm_mte_create_random_tag(a,b);
19 }
20 
21 // CHECK-LABEL: define{{.*}} ptr @create_tag2
22 attribute
create_tag2(short * a,unsigned b)23 short *create_tag2(short *a, unsigned b) {
24 // CHECK: [[T1:%[0-9]+]] = zext i32 %b to i64
25 // CHECK: [[T2:%[0-9]+]] = tail call ptr @llvm.aarch64.irg(ptr %a, i64 [[T1]])
26         return __arm_mte_create_random_tag(a,b);
27 }
28 
29 // CHECK-LABEL: define{{.*}} ptr @create_tag3
30 attribute
create_tag3(char * a,unsigned b)31 char *create_tag3(char *a, unsigned b) {
32 // CHECK: [[T1:%[0-9]+]] = zext i32 %b to i64
33 // CHECK: [[T2:%[0-9]+]] = tail call ptr @llvm.aarch64.irg(ptr %a, i64 [[T1]])
34 // CHECK: ret ptr [[T2:%[0-9]+]]
35         return __arm_mte_create_random_tag(a,b);
36 }
37 
38 // CHECK-LABEL: define{{.*}} ptr @increment_tag1
39 attribute
increment_tag1(char * a)40 char *increment_tag1(char *a) {
41 // CHECK: call ptr @llvm.aarch64.addg(ptr %a, i64 3)
42         return __arm_mte_increment_tag(a,3);
43 }
44 
45 // CHECK-LABEL: define{{.*}} ptr @increment_tag2
46 attribute
increment_tag2(short * a)47 short *increment_tag2(short *a) {
48 // CHECK: [[T1:%[0-9]+]] = tail call ptr @llvm.aarch64.addg(ptr %a, i64 3)
49         return __arm_mte_increment_tag(a,3);
50 }
51 
52 // CHECK-LABEL: define{{.*}} i32 @exclude_tag
53 attribute
exclude_tag(int * a,unsigned m)54 unsigned exclude_tag(int *a, unsigned m) {
55 // CHECK: [[T0:%[0-9]+]] = zext i32 %m to i64
56 // CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.gmi(ptr %a, i64 [[T0]])
57 // CHECK: trunc i64 [[T2]] to i32
58   return __arm_mte_exclude_tag(a, m);
59 }
60 
61 // CHECK-LABEL: define{{.*}} ptr @get_tag1
62 attribute
get_tag1(int * a)63 int *get_tag1(int *a) {
64 // CHECK: [[T1:%[0-9]+]] = tail call ptr @llvm.aarch64.ldg(ptr %a, ptr %a)
65    return __arm_mte_get_tag(a);
66 }
67 
68 // CHECK-LABEL: define{{.*}} ptr @get_tag2
69 attribute
get_tag2(short * a)70 short *get_tag2(short *a) {
71 // CHECK: [[T1:%[0-9]+]] = tail call ptr @llvm.aarch64.ldg(ptr %a, ptr %a)
72    return __arm_mte_get_tag(a);
73 }
74 
75 // CHECK-LABEL: define{{.*}} void @set_tag1
76 attribute
set_tag1(int * a)77 void set_tag1(int *a) {
78 // CHECK: tail call void @llvm.aarch64.stg(ptr %a, ptr %a)
79    __arm_mte_set_tag(a);
80 }
81 
82 // CHECK-LABEL: define{{.*}} i64 @subtract_pointers
83 attribute
subtract_pointers(int * a,int * b)84 ptrdiff_t subtract_pointers(int *a, int *b) {
85 // CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.subp(ptr %a, ptr %b)
86 // CHECK: ret i64 [[T2]]
87    return __arm_mte_ptrdiff(a, b);
88 }
89 
90 // CHECK-LABEL: define{{.*}} i64 @subtract_pointers_null_1
91 attribute
subtract_pointers_null_1(int * a)92 ptrdiff_t subtract_pointers_null_1(int *a) {
93 // CHECK: [[T1:%[0-9]+]] = tail call i64 @llvm.aarch64.subp(ptr %a, ptr null)
94 // CHECK: ret i64 [[T1]]
95    return __arm_mte_ptrdiff(a, NULL);
96 }
97 
98 // CHECK-LABEL: define{{.*}} i64 @subtract_pointers_null_2
99 attribute
subtract_pointers_null_2(int * a)100 ptrdiff_t subtract_pointers_null_2(int *a) {
101 // CHECK: [[T1:%[0-9]+]] = tail call i64 @llvm.aarch64.subp(ptr null, ptr %a)
102 // CHECK: ret i64 [[T1]]
103    return __arm_mte_ptrdiff(NULL, a);
104 }
105 
106 // Check arithmetic promotion on return type
107 // CHECK-LABEL: define{{.*}} i32 @subtract_pointers4
108 attribute
subtract_pointers4(void * a,void * b)109 int subtract_pointers4(void* a, void *b) {
110 // CHECK: [[T0:%[0-9]+]] = tail call i64 @llvm.aarch64.subp(ptr %a, ptr %b)
111 // CHECK-NEXT: %cmp = icmp slt i64 [[T0]], 1
112 // CHECK-NEXT:  = zext i1 %cmp to i32
113   return __arm_mte_ptrdiff(a,b) <= 0;
114 }
115