1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --filter-out "(?!^\s*stl.*\bsp\b)^\s*.*\bsp\b" --filter "^\s*(ld[^r]|st|swp|cas|bl|add|and|eor|orn|orr|sub|mvn|sxt|cmp|ccmp|csel|dmb)" 2; RUN: llc %s -o - -verify-machineinstrs -mtriple=aarch64 -mattr=+v8.4a -mattr=+rcpc-immo -global-isel=true -global-isel-abort=2 -O0 | FileCheck %s --check-prefixes=CHECK,GISEL 3; RUN: llc %s -o - -verify-machineinstrs -mtriple=aarch64 -mattr=+v8.4a -mattr=+rcpc-immo -global-isel=false -O1 | FileCheck %s --check-prefixes=CHECK,SDAG 4 5define void @store_atomic_i8_aligned_unordered(i8 %value, ptr %ptr) { 6; CHECK-LABEL: store_atomic_i8_aligned_unordered: 7; CHECK: strb w0, [x1, #4] 8 %gep = getelementptr inbounds i8, ptr %ptr, i32 4 9 store atomic i8 %value, ptr %gep unordered, align 1 10 ret void 11} 12 13define void @store_atomic_i8_aligned_monotonic(i8 %value, ptr %ptr) { 14; CHECK-LABEL: store_atomic_i8_aligned_monotonic: 15; CHECK: strb w0, [x1, #4] 16 %gep = getelementptr inbounds i8, ptr %ptr, i32 4 17 store atomic i8 %value, ptr %gep monotonic, align 1 18 ret void 19} 20 21define void @store_atomic_i8_aligned_release(i8 %value, ptr %ptr) { 22; CHECK-LABEL: store_atomic_i8_aligned_release: 23; CHECK: stlurb w0, [x1, #4] 24 %gep = getelementptr inbounds i8, ptr %ptr, i32 4 25 store atomic i8 %value, ptr %gep release, align 1 26 ret void 27} 28 29define void @store_atomic_i8_aligned_seq_cst(i8 %value, ptr %ptr) { 30; CHECK-LABEL: store_atomic_i8_aligned_seq_cst: 31; CHECK: stlurb w0, [x1, #4] 32 %gep = getelementptr inbounds i8, ptr %ptr, i32 4 33 store atomic i8 %value, ptr %gep seq_cst, align 1 34 ret void 35} 36 37define void @store_atomic_i16_aligned_unordered(i16 %value, ptr %ptr) { 38; CHECK-LABEL: store_atomic_i16_aligned_unordered: 39; CHECK: strh w0, [x1, #8] 40 %gep = getelementptr inbounds i16, ptr %ptr, i32 4 41 store atomic i16 %value, ptr %gep unordered, align 2 42 ret void 43} 44 45define void @store_atomic_i16_aligned_monotonic(i16 %value, ptr %ptr) { 46; CHECK-LABEL: store_atomic_i16_aligned_monotonic: 47; CHECK: strh w0, [x1, #8] 48 %gep = getelementptr inbounds i16, ptr %ptr, i32 4 49 store atomic i16 %value, ptr %gep monotonic, align 2 50 ret void 51} 52 53define void @store_atomic_i16_aligned_release(i16 %value, ptr %ptr) { 54; CHECK-LABEL: store_atomic_i16_aligned_release: 55; CHECK: stlurh w0, [x1, #8] 56 %gep = getelementptr inbounds i16, ptr %ptr, i32 4 57 store atomic i16 %value, ptr %gep release, align 2 58 ret void 59} 60 61define void @store_atomic_i16_aligned_seq_cst(i16 %value, ptr %ptr) { 62; CHECK-LABEL: store_atomic_i16_aligned_seq_cst: 63; CHECK: stlurh w0, [x1, #8] 64 %gep = getelementptr inbounds i16, ptr %ptr, i32 4 65 store atomic i16 %value, ptr %gep seq_cst, align 2 66 ret void 67} 68 69define void @store_atomic_i32_aligned_unordered(i32 %value, ptr %ptr) { 70; CHECK-LABEL: store_atomic_i32_aligned_unordered: 71; CHECK: str w0, [x1, #16] 72 %gep = getelementptr inbounds i32, ptr %ptr, i32 4 73 store atomic i32 %value, ptr %gep unordered, align 4 74 ret void 75} 76 77define void @store_atomic_i32_aligned_monotonic(i32 %value, ptr %ptr) { 78; CHECK-LABEL: store_atomic_i32_aligned_monotonic: 79; CHECK: str w0, [x1, #16] 80 %gep = getelementptr inbounds i32, ptr %ptr, i32 4 81 store atomic i32 %value, ptr %gep monotonic, align 4 82 ret void 83} 84 85define void @store_atomic_i32_aligned_release(i32 %value, ptr %ptr) { 86; CHECK-LABEL: store_atomic_i32_aligned_release: 87; CHECK: stlur w0, [x1, #16] 88 %gep = getelementptr inbounds i32, ptr %ptr, i32 4 89 store atomic i32 %value, ptr %gep release, align 4 90 ret void 91} 92 93define void @store_atomic_i32_aligned_seq_cst(i32 %value, ptr %ptr) { 94; CHECK-LABEL: store_atomic_i32_aligned_seq_cst: 95; CHECK: stlur w0, [x1, #16] 96 %gep = getelementptr inbounds i32, ptr %ptr, i32 4 97 store atomic i32 %value, ptr %gep seq_cst, align 4 98 ret void 99} 100 101define void @store_atomic_i64_aligned_unordered(i64 %value, ptr %ptr) { 102; CHECK-LABEL: store_atomic_i64_aligned_unordered: 103; CHECK: str x0, [x1, #32] 104 %gep = getelementptr inbounds i64, ptr %ptr, i32 4 105 store atomic i64 %value, ptr %gep unordered, align 8 106 ret void 107} 108 109define void @store_atomic_i64_aligned_monotonic(i64 %value, ptr %ptr) { 110; CHECK-LABEL: store_atomic_i64_aligned_monotonic: 111; CHECK: str x0, [x1, #32] 112 %gep = getelementptr inbounds i64, ptr %ptr, i32 4 113 store atomic i64 %value, ptr %gep monotonic, align 8 114 ret void 115} 116 117define void @store_atomic_i64_aligned_release(i64 %value, ptr %ptr) { 118; CHECK-LABEL: store_atomic_i64_aligned_release: 119; CHECK: stlur x0, [x1, #32] 120 %gep = getelementptr inbounds i64, ptr %ptr, i32 4 121 store atomic i64 %value, ptr %gep release, align 8 122 ret void 123} 124 125define void @store_atomic_i64_aligned_seq_cst(i64 %value, ptr %ptr) { 126; CHECK-LABEL: store_atomic_i64_aligned_seq_cst: 127; CHECK: stlur x0, [x1, #32] 128 %gep = getelementptr inbounds i64, ptr %ptr, i32 4 129 store atomic i64 %value, ptr %gep seq_cst, align 8 130 ret void 131} 132 133define void @store_atomic_i128_aligned_unordered(i128 %value, ptr %ptr) { 134; CHECK-LABEL: store_atomic_i128_aligned_unordered: 135; CHECK: stp x0, x1, [x2, #64] 136 %gep = getelementptr inbounds i128, ptr %ptr, i32 4 137 store atomic i128 %value, ptr %gep unordered, align 16 138 ret void 139} 140 141define void @store_atomic_i128_aligned_monotonic(i128 %value, ptr %ptr) { 142; CHECK-LABEL: store_atomic_i128_aligned_monotonic: 143; CHECK: stp x0, x1, [x2, #64] 144 %gep = getelementptr inbounds i128, ptr %ptr, i32 4 145 store atomic i128 %value, ptr %gep monotonic, align 16 146 ret void 147} 148 149define void @store_atomic_i128_aligned_release(i128 %value, ptr %ptr) { 150; CHECK-LABEL: store_atomic_i128_aligned_release: 151; CHECK: dmb ish 152; CHECK: stp x0, x1, [x2, #64] 153 %gep = getelementptr inbounds i128, ptr %ptr, i32 4 154 store atomic i128 %value, ptr %gep release, align 16 155 ret void 156} 157 158define void @store_atomic_i128_aligned_seq_cst(i128 %value, ptr %ptr) { 159; CHECK-LABEL: store_atomic_i128_aligned_seq_cst: 160; CHECK: dmb ish 161; CHECK: stp x0, x1, [x2, #64] 162; CHECK: dmb ish 163 %gep = getelementptr inbounds i128, ptr %ptr, i32 4 164 store atomic i128 %value, ptr %gep seq_cst, align 16 165 ret void 166} 167 168define void @store_atomic_i8_unaligned_unordered(i8 %value, ptr %ptr) { 169; CHECK-LABEL: store_atomic_i8_unaligned_unordered: 170; CHECK: strb w0, [x1, #4] 171 %gep = getelementptr inbounds i8, ptr %ptr, i32 4 172 store atomic i8 %value, ptr %gep unordered, align 1 173 ret void 174} 175 176define void @store_atomic_i8_unaligned_monotonic(i8 %value, ptr %ptr) { 177; CHECK-LABEL: store_atomic_i8_unaligned_monotonic: 178; CHECK: strb w0, [x1, #4] 179 %gep = getelementptr inbounds i8, ptr %ptr, i32 4 180 store atomic i8 %value, ptr %gep monotonic, align 1 181 ret void 182} 183 184define void @store_atomic_i8_unaligned_release(i8 %value, ptr %ptr) { 185; CHECK-LABEL: store_atomic_i8_unaligned_release: 186; CHECK: stlurb w0, [x1, #4] 187 %gep = getelementptr inbounds i8, ptr %ptr, i32 4 188 store atomic i8 %value, ptr %gep release, align 1 189 ret void 190} 191 192define void @store_atomic_i8_unaligned_seq_cst(i8 %value, ptr %ptr) { 193; CHECK-LABEL: store_atomic_i8_unaligned_seq_cst: 194; CHECK: stlurb w0, [x1, #4] 195 %gep = getelementptr inbounds i8, ptr %ptr, i32 4 196 store atomic i8 %value, ptr %gep seq_cst, align 1 197 ret void 198} 199 200define void @store_atomic_i16_unaligned_unordered(i16 %value, ptr %ptr) { 201; CHECK-LABEL: store_atomic_i16_unaligned_unordered: 202; CHECK: add x1, x1, #8 203; CHECK: bl __atomic_store 204 %gep = getelementptr inbounds i16, ptr %ptr, i32 4 205 store atomic i16 %value, ptr %gep unordered, align 1 206 ret void 207} 208 209define void @store_atomic_i16_unaligned_monotonic(i16 %value, ptr %ptr) { 210; CHECK-LABEL: store_atomic_i16_unaligned_monotonic: 211; CHECK: add x1, x1, #8 212; CHECK: bl __atomic_store 213 %gep = getelementptr inbounds i16, ptr %ptr, i32 4 214 store atomic i16 %value, ptr %gep monotonic, align 1 215 ret void 216} 217 218define void @store_atomic_i16_unaligned_release(i16 %value, ptr %ptr) { 219; CHECK-LABEL: store_atomic_i16_unaligned_release: 220; CHECK: add x1, x1, #8 221; CHECK: bl __atomic_store 222 %gep = getelementptr inbounds i16, ptr %ptr, i32 4 223 store atomic i16 %value, ptr %gep release, align 1 224 ret void 225} 226 227define void @store_atomic_i16_unaligned_seq_cst(i16 %value, ptr %ptr) { 228; CHECK-LABEL: store_atomic_i16_unaligned_seq_cst: 229; CHECK: add x1, x1, #8 230; CHECK: bl __atomic_store 231 %gep = getelementptr inbounds i16, ptr %ptr, i32 4 232 store atomic i16 %value, ptr %gep seq_cst, align 1 233 ret void 234} 235 236define void @store_atomic_i32_unaligned_unordered(i32 %value, ptr %ptr) { 237; CHECK-LABEL: store_atomic_i32_unaligned_unordered: 238; CHECK: add x1, x1, #16 239; CHECK: bl __atomic_store 240 %gep = getelementptr inbounds i32, ptr %ptr, i32 4 241 store atomic i32 %value, ptr %gep unordered, align 1 242 ret void 243} 244 245define void @store_atomic_i32_unaligned_monotonic(i32 %value, ptr %ptr) { 246; CHECK-LABEL: store_atomic_i32_unaligned_monotonic: 247; CHECK: add x1, x1, #16 248; CHECK: bl __atomic_store 249 %gep = getelementptr inbounds i32, ptr %ptr, i32 4 250 store atomic i32 %value, ptr %gep monotonic, align 1 251 ret void 252} 253 254define void @store_atomic_i32_unaligned_release(i32 %value, ptr %ptr) { 255; CHECK-LABEL: store_atomic_i32_unaligned_release: 256; CHECK: add x1, x1, #16 257; CHECK: bl __atomic_store 258 %gep = getelementptr inbounds i32, ptr %ptr, i32 4 259 store atomic i32 %value, ptr %gep release, align 1 260 ret void 261} 262 263define void @store_atomic_i32_unaligned_seq_cst(i32 %value, ptr %ptr) { 264; CHECK-LABEL: store_atomic_i32_unaligned_seq_cst: 265; CHECK: add x1, x1, #16 266; CHECK: bl __atomic_store 267 %gep = getelementptr inbounds i32, ptr %ptr, i32 4 268 store atomic i32 %value, ptr %gep seq_cst, align 1 269 ret void 270} 271 272define void @store_atomic_i64_unaligned_unordered(i64 %value, ptr %ptr) { 273; CHECK-LABEL: store_atomic_i64_unaligned_unordered: 274; CHECK: add x1, x1, #32 275; CHECK: bl __atomic_store 276 %gep = getelementptr inbounds i64, ptr %ptr, i32 4 277 store atomic i64 %value, ptr %gep unordered, align 1 278 ret void 279} 280 281define void @store_atomic_i64_unaligned_monotonic(i64 %value, ptr %ptr) { 282; CHECK-LABEL: store_atomic_i64_unaligned_monotonic: 283; CHECK: add x1, x1, #32 284; CHECK: bl __atomic_store 285 %gep = getelementptr inbounds i64, ptr %ptr, i32 4 286 store atomic i64 %value, ptr %gep monotonic, align 1 287 ret void 288} 289 290define void @store_atomic_i64_unaligned_release(i64 %value, ptr %ptr) { 291; CHECK-LABEL: store_atomic_i64_unaligned_release: 292; CHECK: add x1, x1, #32 293; CHECK: bl __atomic_store 294 %gep = getelementptr inbounds i64, ptr %ptr, i32 4 295 store atomic i64 %value, ptr %gep release, align 1 296 ret void 297} 298 299define void @store_atomic_i64_unaligned_seq_cst(i64 %value, ptr %ptr) { 300; CHECK-LABEL: store_atomic_i64_unaligned_seq_cst: 301; CHECK: add x1, x1, #32 302; CHECK: bl __atomic_store 303 %gep = getelementptr inbounds i64, ptr %ptr, i32 4 304 store atomic i64 %value, ptr %gep seq_cst, align 1 305 ret void 306} 307 308define void @store_atomic_i128_unaligned_unordered(i128 %value, ptr %ptr) { 309; GISEL-LABEL: store_atomic_i128_unaligned_unordered: 310; GISEL: add x1, x8, #64 311; GISEL: bl __atomic_store 312; 313; SDAG-LABEL: store_atomic_i128_unaligned_unordered: 314; SDAG: add x1, x2, #64 315; SDAG: bl __atomic_store 316 %gep = getelementptr inbounds i128, ptr %ptr, i32 4 317 store atomic i128 %value, ptr %gep unordered, align 1 318 ret void 319} 320 321define void @store_atomic_i128_unaligned_monotonic(i128 %value, ptr %ptr) { 322; GISEL-LABEL: store_atomic_i128_unaligned_monotonic: 323; GISEL: add x1, x8, #64 324; GISEL: bl __atomic_store 325; 326; SDAG-LABEL: store_atomic_i128_unaligned_monotonic: 327; SDAG: add x1, x2, #64 328; SDAG: bl __atomic_store 329 %gep = getelementptr inbounds i128, ptr %ptr, i32 4 330 store atomic i128 %value, ptr %gep monotonic, align 1 331 ret void 332} 333 334define void @store_atomic_i128_unaligned_release(i128 %value, ptr %ptr) { 335; GISEL-LABEL: store_atomic_i128_unaligned_release: 336; GISEL: add x1, x8, #64 337; GISEL: bl __atomic_store 338; 339; SDAG-LABEL: store_atomic_i128_unaligned_release: 340; SDAG: add x1, x2, #64 341; SDAG: bl __atomic_store 342 %gep = getelementptr inbounds i128, ptr %ptr, i32 4 343 store atomic i128 %value, ptr %gep release, align 1 344 ret void 345} 346 347define void @store_atomic_i128_unaligned_seq_cst(i128 %value, ptr %ptr) { 348; GISEL-LABEL: store_atomic_i128_unaligned_seq_cst: 349; GISEL: add x1, x8, #64 350; GISEL: bl __atomic_store 351; 352; SDAG-LABEL: store_atomic_i128_unaligned_seq_cst: 353; SDAG: add x1, x2, #64 354; SDAG: bl __atomic_store 355 %gep = getelementptr inbounds i128, ptr %ptr, i32 4 356 store atomic i128 %value, ptr %gep seq_cst, align 1 357 ret void 358} 359 360; TODO: missed opportunity to emit a stlurb w/ GISel 361define void @store_atomic_i8_from_gep() { 362; GISEL-LABEL: store_atomic_i8_from_gep: 363; GISEL: bl init 364; GISEL: add x9, x8, #1 365; GISEL: stlrb w8, [x9] 366; 367; SDAG-LABEL: store_atomic_i8_from_gep: 368; SDAG: bl init 369; SDAG: stlurb wzr, [sp, #13] 370 %a = alloca [3 x i8] 371 call void @init(ptr %a) 372 %arrayidx = getelementptr [3 x i8], ptr %a, i64 0, i64 1 373 store atomic i8 0, ptr %arrayidx release, align 8 374 ret void 375} 376 377; TODO: missed opportunity to emit a stlurh w/ GISel 378define void @store_atomic_i16_from_gep() { 379; GISEL-LABEL: store_atomic_i16_from_gep: 380; GISEL: bl init 381; GISEL: add x9, x8, #2 382; GISEL: stlrh w8, [x9] 383; 384; SDAG-LABEL: store_atomic_i16_from_gep: 385; SDAG: bl init 386; SDAG: stlurh wzr, [sp, #10] 387 %a = alloca [3 x i16] 388 call void @init(ptr %a) 389 %arrayidx = getelementptr [3 x i16], ptr %a, i64 0, i64 1 390 store atomic i16 0, ptr %arrayidx release, align 8 391 ret void 392} 393 394define void @store_atomic_i32_from_gep() { 395; GISEL-LABEL: store_atomic_i32_from_gep: 396; GISEL: bl init 397; GISEL: stlur w8, [x9, #4] 398; 399; SDAG-LABEL: store_atomic_i32_from_gep: 400; SDAG: bl init 401; SDAG: stlur wzr, [sp, #8] 402 %a = alloca [3 x i32] 403 call void @init(ptr %a) 404 %arrayidx = getelementptr [3 x i32], ptr %a, i64 0, i64 1 405 store atomic i32 0, ptr %arrayidx release, align 8 406 ret void 407} 408 409define void @store_atomic_i64_from_gep() { 410; GISEL-LABEL: store_atomic_i64_from_gep: 411; GISEL: bl init 412; GISEL: stlur x8, [x9, #8] 413; 414; SDAG-LABEL: store_atomic_i64_from_gep: 415; SDAG: bl init 416; SDAG: stlur xzr, [sp, #16] 417 %a = alloca [3 x i64] 418 call void @init(ptr %a) 419 %arrayidx = getelementptr [3 x i64], ptr %a, i64 0, i64 1 420 store atomic i64 0, ptr %arrayidx release, align 8 421 ret void 422} 423 424define void @store_atomic_i128_from_gep() { 425; GISEL-LABEL: store_atomic_i128_from_gep: 426; GISEL: bl init 427; GISEL: dmb ish 428; GISEL: stp x8, x8, [x9, #16] 429; 430; SDAG-LABEL: store_atomic_i128_from_gep: 431; SDAG: bl init 432; SDAG: dmb ish 433; SDAG: stp xzr, xzr, [sp, #16] 434 %a = alloca [3 x i128] 435 call void @init(ptr %a) 436 %arrayidx = getelementptr [3 x i128], ptr %a, i64 0, i64 1 437 store atomic i128 0, ptr %arrayidx release, align 16 438 ret void 439} 440 441declare void @init(ptr) 442