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
8 #define attribute __attribute__((target("mte")))
13 // CHECK-LABEL: define{{.*}} ptr @create_tag1
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
);
21 // CHECK-LABEL: define{{.*}} ptr @create_tag2
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
);
29 // CHECK-LABEL: define{{.*}} ptr @create_tag3
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
);
38 // CHECK-LABEL: define{{.*}} ptr @increment_tag1
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);
45 // CHECK-LABEL: define{{.*}} ptr @increment_tag2
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);
52 // CHECK-LABEL: define{{.*}} i32 @exclude_tag
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
);
61 // CHECK-LABEL: define{{.*}} ptr @get_tag1
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
);
68 // CHECK-LABEL: define{{.*}} ptr @get_tag2
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
);
75 // CHECK-LABEL: define{{.*}} void @set_tag1
77 void set_tag1(int *a
) {
78 // CHECK: tail call void @llvm.aarch64.stg(ptr %a, ptr %a)
82 // CHECK-LABEL: define{{.*}} i64 @subtract_pointers
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
);
90 // CHECK-LABEL: define{{.*}} i64 @subtract_pointers_null_1
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
);
98 // CHECK-LABEL: define{{.*}} i64 @subtract_pointers_null_2
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
);
106 // Check arithmetic promotion on return type
107 // CHECK-LABEL: define{{.*}} i32 @subtract_pointers4
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;