1; RUN: llc -mtriple=i686 -O0 < %s | FileCheck %s 2; RUN: llc -mtriple=x86_64 -O0 < %s | FileCheck %s 3 4; CHECK-LABEL: in_bounds: 5; CHECK-NOT: __stack_chk_guard 6define i32 @in_bounds() #0 { 7 %var = alloca i32, align 4 8 store i32 0, ptr %var, align 4 9 %ret = load i32, ptr %var, align 4 10 ret i32 %ret 11} 12 13; CHECK-LABEL: constant_out_of_bounds: 14; CHECK: __stack_chk_guard 15define i32 @constant_out_of_bounds() #0 { 16 %var = alloca i32, align 4 17 store i32 0, ptr %var, align 4 18 %gep = getelementptr inbounds i32, ptr %var, i32 1 19 %ret = load i32, ptr %gep, align 4 20 ret i32 %ret 21} 22 23; CHECK-LABEL: nonconstant_out_of_bounds: 24; CHECK: __stack_chk_guard 25define i32 @nonconstant_out_of_bounds(i32 %n) #0 { 26 %var = alloca i32, align 4 27 store i32 0, ptr %var, align 4 28 %gep = getelementptr inbounds i32, ptr %var, i32 %n 29 %ret = load i32, ptr %gep, align 4 30 ret i32 %ret 31} 32 33; CHECK-LABEL: phi_before_gep_in_bounds: 34; CHECK-NOT: __stack_chk_guard 35define i32 @phi_before_gep_in_bounds(i32 %k) #0 { 36entry: 37 %var1 = alloca i32, align 4 38 %var2 = alloca i32, align 4 39 store i32 0, ptr %var1, align 4 40 store i32 0, ptr %var2, align 4 41 %cmp = icmp ne i32 %k, 0 42 br i1 %cmp, label %if, label %then 43 44if: 45 br label %then 46 47then: 48 %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ] 49 %ret = load i32, ptr %ptr, align 4 50 ret i32 %ret 51} 52 53; CHECK-LABEL: phi_before_gep_constant_out_of_bounds: 54; CHECK: __stack_chk_guard 55define i32 @phi_before_gep_constant_out_of_bounds(i32 %k) #0 { 56entry: 57 %var1 = alloca i32, align 4 58 %var2 = alloca i32, align 4 59 store i32 0, ptr %var1, align 4 60 store i32 0, ptr %var2, align 4 61 %cmp = icmp ne i32 %k, 0 62 br i1 %cmp, label %if, label %then 63 64if: 65 br label %then 66 67then: 68 %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ] 69 %gep = getelementptr inbounds i32, ptr %ptr, i32 1 70 %ret = load i32, ptr %gep, align 4 71 ret i32 %ret 72} 73 74; CHECK-LABEL: phi_before_gep_nonconstant_out_of_bounds: 75; CHECK: __stack_chk_guard 76define i32 @phi_before_gep_nonconstant_out_of_bounds(i32 %k, i32 %n) #0 { 77entry: 78 %var1 = alloca i32, align 4 79 %var2 = alloca i32, align 4 80 store i32 0, ptr %var1, align 4 81 store i32 0, ptr %var2, align 4 82 %cmp = icmp ne i32 %k, 0 83 br i1 %cmp, label %if, label %then 84 85if: 86 br label %then 87 88then: 89 %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ] 90 %gep = getelementptr inbounds i32, ptr %ptr, i32 %n 91 %ret = load i32, ptr %gep, align 4 92 ret i32 %ret 93} 94 95; CHECK-LABEL: phi_after_gep_in_bounds: 96; CHECK-NOT: __stack_chk_guard 97define i32 @phi_after_gep_in_bounds(i32 %k) #0 { 98entry: 99 %var1 = alloca i32, align 4 100 %var2 = alloca i32, align 4 101 store i32 0, ptr %var1, align 4 102 store i32 0, ptr %var2, align 4 103 %cmp = icmp ne i32 %k, 0 104 br i1 %cmp, label %if, label %else 105 106if: 107 br label %then 108 109else: 110 br label %then 111 112then: 113 %ptr = phi ptr [ %var1, %if ], [ %var2, %else ] 114 %ret = load i32, ptr %ptr, align 4 115 ret i32 %ret 116} 117 118; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_a: 119; CHECK: __stack_chk_guard 120define i32 @phi_after_gep_constant_out_of_bounds_a(i32 %k) #0 { 121entry: 122 %var1 = alloca i32, align 4 123 %var2 = alloca i32, align 4 124 store i32 0, ptr %var1, align 4 125 store i32 0, ptr %var2, align 4 126 %cmp = icmp ne i32 %k, 0 127 br i1 %cmp, label %if, label %else 128 129if: 130 br label %then 131 132else: 133 %gep2 = getelementptr inbounds i32, ptr %var2, i32 1 134 br label %then 135 136then: 137 %ptr = phi ptr [ %var1, %if ], [ %gep2, %else ] 138 %ret = load i32, ptr %ptr, align 4 139 ret i32 %ret 140} 141 142; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_b: 143; CHECK: __stack_chk_guard 144define i32 @phi_after_gep_constant_out_of_bounds_b(i32 %k) #0 { 145entry: 146 %var1 = alloca i32, align 4 147 %var2 = alloca i32, align 4 148 store i32 0, ptr %var1, align 4 149 store i32 0, ptr %var2, align 4 150 %cmp = icmp ne i32 %k, 0 151 br i1 %cmp, label %if, label %else 152 153if: 154 %gep1 = getelementptr inbounds i32, ptr %var1, i32 1 155 br label %then 156 157else: 158 br label %then 159 160then: 161 %ptr = phi ptr [ %gep1, %if ], [ %var2, %else ] 162 %ret = load i32, ptr %ptr, align 4 163 ret i32 %ret 164} 165 166; CHECK-LABEL: phi_different_types_a: 167; CHECK: __stack_chk_guard 168define i64 @phi_different_types_a(i32 %k) #0 { 169entry: 170 %var1 = alloca i64, align 4 171 %var2 = alloca i32, align 4 172 store i64 0, ptr %var1, align 4 173 store i32 0, ptr %var2, align 4 174 %cmp = icmp ne i32 %k, 0 175 br i1 %cmp, label %if, label %then 176 177if: 178 br label %then 179 180then: 181 %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ] 182 %ret = load i64, ptr %ptr, align 4 183 ret i64 %ret 184} 185 186; CHECK-LABEL: phi_different_types_b: 187; CHECK: __stack_chk_guard 188define i64 @phi_different_types_b(i32 %k) #0 { 189entry: 190 %var1 = alloca i32, align 4 191 %var2 = alloca i64, align 4 192 store i32 0, ptr %var1, align 4 193 store i64 0, ptr %var2, align 4 194 %cmp = icmp ne i32 %k, 0 195 br i1 %cmp, label %if, label %then 196 197if: 198 br label %then 199 200then: 201 %ptr = phi ptr [ %var2, %entry ], [ %var1, %if ] 202 %ret = load i64, ptr %ptr, align 4 203 ret i64 %ret 204} 205 206; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_a: 207; CHECK: __stack_chk_guard 208define i32 @phi_after_gep_nonconstant_out_of_bounds_a(i32 %k, i32 %n) #0 { 209entry: 210 %var1 = alloca i32, align 4 211 %var2 = alloca i32, align 4 212 store i32 0, ptr %var1, align 4 213 store i32 0, ptr %var2, align 4 214 %cmp = icmp ne i32 %k, 0 215 br i1 %cmp, label %if, label %else 216 217if: 218 br label %then 219 220else: 221 %gep2 = getelementptr inbounds i32, ptr %var2, i32 %n 222 br label %then 223 224then: 225 %ptr = phi ptr [ %var1, %if ], [ %gep2, %else ] 226 %ret = load i32, ptr %ptr, align 4 227 ret i32 %ret 228} 229 230; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_b: 231; CHECK: __stack_chk_guard 232define i32 @phi_after_gep_nonconstant_out_of_bounds_b(i32 %k, i32 %n) #0 { 233entry: 234 %var1 = alloca i32, align 4 235 %var2 = alloca i32, align 4 236 store i32 0, ptr %var1, align 4 237 store i32 0, ptr %var2, align 4 238 %cmp = icmp ne i32 %k, 0 239 br i1 %cmp, label %if, label %else 240 241if: 242 %gep1 = getelementptr inbounds i32, ptr %var1, i32 %n 243 br label %then 244 245else: 246 br label %then 247 248then: 249 %ptr = phi ptr [ %gep1, %if ], [ %var2, %else ] 250 %ret = load i32, ptr %ptr, align 4 251 ret i32 %ret 252} 253 254%struct.outer = type { %struct.inner, %struct.inner } 255%struct.inner = type { i32, i32 } 256 257; CHECK-LABEL: struct_in_bounds: 258; CHECK-NOT: __stack_chk_guard 259define void @struct_in_bounds() #0 { 260 %var = alloca %struct.outer, align 4 261 %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 0, i32 1 262 %innergep = getelementptr inbounds %struct.inner, ptr %outergep, i32 0, i32 1 263 store i32 0, ptr %innergep, align 4 264 ret void 265} 266 267; CHECK-LABEL: struct_constant_out_of_bounds_a: 268; CHECK: __stack_chk_guard 269define void @struct_constant_out_of_bounds_a() #0 { 270 %var = alloca %struct.outer, align 4 271 %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 1, i32 0 272 store i32 0, ptr %outergep, align 4 273 ret void 274} 275 276; CHECK-LABEL: struct_constant_out_of_bounds_b: 277; Here the offset is out-of-bounds of the addressed struct.inner member, but 278; still within bounds of the outer struct so no stack guard is needed. 279; CHECK-NOT: __stack_chk_guard 280define void @struct_constant_out_of_bounds_b() #0 { 281 %var = alloca %struct.outer, align 4 282 %innergep = getelementptr inbounds %struct.inner, ptr %var, i32 1, i32 0 283 store i32 0, ptr %innergep, align 4 284 ret void 285} 286 287; CHECK-LABEL: struct_constant_out_of_bounds_c: 288; Here we are out-of-bounds of both the inner and outer struct. 289; CHECK: __stack_chk_guard 290define void @struct_constant_out_of_bounds_c() #0 { 291 %var = alloca %struct.outer, align 4 292 %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 0, i32 1 293 %innergep = getelementptr inbounds %struct.inner, ptr %outergep, i32 1, i32 0 294 store i32 0, ptr %innergep, align 4 295 ret void 296} 297 298; CHECK-LABEL: struct_nonconstant_out_of_bounds_a: 299; CHECK: __stack_chk_guard 300define void @struct_nonconstant_out_of_bounds_a(i32 %n) #0 { 301 %var = alloca %struct.outer, align 4 302 %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 %n, i32 0 303 store i32 0, ptr %outergep, align 4 304 ret void 305} 306 307; CHECK-LABEL: struct_nonconstant_out_of_bounds_b: 308; CHECK: __stack_chk_guard 309define void @struct_nonconstant_out_of_bounds_b(i32 %n) #0 { 310 %var = alloca %struct.outer, align 4 311 %innergep = getelementptr inbounds %struct.inner, ptr %var, i32 %n, i32 0 312 store i32 0, ptr %innergep, align 4 313 ret void 314} 315 316; CHECK-LABEL: bitcast_smaller_load 317; CHECK-NOT: __stack_chk_guard 318define i32 @bitcast_smaller_load() #0 { 319 %var = alloca i64, align 4 320 store i64 0, ptr %var, align 4 321 %ret = load i32, ptr %var, align 4 322 ret i32 %ret 323} 324 325; CHECK-LABEL: bitcast_same_size_load 326; CHECK-NOT: __stack_chk_guard 327define i32 @bitcast_same_size_load() #0 { 328 %var = alloca i64, align 4 329 store i64 0, ptr %var, align 4 330 %gep = getelementptr inbounds %struct.inner, ptr %var, i32 0, i32 1 331 %ret = load i32, ptr %gep, align 4 332 ret i32 %ret 333} 334 335; CHECK-LABEL: bitcast_larger_load 336; CHECK: __stack_chk_guard 337define i64 @bitcast_larger_load() #0 { 338 %var = alloca i32, align 4 339 store i32 0, ptr %var, align 4 340 %ret = load i64, ptr %var, align 4 341 ret i64 %ret 342} 343 344; CHECK-LABEL: bitcast_larger_store 345; CHECK: __stack_chk_guard 346define i32 @bitcast_larger_store() #0 { 347 %var = alloca i32, align 4 348 store i64 0, ptr %var, align 4 349 %ret = load i32, ptr %var, align 4 350 ret i32 %ret 351} 352 353; CHECK-LABEL: bitcast_larger_cmpxchg 354; CHECK: __stack_chk_guard 355define i64 @bitcast_larger_cmpxchg(i64 %desired, i64 %new) #0 { 356 %var = alloca i32, align 4 357 %pair = cmpxchg ptr %var, i64 %desired, i64 %new seq_cst monotonic 358 %ret = extractvalue { i64, i1 } %pair, 0 359 ret i64 %ret 360} 361 362; CHECK-LABEL: bitcast_larger_atomic_rmw 363; CHECK: __stack_chk_guard 364define i64 @bitcast_larger_atomic_rmw() #0 { 365 %var = alloca i32, align 4 366 %ret = atomicrmw add ptr %var, i64 1 monotonic 367 ret i64 %ret 368} 369 370%struct.packed = type <{ i16, i32 }> 371 372; CHECK-LABEL: bitcast_overlap 373; CHECK: __stack_chk_guard 374define i32 @bitcast_overlap() #0 { 375 %var = alloca i32, align 4 376 %gep = getelementptr inbounds %struct.packed, ptr %var, i32 0, i32 1 377 %ret = load i32, ptr %gep, align 2 378 ret i32 %ret 379} 380 381%struct.multi_dimensional = type { [10 x [10 x i32]], i32 } 382 383; CHECK-LABEL: multi_dimensional_array 384; CHECK: __stack_chk_guard 385define i32 @multi_dimensional_array() #0 { 386 %var = alloca %struct.multi_dimensional, align 4 387 %gep2 = getelementptr inbounds [10 x [10 x i32]], ptr %var, i32 0, i32 10 388 %gep3 = getelementptr inbounds [10 x i32], ptr %gep2, i32 0, i32 5 389 %ret = load i32, ptr %gep3, align 4 390 ret i32 %ret 391} 392 393attributes #0 = { sspstrong } 394