[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / AArch64 / stack-tagging-unchecked-ld-st.ll
blob095bedf494a2d8e51c12afb8fe8e20cc90a494e0
1 ; RUN: llc < %s -mtriple=aarch64 -mattr=+mte | FileCheck %s --check-prefixes=DEFAULT,COMMON
2 ; RUN: llc < %s -mtriple=aarch64 -mattr=+mte -stack-tagging-unchecked-ld-st=never | FileCheck %s --check-prefixes=NEVER,COMMON
3 ; RUN: llc < %s -mtriple=aarch64 -mattr=+mte -stack-tagging-unchecked-ld-st=always | FileCheck %s --check-prefixes=ALWAYS,COMMON
5 declare void @use8(i8*)
6 declare void @use32(i32*)
7 declare void @use2x64([2 x i64]*)
8 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
9 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
11 define i32 @CallLd() sanitize_memtag {
12 entry:
13   %x = alloca i32, align 4
14   call void @use32(i32* %x)
15   %a = load i32, i32* %x
16   ret i32 %a
19 ; COMMON:  CallLd:
20 ; COMMON:  bl  use32
22 ; ALWAYS:  ldr w0, [sp]
23 ; DEFAULT: ldr w0, [sp]
24 ; NEVER:   ldr w0, [x{{.*}}]
26 ; COMMON:  ret
28 define void @CallStCall() sanitize_memtag {
29 entry:
30   %x = alloca i32, align 4
31   call void @use32(i32* %x)
32   store i32 42, i32* %x
33   call void @use32(i32* %x)
34   ret void
37 ; COMMON:  CallStCall:
38 ; COMMON:  bl  use32
40 ; ALWAYS:  str w{{.*}}, [sp]
41 ; DEFAULT: str w{{.*}}, [sp]
42 ; NEVER:   str w{{.*}}, [x{{.*}}]
44 ; COMMON:  bl  use32
45 ; COMMON:  ret
47 define void @CallStPair(i64 %z) sanitize_memtag {
48 entry:
49   %x = alloca [2 x i64], align 8
50   call void @use2x64([2 x i64]* %x)
51   %x0 = getelementptr inbounds [2 x i64], [2 x i64]* %x, i64 0, i64 0
52   store i64 %z, i64* %x0, align 8
53   %x1 = getelementptr inbounds [2 x i64], [2 x i64]* %x, i64 0, i64 1
54   store i64 %z, i64* %x1, align 8
55   call void @use2x64([2 x i64]* %x)
56   ret void
59 ; COMMON:  CallStPair:
60 ; COMMON:  bl  use2x64
62 ; ALWAYS:  stp {{.*}}, [sp]
63 ; DEFAULT: stp {{.*}}, [sp]
64 ; NEVER:   stp {{.*}}, [x{{.*}}]
66 ; COMMON:  bl  use2x64
67 ; COMMON:  ret
69 ; One of the two allocas will end up out of range of ldrb [sp].
70 define dso_local i8 @LargeFrame() sanitize_memtag {
71 entry:
72   %x = alloca [4096 x i8], align 4
73   %y = alloca [4096 x i8], align 4
74   %0 = getelementptr inbounds [4096 x i8], [4096 x i8]* %x, i64 0, i64 0
75   %1 = getelementptr inbounds [4096 x i8], [4096 x i8]* %y, i64 0, i64 0
76   call void @use8(i8* %0)
77   call void @use8(i8* %1)
78   %2 = load i8, i8* %0, align 4
79   %3 = load i8, i8* %1, align 4
80   %add = add i8 %3, %2
81   ret i8 %add
84 ; COMMON: LargeFrame:
85 ; COMMON: bl use8
86 ; COMMON: bl use8
88 ; NEVER:  ldrb [[A:w.*]], [x{{.*}}]
89 ; NEVER:  ldrb [[B:w.*]], [x{{.*}}]
91 ; DEFAULT:  ldrb [[A:w.*]], [x{{.*}}]
92 ; DEFAULT:  ldrb [[B:w.*]], [x{{.*}}]
94 ; ALWAYS: ldg [[PA:x.*]], [x{{.*}}]
95 ; ALWAYS: ldrb [[B:w.*]], [sp]
96 ; ALWAYS: ldrb [[A:w.*]], {{\[}}[[PA]]{{\]}}
98 ; COMMON: add w0, [[B]], [[A]]
99 ; COMMON: ret
101 ; One of these allocas is closer to FP than to SP, and within 256 bytes
102 ; of the former (see hardcoded limit in resolveFrameOffsetReference).
103 ; It could be lowered to an FP-relative load, but not when doing an
104 ; unchecked access to tagged memory!
105 define i8 @FPOffset() "frame-pointer"="all" sanitize_memtag {
106   %x = alloca [200 x i8], align 4
107   %y = alloca [200 x i8], align 4
108   %z = alloca [200 x i8], align 4
109   %x0 = getelementptr inbounds [200 x i8], [200 x i8]* %x, i64 0, i64 0
110   %y0 = getelementptr inbounds [200 x i8], [200 x i8]* %y, i64 0, i64 0
111   %z0 = getelementptr inbounds [200 x i8], [200 x i8]* %z, i64 0, i64 0
112   call void @use8(i8* %x0)
113   call void @use8(i8* %y0)
114   call void @use8(i8* %z0)
115   %x1 = load i8, i8* %x0, align 4
116   %y1 = load i8, i8* %y0, align 4
117   %z1 = load i8, i8* %z0, align 4
118   %a = add i8 %x1, %y1
119   %b = add i8 %a, %z1
120   ret i8 %b
123 ; COMMON: FPOffset:
124 ; COMMON: bl use8
125 ; COMMON: bl use8
126 ; COMMON: bl use8
128 ; All three loads are SP-based.
129 ; ALWAYS-DAG: ldrb  w{{.*}}, [sp, #416]
130 ; ALWAYS-DAG: ldrb  w{{.*}}, [sp, #208]
131 ; ALWAYS-DAG: ldrb  w{{.*}}, [sp]
133 ; DEFAULT-DAG: ldrb  w{{.*}}, [sp, #416]
134 ; DEFAULT-DAG: ldrb  w{{.*}}, [sp, #208]
135 ; DEFAULT-DAG: ldrb  w{{.*}}, [sp]
137 ; NEVER-DAG: ldrb  w{{.*}}, [x{{.*}}]
138 ; NEVER-DAG: ldrb  w{{.*}}, [x{{.*}}]
139 ; NEVER-DAG: ldrb  w{{.*}}, [x{{.*}}]
141 ; COMMON: ret