1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; Test basic type sanitizer instrumentation.
4 ; RUN: opt -passes='tysan' -S %s | FileCheck %s
6 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8 define i32 @test_load_unk(ptr %a) sanitize_type {
9 ; CHECK-LABEL: @test_load_unk(
11 ; CHECK-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8
12 ; CHECK-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8
13 ; CHECK-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A:%.*]] to i64
14 ; CHECK-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]]
15 ; CHECK-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3
16 ; CHECK-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]]
17 ; CHECK-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr
18 ; CHECK-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8
19 ; CHECK-NEXT: [[BAD_DESC:%.*]] = icmp ne ptr [[SHADOW_DESC]], null
20 ; CHECK-NEXT: br i1 [[BAD_DESC]], label [[TMP0:%.*]], label [[TMP22:%.*]], !prof [[PROF0:![0-9]+]]
22 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[SHADOW_DESC]], null
23 ; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP20:%.*]]
25 ; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[SHADOW_PTR_INT]], 8
26 ; CHECK-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr
27 ; CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
28 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ne ptr [[TMP5]], null
29 ; CHECK-NEXT: [[TMP7:%.*]] = or i1 false, [[TMP6]]
30 ; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[SHADOW_PTR_INT]], 16
31 ; CHECK-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr
32 ; CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8
33 ; CHECK-NEXT: [[TMP11:%.*]] = icmp ne ptr [[TMP10]], null
34 ; CHECK-NEXT: [[TMP12:%.*]] = or i1 [[TMP7]], [[TMP11]]
35 ; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[SHADOW_PTR_INT]], 24
36 ; CHECK-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr
37 ; CHECK-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP14]], align 8
38 ; CHECK-NEXT: [[TMP16:%.*]] = icmp ne ptr [[TMP15]], null
39 ; CHECK-NEXT: [[TMP17:%.*]] = or i1 [[TMP12]], [[TMP16]]
40 ; CHECK-NEXT: br i1 [[TMP17]], label [[TMP18:%.*]], label [[TMP19:%.*]], !prof [[PROF0]]
42 ; CHECK-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 1)
43 ; CHECK-NEXT: br label [[TMP19]]
45 ; CHECK-NEXT: store ptr null, ptr [[SHADOW_PTR]], align 8
46 ; CHECK-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8
47 ; CHECK-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr
48 ; CHECK-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8
49 ; CHECK-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16
50 ; CHECK-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr
51 ; CHECK-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8
52 ; CHECK-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24
53 ; CHECK-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr
54 ; CHECK-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8
55 ; CHECK-NEXT: br label [[TMP21:%.*]]
57 ; CHECK-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 1)
58 ; CHECK-NEXT: br label [[TMP21]]
60 ; CHECK-NEXT: br label [[TMP43:%.*]]
62 ; CHECK-NEXT: [[TMP23:%.*]] = add i64 [[SHADOW_PTR_INT]], 8
63 ; CHECK-NEXT: [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to ptr
64 ; CHECK-NEXT: [[TMP25:%.*]] = load ptr, ptr [[TMP24]], align 8
65 ; CHECK-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[TMP25]] to i64
66 ; CHECK-NEXT: [[TMP27:%.*]] = icmp sge i64 [[TMP26]], 0
67 ; CHECK-NEXT: [[TMP28:%.*]] = or i1 false, [[TMP27]]
68 ; CHECK-NEXT: [[TMP29:%.*]] = add i64 [[SHADOW_PTR_INT]], 16
69 ; CHECK-NEXT: [[TMP30:%.*]] = inttoptr i64 [[TMP29]] to ptr
70 ; CHECK-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP30]], align 8
71 ; CHECK-NEXT: [[TMP32:%.*]] = ptrtoint ptr [[TMP31]] to i64
72 ; CHECK-NEXT: [[TMP33:%.*]] = icmp sge i64 [[TMP32]], 0
73 ; CHECK-NEXT: [[TMP34:%.*]] = or i1 [[TMP28]], [[TMP33]]
74 ; CHECK-NEXT: [[TMP35:%.*]] = add i64 [[SHADOW_PTR_INT]], 24
75 ; CHECK-NEXT: [[TMP36:%.*]] = inttoptr i64 [[TMP35]] to ptr
76 ; CHECK-NEXT: [[TMP37:%.*]] = load ptr, ptr [[TMP36]], align 8
77 ; CHECK-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP37]] to i64
78 ; CHECK-NEXT: [[TMP39:%.*]] = icmp sge i64 [[TMP38]], 0
79 ; CHECK-NEXT: [[TMP40:%.*]] = or i1 [[TMP34]], [[TMP39]]
80 ; CHECK-NEXT: br i1 [[TMP40]], label [[TMP41:%.*]], label [[TMP42:%.*]], !prof [[PROF0]]
82 ; CHECK-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 1)
83 ; CHECK-NEXT: br label [[TMP42]]
85 ; CHECK-NEXT: br label [[TMP43]]
87 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4
88 ; CHECK-NEXT: ret i32 [[TMP1]]
91 %tmp1 = load i32, ptr %a, align 4
95 define void @test_store_unk(ptr %a) sanitize_type {
96 ; CHECK-LABEL: @test_store_unk(
98 ; CHECK-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8
99 ; CHECK-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8
100 ; CHECK-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A:%.*]] to i64
101 ; CHECK-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]]
102 ; CHECK-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3
103 ; CHECK-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]]
104 ; CHECK-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr
105 ; CHECK-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8
106 ; CHECK-NEXT: [[BAD_DESC:%.*]] = icmp ne ptr [[SHADOW_DESC]], null
107 ; CHECK-NEXT: br i1 [[BAD_DESC]], label [[TMP0:%.*]], label [[TMP22:%.*]], !prof [[PROF0]]
109 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[SHADOW_DESC]], null
110 ; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP20:%.*]]
112 ; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[SHADOW_PTR_INT]], 8
113 ; CHECK-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr
114 ; CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
115 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ne ptr [[TMP5]], null
116 ; CHECK-NEXT: [[TMP7:%.*]] = or i1 false, [[TMP6]]
117 ; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[SHADOW_PTR_INT]], 16
118 ; CHECK-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr
119 ; CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8
120 ; CHECK-NEXT: [[TMP11:%.*]] = icmp ne ptr [[TMP10]], null
121 ; CHECK-NEXT: [[TMP12:%.*]] = or i1 [[TMP7]], [[TMP11]]
122 ; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[SHADOW_PTR_INT]], 24
123 ; CHECK-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr
124 ; CHECK-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP14]], align 8
125 ; CHECK-NEXT: [[TMP16:%.*]] = icmp ne ptr [[TMP15]], null
126 ; CHECK-NEXT: [[TMP17:%.*]] = or i1 [[TMP12]], [[TMP16]]
127 ; CHECK-NEXT: br i1 [[TMP17]], label [[TMP18:%.*]], label [[TMP19:%.*]], !prof [[PROF0]]
129 ; CHECK-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 2)
130 ; CHECK-NEXT: br label [[TMP19]]
132 ; CHECK-NEXT: store ptr null, ptr [[SHADOW_PTR]], align 8
133 ; CHECK-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8
134 ; CHECK-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr
135 ; CHECK-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8
136 ; CHECK-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16
137 ; CHECK-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr
138 ; CHECK-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8
139 ; CHECK-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24
140 ; CHECK-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr
141 ; CHECK-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8
142 ; CHECK-NEXT: br label [[TMP21:%.*]]
144 ; CHECK-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 2)
145 ; CHECK-NEXT: br label [[TMP21]]
147 ; CHECK-NEXT: br label [[TMP43:%.*]]
149 ; CHECK-NEXT: [[TMP23:%.*]] = add i64 [[SHADOW_PTR_INT]], 8
150 ; CHECK-NEXT: [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to ptr
151 ; CHECK-NEXT: [[TMP25:%.*]] = load ptr, ptr [[TMP24]], align 8
152 ; CHECK-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[TMP25]] to i64
153 ; CHECK-NEXT: [[TMP27:%.*]] = icmp sge i64 [[TMP26]], 0
154 ; CHECK-NEXT: [[TMP28:%.*]] = or i1 false, [[TMP27]]
155 ; CHECK-NEXT: [[TMP29:%.*]] = add i64 [[SHADOW_PTR_INT]], 16
156 ; CHECK-NEXT: [[TMP30:%.*]] = inttoptr i64 [[TMP29]] to ptr
157 ; CHECK-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP30]], align 8
158 ; CHECK-NEXT: [[TMP32:%.*]] = ptrtoint ptr [[TMP31]] to i64
159 ; CHECK-NEXT: [[TMP33:%.*]] = icmp sge i64 [[TMP32]], 0
160 ; CHECK-NEXT: [[TMP34:%.*]] = or i1 [[TMP28]], [[TMP33]]
161 ; CHECK-NEXT: [[TMP35:%.*]] = add i64 [[SHADOW_PTR_INT]], 24
162 ; CHECK-NEXT: [[TMP36:%.*]] = inttoptr i64 [[TMP35]] to ptr
163 ; CHECK-NEXT: [[TMP37:%.*]] = load ptr, ptr [[TMP36]], align 8
164 ; CHECK-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP37]] to i64
165 ; CHECK-NEXT: [[TMP39:%.*]] = icmp sge i64 [[TMP38]], 0
166 ; CHECK-NEXT: [[TMP40:%.*]] = or i1 [[TMP34]], [[TMP39]]
167 ; CHECK-NEXT: br i1 [[TMP40]], label [[TMP41:%.*]], label [[TMP42:%.*]], !prof [[PROF0]]
169 ; CHECK-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 2)
170 ; CHECK-NEXT: br label [[TMP42]]
172 ; CHECK-NEXT: br label [[TMP43]]
174 ; CHECK-NEXT: store i32 42, ptr [[A]], align 4
175 ; CHECK-NEXT: ret void
178 store i32 42, ptr %a, align 4