1; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,LEGACY 2; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-event-callbacks=true -S | FileCheck %s --check-prefixes=CHECK,EVENT_CALLBACKS 3; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-event-callbacks=true -S | FileCheck %s --check-prefixes=CHECK,EVENT_CALLBACKS 4; RUN: opt < %s -dfsan -dfsan-args-abi -S | FileCheck %s --check-prefixes=CHECK,ARGS_ABI 5; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,FAST 6; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_LOAD_PTR 7; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-combine-pointer-labels-on-store=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR 8; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-debug-nonzero-labels -S | FileCheck %s --check-prefixes=CHECK,DEBUG_NONZERO_LABELS 9; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,FAST 10; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_LOAD_PTR 11; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-combine-pointer-labels-on-store=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR 12; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-debug-nonzero-labels -S | FileCheck %s --check-prefixes=CHECK,DEBUG_NONZERO_LABELS 13target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 14target triple = "x86_64-unknown-linux-gnu" 15 16; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]] 17; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]] 18; CHECK: @__dfsan_shadow_width_bits = weak_odr constant i32 [[#SBITS:]] 19; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]] 20 21define [4 x i8] @pass_array([4 x i8] %a) { 22 ; NO_COMBINE_LOAD_PTR: @"dfs$pass_array" 23 ; NO_COMBINE_LOAD_PTR: %1 = load [4 x i[[#SBITS]]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [4 x i[[#SBITS]]]*), align [[ALIGN:2]] 24 ; NO_COMBINE_LOAD_PTR: store [4 x i[[#SBITS]]] %1, [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [4 x i[[#SBITS]]]*), align [[ALIGN]] 25 26 ; ARGS_ABI: @"dfs$pass_array" 27 ; ARGS_ABI: ret { [4 x i8], i[[#SBITS]] } 28 29 ; DEBUG_NONZERO_LABELS: @"dfs$pass_array" 30 ; DEBUG_NONZERO_LABELS: [[L:%.*]] = load [4 x i[[#SBITS]]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [4 x i[[#SBITS]]]*), align [[ALIGN:2]] 31 ; DEBUG_NONZERO_LABELS: [[L0:%.*]] = extractvalue [4 x i[[#SBITS]]] [[L]], 0 32 ; DEBUG_NONZERO_LABELS: [[L1:%.*]] = extractvalue [4 x i[[#SBITS]]] [[L]], 1 33 ; DEBUG_NONZERO_LABELS: [[L01:%.*]] = or i[[#SBITS]] [[L0]], [[L1]] 34 ; DEBUG_NONZERO_LABELS: [[L2:%.*]] = extractvalue [4 x i[[#SBITS]]] [[L]], 2 35 ; DEBUG_NONZERO_LABELS: [[L012:%.*]] = or i[[#SBITS]] [[L01]], [[L2]] 36 ; DEBUG_NONZERO_LABELS: [[L3:%.*]] = extractvalue [4 x i[[#SBITS]]] [[L]], 3 37 ; DEBUG_NONZERO_LABELS: [[L0123:%.*]] = or i[[#SBITS]] [[L012]], [[L3]] 38 ; DEBUG_NONZERO_LABELS: {{.*}} = icmp ne i[[#SBITS]] [[L0123]], 0 39 ; DEBUG_NONZERO_LABELS: call void @__dfsan_nonzero_label() 40 41 ret [4 x i8] %a 42} 43 44%ArrayOfStruct = type [4 x {i8*, i32}] 45 46define %ArrayOfStruct @pass_array_of_struct(%ArrayOfStruct %as) { 47 ; NO_COMBINE_LOAD_PTR: @"dfs$pass_array_of_struct" 48 ; NO_COMBINE_LOAD_PTR: %1 = load [4 x { i[[#SBITS]], i[[#SBITS]] }], [4 x { i[[#SBITS]], i[[#SBITS]] }]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [4 x { i[[#SBITS]], i[[#SBITS]] }]*), align [[ALIGN:2]] 49 ; NO_COMBINE_LOAD_PTR: store [4 x { i[[#SBITS]], i[[#SBITS]] }] %1, [4 x { i[[#SBITS]], i[[#SBITS]] }]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [4 x { i[[#SBITS]], i[[#SBITS]] }]*), align [[ALIGN]] 50 51 ; ARGS_ABI: @"dfs$pass_array_of_struct" 52 ; ARGS_ABI: ret { [4 x { i8*, i32 }], i[[#SBITS]] } 53 ret %ArrayOfStruct %as 54} 55 56define [4 x i1]* @alloca_ret_array() { 57 ; NO_COMBINE_LOAD_PTR: @"dfs$alloca_ret_array" 58 ; NO_COMBINE_LOAD_PTR: store i[[#SBITS]] 0, i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align 2 59 %p = alloca [4 x i1] 60 ret [4 x i1]* %p 61} 62 63define [4 x i1] @load_alloca_array() { 64 ; NO_COMBINE_LOAD_PTR-LABEL: @"dfs$load_alloca_array" 65 ; NO_COMBINE_LOAD_PTR-NEXT: %[[#R:]] = alloca i[[#SBITS]], align [[#SBYTES]] 66 ; NO_COMBINE_LOAD_PTR-NEXT: %p = alloca [4 x i1] 67 ; NO_COMBINE_LOAD_PTR-NEXT: %[[#R+1]] = load i[[#SBITS]], i[[#SBITS]]* %[[#R]], align [[#SBYTES]] 68 ; NO_COMBINE_LOAD_PTR-NEXT: %[[#R+2]] = insertvalue [4 x i[[#SBITS]]] undef, i[[#SBITS]] %[[#R+1]], 0 69 ; NO_COMBINE_LOAD_PTR-NEXT: %[[#R+3]] = insertvalue [4 x i[[#SBITS]]] %[[#R+2]], i[[#SBITS]] %[[#R+1]], 1 70 ; NO_COMBINE_LOAD_PTR-NEXT: %[[#R+4]] = insertvalue [4 x i[[#SBITS]]] %[[#R+3]], i[[#SBITS]] %[[#R+1]], 2 71 ; NO_COMBINE_LOAD_PTR-NEXT: %[[#R+5]] = insertvalue [4 x i[[#SBITS]]] %[[#R+4]], i[[#SBITS]] %[[#R+1]], 3 72 ; NO_COMBINE_LOAD_PTR-NEXT: %a = load [4 x i1], [4 x i1]* %p 73 ; NO_COMBINE_LOAD_PTR-NEXT: store [4 x i[[#SBITS]]] %[[#R+5]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [4 x i[[#SBITS]]]*), align 2 74 ; NO_COMBINE_LOAD_PTR-NEXT: ret [4 x i1] %a 75 76 %p = alloca [4 x i1] 77 %a = load [4 x i1], [4 x i1]* %p 78 ret [4 x i1] %a 79} 80 81define [0 x i1] @load_array0([0 x i1]* %p) { 82 ; NO_COMBINE_LOAD_PTR: @"dfs$load_array0" 83 ; NO_COMBINE_LOAD_PTR: store [0 x i[[#SBITS]]] zeroinitializer, [0 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [0 x i[[#SBITS]]]*), align 2 84 %a = load [0 x i1], [0 x i1]* %p 85 ret [0 x i1] %a 86} 87 88define [1 x i1] @load_array1([1 x i1]* %p) { 89 ; NO_COMBINE_LOAD_PTR: @"dfs$load_array1" 90 ; NO_COMBINE_LOAD_PTR: [[L:%.*]] = load i[[#SBITS]], 91 ; NO_COMBINE_LOAD_PTR: [[S:%.*]] = insertvalue [1 x i[[#SBITS]]] undef, i[[#SBITS]] [[L]], 0 92 ; NO_COMBINE_LOAD_PTR: store [1 x i[[#SBITS]]] [[S]], [1 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [1 x i[[#SBITS]]]*), align 2 93 94 ; EVENT_CALLBACKS: @"dfs$load_array1" 95 ; EVENT_CALLBACKS: [[L:%.*]] = or i[[#SBITS]] 96 ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] [[L]], i8* {{.*}}) 97 98 ; FAST: @"dfs$load_array1" 99 ; FAST: [[P:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]] 100 ; FAST: [[L:%.*]] = load i[[#SBITS]], i[[#SBITS]]* {{.*}}, align [[#SBYTES]] 101 ; FAST: [[U:%.*]] = or i[[#SBITS]] [[L]], [[P]] 102 ; FAST: [[S1:%.*]] = insertvalue [1 x i[[#SBITS]]] undef, i[[#SBITS]] [[U]], 0 103 ; FAST: store [1 x i[[#SBITS]]] [[S1]], [1 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [1 x i[[#SBITS]]]*), align [[ALIGN]] 104 105 ; LEGACY: @"dfs$load_array1" 106 ; LEGACY: [[P:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]] 107 ; LEGACY: [[L:%.*]] = load i[[#SBITS]], i[[#SBITS]]* {{.*}}, align [[#SBYTES]] 108 ; LEGACY: [[U:%.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext [[L]], i[[#SBITS]] zeroext [[P]]) 109 ; LEGACY: [[PH:%.*]] = phi i[[#SBITS]] [ [[U]], {{.*}} ], [ [[L]], {{.*}} ] 110 ; LEGACY: store i[[#SBITS]] [[PH]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]] 111 112 %a = load [1 x i1], [1 x i1]* %p 113 ret [1 x i1] %a 114} 115 116define [2 x i1] @load_array2([2 x i1]* %p) { 117 ; NO_COMBINE_LOAD_PTR: @"dfs$load_array2" 118 ; NO_COMBINE_LOAD_PTR: [[P1:%.*]] = getelementptr i[[#SBITS]], i[[#SBITS]]* [[P0:%.*]], i64 1 119 ; NO_COMBINE_LOAD_PTR-DAG: [[E1:%.*]] = load i[[#SBITS]], i[[#SBITS]]* [[P1]], align [[#SBYTES]] 120 ; NO_COMBINE_LOAD_PTR-DAG: [[E0:%.*]] = load i[[#SBITS]], i[[#SBITS]]* [[P0]], align [[#SBYTES]] 121 ; NO_COMBINE_LOAD_PTR: [[U:%.*]] = or i[[#SBITS]] [[E0]], [[E1]] 122 ; NO_COMBINE_LOAD_PTR: [[S1:%.*]] = insertvalue [2 x i[[#SBITS]]] undef, i[[#SBITS]] [[U]], 0 123 ; NO_COMBINE_LOAD_PTR: [[S2:%.*]] = insertvalue [2 x i[[#SBITS]]] [[S1]], i[[#SBITS]] [[U]], 1 124 ; NO_COMBINE_LOAD_PTR: store [2 x i[[#SBITS]]] [[S2]], [2 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 125 126 ; EVENT_CALLBACKS: @"dfs$load_array2" 127 ; EVENT_CALLBACKS: [[O1:%.*]] = or i[[#SBITS]] 128 ; EVENT_CALLBACKS: [[O2:%.*]] = or i[[#SBITS]] [[O1]] 129 ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] [[O2]], i8* {{.*}}) 130 131 ; FAST: @"dfs$load_array2" 132 ; FAST: [[P:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]] 133 ; FAST: [[O:%.*]] = or i[[#SBITS]] 134 ; FAST: [[U:%.*]] = or i[[#SBITS]] [[O]], [[P]] 135 ; FAST: [[S:%.*]] = insertvalue [2 x i[[#SBITS]]] undef, i[[#SBITS]] [[U]], 0 136 ; FAST: [[S1:%.*]] = insertvalue [2 x i[[#SBITS]]] [[S]], i[[#SBITS]] [[U]], 1 137 ; FAST: store [2 x i[[#SBITS]]] [[S1]], [2 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [2 x i[[#SBITS]]]*), align [[ALIGN]] 138 %a = load [2 x i1], [2 x i1]* %p 139 ret [2 x i1] %a 140} 141 142define [4 x i1] @load_array4([4 x i1]* %p) { 143 ; NO_COMBINE_LOAD_PTR: @"dfs$load_array4" 144 ; NO_COMBINE_LOAD_PTR: [[T:%.*]] = trunc i[[#mul(4, SBITS)]] {{.*}} to i[[#SBITS]] 145 ; NO_COMBINE_LOAD_PTR: [[S1:%.*]] = insertvalue [4 x i[[#SBITS]]] undef, i[[#SBITS]] [[T]], 0 146 ; NO_COMBINE_LOAD_PTR: [[S2:%.*]] = insertvalue [4 x i[[#SBITS]]] [[S1]], i[[#SBITS]] [[T]], 1 147 ; NO_COMBINE_LOAD_PTR: [[S3:%.*]] = insertvalue [4 x i[[#SBITS]]] [[S2]], i[[#SBITS]] [[T]], 2 148 ; NO_COMBINE_LOAD_PTR: [[S4:%.*]] = insertvalue [4 x i[[#SBITS]]] [[S3]], i[[#SBITS]] [[T]], 3 149 ; NO_COMBINE_LOAD_PTR: store [4 x i[[#SBITS]]] [[S4]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [4 x i[[#SBITS]]]*), align 2 150 151 ; EVENT_CALLBACKS: @"dfs$load_array4" 152 ; EVENT_CALLBACKS: [[O0:%.*]] = or i[[#mul(4, SBITS)]] 153 ; EVENT_CALLBACKS: [[O1:%.*]] = or i[[#mul(4, SBITS)]] [[O0]] 154 ; EVENT_CALLBACKS: [[O2:%.*]] = trunc i[[#mul(4, SBITS)]] [[O1]] to i[[#SBITS]] 155 ; EVENT_CALLBACKS: [[O3:%.*]] = or i[[#SBITS]] [[O2]] 156 ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] [[O3]], i8* {{.*}}) 157 158 ; FAST: @"dfs$load_array4" 159 ; FAST: [[T:%.*]] = trunc i[[#mul(4, SBITS)]] {{.*}} to i[[#SBITS]] 160 ; FAST: [[O:%.*]] = or i[[#SBITS]] [[T]] 161 ; FAST: [[S1:%.*]] = insertvalue [4 x i[[#SBITS]]] undef, i[[#SBITS]] [[O]], 0 162 ; FAST: [[S2:%.*]] = insertvalue [4 x i[[#SBITS]]] [[S1]], i[[#SBITS]] [[O]], 1 163 ; FAST: [[S3:%.*]] = insertvalue [4 x i[[#SBITS]]] [[S2]], i[[#SBITS]] [[O]], 2 164 ; FAST: [[S4:%.*]] = insertvalue [4 x i[[#SBITS]]] [[S3]], i[[#SBITS]] [[O]], 3 165 ; FAST: store [4 x i[[#SBITS]]] [[S4]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [4 x i[[#SBITS]]]*), align 2 166 167 ; LEGACY: @"dfs$load_array4" 168 ; LEGACY: [[P:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]] 169 ; LEGACY: [[PH1:%.*]] = phi i[[#SBITS]] 170 ; LEGACY: [[U:%.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext [[PH1]], i[[#SBITS]] zeroext [[P]]) 171 ; LEGACY: [[PH:%.*]] = phi i[[#SBITS]] [ [[U]], {{.*}} ], [ [[PH1]], {{.*}} ] 172 ; LEGACY: store i[[#SBITS]] [[PH]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]] 173 174 %a = load [4 x i1], [4 x i1]* %p 175 ret [4 x i1] %a 176} 177 178define i1 @extract_array([4 x i1] %a) { 179 ; NO_COMBINE_LOAD_PTR: @"dfs$extract_array" 180 ; NO_COMBINE_LOAD_PTR: [[AM:%.*]] = load [4 x i[[#SBITS]]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [4 x i[[#SBITS]]]*), align [[ALIGN:2]] 181 ; NO_COMBINE_LOAD_PTR: [[EM:%.*]] = extractvalue [4 x i[[#SBITS]]] [[AM]], 2 182 ; NO_COMBINE_LOAD_PTR: store i[[#SBITS]] [[EM]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align 2 183 %e2 = extractvalue [4 x i1] %a, 2 184 ret i1 %e2 185} 186 187define [4 x i1] @insert_array([4 x i1] %a, i1 %e2) { 188 ; NO_COMBINE_LOAD_PTR: @"dfs$insert_array" 189 ; NO_COMBINE_LOAD_PTR: [[EM:%.*]] = load i[[#SBITS]], i[[#SBITS]]* 190 ; NO_COMBINE_LOAD_PTR-SAME: inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 [[#mul(4, SBYTES)]]) to i[[#SBITS]]*), align [[ALIGN:2]] 191 ; NO_COMBINE_LOAD_PTR: [[AM:%.*]] = load [4 x i[[#SBITS]]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [4 x i[[#SBITS]]]*), align [[ALIGN]] 192 ; NO_COMBINE_LOAD_PTR: [[AM1:%.*]] = insertvalue [4 x i[[#SBITS]]] [[AM]], i[[#SBITS]] [[EM]], 0 193 ; NO_COMBINE_LOAD_PTR: store [4 x i[[#SBITS]]] [[AM1]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [4 x i[[#SBITS]]]*), align [[ALIGN]] 194 %a1 = insertvalue [4 x i1] %a, i1 %e2, 0 195 ret [4 x i1] %a1 196} 197 198define void @store_alloca_array([4 x i1] %a) { 199 ; FAST: @"dfs$store_alloca_array" 200 ; FAST: [[S:%.*]] = load [4 x i[[#SBITS]]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [4 x i[[#SBITS]]]*), align [[ALIGN:2]] 201 ; FAST: [[SP:%.*]] = alloca i[[#SBITS]], align [[#SBYTES]] 202 ; FAST: [[E0:%.*]] = extractvalue [4 x i[[#SBITS]]] [[S]], 0 203 ; FAST: [[E1:%.*]] = extractvalue [4 x i[[#SBITS]]] [[S]], 1 204 ; FAST: [[E01:%.*]] = or i[[#SBITS]] [[E0]], [[E1]] 205 ; FAST: [[E2:%.*]] = extractvalue [4 x i[[#SBITS]]] [[S]], 2 206 ; FAST: [[E012:%.*]] = or i[[#SBITS]] [[E01]], [[E2]] 207 ; FAST: [[E3:%.*]] = extractvalue [4 x i[[#SBITS]]] [[S]], 3 208 ; FAST: [[E0123:%.*]] = or i[[#SBITS]] [[E012]], [[E3]] 209 ; FAST: store i[[#SBITS]] [[E0123]], i[[#SBITS]]* [[SP]], align [[#SBYTES]] 210 %p = alloca [4 x i1] 211 store [4 x i1] %a, [4 x i1]* %p 212 ret void 213} 214 215define void @store_zero_array([4 x i1]* %p) { 216 ; FAST: @"dfs$store_zero_array" 217 ; FAST: store i[[#mul(4, SBITS)]] 0, i[[#mul(4, SBITS)]]* {{.*}} 218 store [4 x i1] zeroinitializer, [4 x i1]* %p 219 ret void 220} 221 222define void @store_array2([2 x i1] %a, [2 x i1]* %p) { 223 ; LEGACY: @"dfs$store_array2" 224 ; LEGACY: [[S:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]] 225 ; LEGACY: [[SP0:%.*]] = getelementptr i[[#SBITS]], i[[#SBITS]]* [[SP:%.*]], i32 0 226 ; LEGACY: store i[[#SBITS]] [[S]], i[[#SBITS]]* [[SP0]], align [[#SBYTES]] 227 ; LEGACY: [[SP1:%.*]] = getelementptr i[[#SBITS]], i[[#SBITS]]* [[SP]], i32 1 228 ; LEGACY: store i[[#SBITS]] [[S]], i[[#SBITS]]* [[SP1]], align [[#SBYTES]] 229 230 ; EVENT_CALLBACKS: @"dfs$store_array2" 231 ; EVENT_CALLBACKS: [[E12:%.*]] = or i[[#SBITS]] 232 ; EVENT_CALLBACKS: [[P:%.*]] = bitcast [2 x i1]* %p to i8* 233 ; EVENT_CALLBACKS: call void @__dfsan_store_callback(i[[#SBITS]] [[E12]], i8* [[P]]) 234 235 ; FAST: @"dfs$store_array2" 236 ; FAST: [[S:%.*]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 237 ; FAST: [[E1:%.*]] = extractvalue [2 x i[[#SBITS]]] [[S]], 0 238 ; FAST: [[E2:%.*]] = extractvalue [2 x i[[#SBITS]]] [[S]], 1 239 ; FAST: [[E12:%.*]] = or i[[#SBITS]] [[E1]], [[E2]] 240 ; FAST: [[SP0:%.*]] = getelementptr i[[#SBITS]], i[[#SBITS]]* [[SP:%.*]], i32 0 241 ; FAST: store i[[#SBITS]] [[E12]], i[[#SBITS]]* [[SP0]], align [[#SBYTES]] 242 ; FAST: [[SP1:%.*]] = getelementptr i[[#SBITS]], i[[#SBITS]]* [[SP]], i32 1 243 ; FAST: store i[[#SBITS]] [[E12]], i[[#SBITS]]* [[SP1]], align [[#SBYTES]] 244 245 ; COMBINE_STORE_PTR: @"dfs$store_array2" 246 ; COMBINE_STORE_PTR: [[O:%.*]] = or i[[#SBITS]] 247 ; COMBINE_STORE_PTR: [[U:%.*]] = or i[[#SBITS]] [[O]] 248 ; COMBINE_STORE_PTR: [[P1:%.*]] = getelementptr i[[#SBITS]], i[[#SBITS]]* [[P:%.*]], i32 0 249 ; COMBINE_STORE_PTR: store i[[#SBITS]] [[U]], i[[#SBITS]]* [[P1]], align [[#SBYTES]] 250 ; COMBINE_STORE_PTR: [[P2:%.*]] = getelementptr i[[#SBITS]], i[[#SBITS]]* [[P]], i32 1 251 ; COMBINE_STORE_PTR: store i[[#SBITS]] [[U]], i[[#SBITS]]* [[P2]], align [[#SBYTES]] 252 253 store [2 x i1] %a, [2 x i1]* %p 254 ret void 255} 256 257define void @store_array17([17 x i1] %a, [17 x i1]* %p) { 258 ; FAST: @"dfs$store_array17" 259 ; FAST: %[[#R:]] = load [17 x i[[#SBITS]]], [17 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [17 x i[[#SBITS]]]*), align 2 260 ; FAST: %[[#R+1]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 0 261 ; FAST: %[[#R+2]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 1 262 ; FAST: %[[#R+3]] = or i[[#SBITS]] %[[#R+1]], %[[#R+2]] 263 ; FAST: %[[#R+4]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 2 264 ; FAST: %[[#R+5]] = or i[[#SBITS]] %[[#R+3]], %[[#R+4]] 265 ; FAST: %[[#R+6]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 3 266 ; FAST: %[[#R+7]] = or i[[#SBITS]] %[[#R+5]], %[[#R+6]] 267 ; FAST: %[[#R+8]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 4 268 ; FAST: %[[#R+9]] = or i[[#SBITS]] %[[#R+7]], %[[#R+8]] 269 ; FAST: %[[#R+10]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 5 270 ; FAST: %[[#R+11]] = or i[[#SBITS]] %[[#R+9]], %[[#R+10]] 271 ; FAST: %[[#R+12]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 6 272 ; FAST: %[[#R+13]] = or i[[#SBITS]] %[[#R+11]], %[[#R+12]] 273 ; FAST: %[[#R+14]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 7 274 ; FAST: %[[#R+15]] = or i[[#SBITS]] %[[#R+13]], %[[#R+14]] 275 ; FAST: %[[#R+16]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 8 276 ; FAST: %[[#R+17]] = or i[[#SBITS]] %[[#R+15]], %[[#R+16]] 277 ; FAST: %[[#R+18]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 9 278 ; FAST: %[[#R+19]] = or i[[#SBITS]] %[[#R+17]], %[[#R+18]] 279 ; FAST: %[[#R+20]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 10 280 ; FAST: %[[#R+21]] = or i[[#SBITS]] %[[#R+19]], %[[#R+20]] 281 ; FAST: %[[#R+22]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 11 282 ; FAST: %[[#R+23]] = or i[[#SBITS]] %[[#R+21]], %[[#R+22]] 283 ; FAST: %[[#R+24]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 12 284 ; FAST: %[[#R+25]] = or i[[#SBITS]] %[[#R+23]], %[[#R+24]] 285 ; FAST: %[[#R+26]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 13 286 ; FAST: %[[#R+27]] = or i[[#SBITS]] %[[#R+25]], %[[#R+26]] 287 ; FAST: %[[#R+28]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 14 288 ; FAST: %[[#R+29]] = or i[[#SBITS]] %[[#R+27]], %[[#R+28]] 289 ; FAST: %[[#R+30]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 15 290 ; FAST: %[[#R+31]] = or i[[#SBITS]] %[[#R+29]], %[[#R+30]] 291 ; FAST: %[[#R+32]] = extractvalue [17 x i[[#SBITS]]] %[[#R]], 16 292 ; FAST: %[[#R+33]] = or i[[#SBITS]] %[[#R+31]], %[[#R+32]] 293 ; FAST: %[[#VREG:]] = insertelement <8 x i[[#SBITS]]> undef, i[[#SBITS]] %[[#R+33]], i32 0 294 ; FAST: %[[#VREG+1]] = insertelement <8 x i[[#SBITS]]> %[[#VREG]], i[[#SBITS]] %[[#R+33]], i32 1 295 ; FAST: %[[#VREG+2]] = insertelement <8 x i[[#SBITS]]> %[[#VREG+1]], i[[#SBITS]] %[[#R+33]], i32 2 296 ; FAST: %[[#VREG+3]] = insertelement <8 x i[[#SBITS]]> %[[#VREG+2]], i[[#SBITS]] %[[#R+33]], i32 3 297 ; FAST: %[[#VREG+4]] = insertelement <8 x i[[#SBITS]]> %[[#VREG+3]], i[[#SBITS]] %[[#R+33]], i32 4 298 ; FAST: %[[#VREG+5]] = insertelement <8 x i[[#SBITS]]> %[[#VREG+4]], i[[#SBITS]] %[[#R+33]], i32 5 299 ; FAST: %[[#VREG+6]] = insertelement <8 x i[[#SBITS]]> %[[#VREG+5]], i[[#SBITS]] %[[#R+33]], i32 6 300 ; FAST: %[[#VREG+7]] = insertelement <8 x i[[#SBITS]]> %[[#VREG+6]], i[[#SBITS]] %[[#R+33]], i32 7 301 ; FAST: %[[#VREG+8]] = bitcast i[[#SBITS]]* %[[P:.*]] to <8 x i[[#SBITS]]>* 302 ; FAST: %[[#VREG+9]] = getelementptr <8 x i[[#SBITS]]>, <8 x i[[#SBITS]]>* %[[#VREG+8]], i32 0 303 ; FAST: store <8 x i[[#SBITS]]> %[[#VREG+7]], <8 x i[[#SBITS]]>* %[[#VREG+9]], align [[#SBYTES]] 304 ; FAST: %[[#VREG+10]] = getelementptr <8 x i[[#SBITS]]>, <8 x i[[#SBITS]]>* %[[#VREG+8]], i32 1 305 ; FAST: store <8 x i[[#SBITS]]> %[[#VREG+7]], <8 x i[[#SBITS]]>* %[[#VREG+10]], align [[#SBYTES]] 306 ; FAST: %[[#VREG+11]] = getelementptr i[[#SBITS]], i[[#SBITS]]* %[[P]], i32 16 307 ; FAST: store i[[#SBITS]] %[[#R+33]], i[[#SBITS]]* %[[#VREG+11]], align [[#SBYTES]] 308 store [17 x i1] %a, [17 x i1]* %p 309 ret void 310} 311 312define [2 x i32] @const_array() { 313 ; FAST: @"dfs$const_array" 314 ; FAST: store [2 x i[[#SBITS]]] zeroinitializer, [2 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [2 x i[[#SBITS]]]*), align 2 315 ret [2 x i32] [ i32 42, i32 11 ] 316} 317 318define [4 x i8] @call_array([4 x i8] %a) { 319 ; FAST-LABEL: @"dfs$call_array" 320 ; FAST: %[[#R:]] = load [4 x i[[#SBITS]]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [4 x i[[#SBITS]]]*), align [[ALIGN:2]] 321 ; FAST: store [4 x i[[#SBITS]]] %[[#R]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to [4 x i[[#SBITS]]]*), align [[ALIGN]] 322 ; FAST: %_dfsret = load [4 x i[[#SBITS]]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [4 x i[[#SBITS]]]*), align [[ALIGN]] 323 ; FAST: store [4 x i[[#SBITS]]] %_dfsret, [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [4 x i[[#SBITS]]]*), align [[ALIGN]] 324 325 %r = call [4 x i8] @pass_array([4 x i8] %a) 326 ret [4 x i8] %r 327} 328 329%LargeArr = type [1000 x i8] 330 331define i8 @fun_with_large_args(i1 %i, %LargeArr %a) { 332 ; FAST: @"dfs$fun_with_large_args" 333 ; FAST: store i[[#SBITS]] 0, i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align 2 334 %r = extractvalue %LargeArr %a, 0 335 ret i8 %r 336} 337 338define %LargeArr @fun_with_large_ret() { 339 ; FAST: @"dfs$fun_with_large_ret" 340 ; FAST-NEXT: ret [1000 x i8] zeroinitializer 341 ret %LargeArr zeroinitializer 342} 343 344define i8 @call_fun_with_large_ret() { 345 ; FAST: @"dfs$call_fun_with_large_ret" 346 ; FAST: store i[[#SBITS]] 0, i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align 2 347 %r = call %LargeArr @fun_with_large_ret() 348 %e = extractvalue %LargeArr %r, 0 349 ret i8 %e 350} 351 352define i8 @call_fun_with_large_args(i1 %i, %LargeArr %a) { 353 ; FAST: @"dfs$call_fun_with_large_args" 354 ; FAST: [[I:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]] 355 ; FAST: store i[[#SBITS]] [[I]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]] 356 ; FAST: %r = call i8 @"dfs$fun_with_large_args"(i1 %i, [1000 x i8] %a) 357 358 %r = call i8 @fun_with_large_args(i1 %i, %LargeArr %a) 359 ret i8 %r 360} 361