1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s -check-prefixes=ARM 3; RUN: llc < %s -mtriple=armv7-apple-ios -O0 | FileCheck %s -check-prefix=ARMOPTNONE 4; RUN: llc < %s -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s -check-prefix=THUMBTWO 5; RUN: llc < %s -mtriple=thumbv6 | FileCheck %s -check-prefix=THUMBONE 6; RUN: llc < %s -mtriple=armv4 | FileCheck %s -check-prefix=ARMV4 7; RUN: llc < %s -mtriple=armv6 | FileCheck %s -check-prefix=ARMV6 8; RUN: llc < %s -mtriple=thumbv7m | FileCheck %s -check-prefix=THUMBM 9 10define void @test1(i32* %ptr, i32 %val1) { 11; ARM-LABEL: test1: 12; ARM: @ %bb.0: 13; ARM-NEXT: dmb ish 14; ARM-NEXT: str r1, [r0] 15; ARM-NEXT: dmb ish 16; ARM-NEXT: bx lr 17; 18; ARMOPTNONE-LABEL: test1: 19; ARMOPTNONE: @ %bb.0: 20; ARMOPTNONE-NEXT: dmb ish 21; ARMOPTNONE-NEXT: str r1, [r0] 22; ARMOPTNONE-NEXT: dmb ish 23; ARMOPTNONE-NEXT: bx lr 24; 25; THUMBTWO-LABEL: test1: 26; THUMBTWO: @ %bb.0: 27; THUMBTWO-NEXT: dmb ish 28; THUMBTWO-NEXT: str r1, [r0] 29; THUMBTWO-NEXT: dmb ish 30; THUMBTWO-NEXT: bx lr 31; 32; THUMBONE-LABEL: test1: 33; THUMBONE: @ %bb.0: 34; THUMBONE-NEXT: push {r7, lr} 35; THUMBONE-NEXT: bl __sync_lock_test_and_set_4 36; THUMBONE-NEXT: pop {r7, pc} 37; 38; ARMV4-LABEL: test1: 39; ARMV4: @ %bb.0: 40; ARMV4-NEXT: push {r11, lr} 41; ARMV4-NEXT: mov r2, #5 42; ARMV4-NEXT: bl __atomic_store_4 43; ARMV4-NEXT: pop {r11, lr} 44; ARMV4-NEXT: mov pc, lr 45; 46; ARMV6-LABEL: test1: 47; ARMV6: @ %bb.0: 48; ARMV6-NEXT: mov r2, #0 49; ARMV6-NEXT: mcr p15, #0, r2, c7, c10, #5 50; ARMV6-NEXT: str r1, [r0] 51; ARMV6-NEXT: mcr p15, #0, r2, c7, c10, #5 52; ARMV6-NEXT: bx lr 53; 54; THUMBM-LABEL: test1: 55; THUMBM: @ %bb.0: 56; THUMBM-NEXT: dmb sy 57; THUMBM-NEXT: str r1, [r0] 58; THUMBM-NEXT: dmb sy 59; THUMBM-NEXT: bx lr 60 store atomic i32 %val1, i32* %ptr seq_cst, align 4 61 ret void 62} 63 64define i32 @test2(i32* %ptr) { 65; ARM-LABEL: test2: 66; ARM: @ %bb.0: 67; ARM-NEXT: ldr r0, [r0] 68; ARM-NEXT: dmb ish 69; ARM-NEXT: bx lr 70; 71; ARMOPTNONE-LABEL: test2: 72; ARMOPTNONE: @ %bb.0: 73; ARMOPTNONE-NEXT: ldr r0, [r0] 74; ARMOPTNONE-NEXT: dmb ish 75; ARMOPTNONE-NEXT: bx lr 76; 77; THUMBTWO-LABEL: test2: 78; THUMBTWO: @ %bb.0: 79; THUMBTWO-NEXT: ldr r0, [r0] 80; THUMBTWO-NEXT: dmb ish 81; THUMBTWO-NEXT: bx lr 82; 83; THUMBONE-LABEL: test2: 84; THUMBONE: @ %bb.0: 85; THUMBONE-NEXT: push {r7, lr} 86; THUMBONE-NEXT: movs r1, #0 87; THUMBONE-NEXT: mov r2, r1 88; THUMBONE-NEXT: bl __sync_val_compare_and_swap_4 89; THUMBONE-NEXT: pop {r7, pc} 90; 91; ARMV4-LABEL: test2: 92; ARMV4: @ %bb.0: 93; ARMV4-NEXT: push {r11, lr} 94; ARMV4-NEXT: mov r1, #5 95; ARMV4-NEXT: bl __atomic_load_4 96; ARMV4-NEXT: pop {r11, lr} 97; ARMV4-NEXT: mov pc, lr 98; 99; ARMV6-LABEL: test2: 100; ARMV6: @ %bb.0: 101; ARMV6-NEXT: ldr r0, [r0] 102; ARMV6-NEXT: mov r1, #0 103; ARMV6-NEXT: mcr p15, #0, r1, c7, c10, #5 104; ARMV6-NEXT: bx lr 105; 106; THUMBM-LABEL: test2: 107; THUMBM: @ %bb.0: 108; THUMBM-NEXT: ldr r0, [r0] 109; THUMBM-NEXT: dmb sy 110; THUMBM-NEXT: bx lr 111 %val = load atomic i32, i32* %ptr seq_cst, align 4 112 ret i32 %val 113} 114 115define void @test3(i8* %ptr1, i8* %ptr2) { 116; ARM-LABEL: test3: 117; ARM: @ %bb.0: 118; ARM-NEXT: ldrb r0, [r0] 119; ARM-NEXT: strb r0, [r1] 120; ARM-NEXT: bx lr 121; 122; ARMOPTNONE-LABEL: test3: 123; ARMOPTNONE: @ %bb.0: 124; ARMOPTNONE-NEXT: ldrb r0, [r0] 125; ARMOPTNONE-NEXT: strb r0, [r1] 126; ARMOPTNONE-NEXT: bx lr 127; 128; THUMBTWO-LABEL: test3: 129; THUMBTWO: @ %bb.0: 130; THUMBTWO-NEXT: ldrb r0, [r0] 131; THUMBTWO-NEXT: strb r0, [r1] 132; THUMBTWO-NEXT: bx lr 133; 134; THUMBONE-LABEL: test3: 135; THUMBONE: @ %bb.0: 136; THUMBONE-NEXT: ldrb r0, [r0] 137; THUMBONE-NEXT: strb r0, [r1] 138; THUMBONE-NEXT: bx lr 139; 140; ARMV4-LABEL: test3: 141; ARMV4: @ %bb.0: 142; ARMV4-NEXT: push {r4, lr} 143; ARMV4-NEXT: mov r4, r1 144; ARMV4-NEXT: mov r1, #0 145; ARMV4-NEXT: bl __atomic_load_1 146; ARMV4-NEXT: mov r1, r0 147; ARMV4-NEXT: mov r0, r4 148; ARMV4-NEXT: mov r2, #0 149; ARMV4-NEXT: bl __atomic_store_1 150; ARMV4-NEXT: pop {r4, lr} 151; ARMV4-NEXT: mov pc, lr 152; 153; ARMV6-LABEL: test3: 154; ARMV6: @ %bb.0: 155; ARMV6-NEXT: ldrb r0, [r0] 156; ARMV6-NEXT: strb r0, [r1] 157; ARMV6-NEXT: bx lr 158; 159; THUMBM-LABEL: test3: 160; THUMBM: @ %bb.0: 161; THUMBM-NEXT: ldrb r0, [r0] 162; THUMBM-NEXT: strb r0, [r1] 163; THUMBM-NEXT: bx lr 164 165 166 167 %val = load atomic i8, i8* %ptr1 unordered, align 1 168 store atomic i8 %val, i8* %ptr2 unordered, align 1 169 ret void 170} 171 172define void @test4(i8* %ptr1, i8* %ptr2) { 173; ARM-LABEL: test4: 174; ARM: @ %bb.0: 175; ARM-NEXT: ldrb r0, [r0] 176; ARM-NEXT: dmb ish 177; ARM-NEXT: strb r0, [r1] 178; ARM-NEXT: dmb ish 179; ARM-NEXT: bx lr 180; 181; ARMOPTNONE-LABEL: test4: 182; ARMOPTNONE: @ %bb.0: 183; ARMOPTNONE-NEXT: ldrb r0, [r0] 184; ARMOPTNONE-NEXT: dmb ish 185; ARMOPTNONE-NEXT: dmb ish 186; ARMOPTNONE-NEXT: strb r0, [r1] 187; ARMOPTNONE-NEXT: dmb ish 188; ARMOPTNONE-NEXT: bx lr 189; 190; THUMBTWO-LABEL: test4: 191; THUMBTWO: @ %bb.0: 192; THUMBTWO-NEXT: ldrb r0, [r0] 193; THUMBTWO-NEXT: dmb ish 194; THUMBTWO-NEXT: dmb ish 195; THUMBTWO-NEXT: strb r0, [r1] 196; THUMBTWO-NEXT: dmb ish 197; THUMBTWO-NEXT: bx lr 198; 199; THUMBONE-LABEL: test4: 200; THUMBONE: @ %bb.0: 201; THUMBONE-NEXT: push {r4, lr} 202; THUMBONE-NEXT: mov r4, r1 203; THUMBONE-NEXT: movs r1, #0 204; THUMBONE-NEXT: mov r2, r1 205; THUMBONE-NEXT: bl __sync_val_compare_and_swap_1 206; THUMBONE-NEXT: mov r1, r0 207; THUMBONE-NEXT: mov r0, r4 208; THUMBONE-NEXT: bl __sync_lock_test_and_set_1 209; THUMBONE-NEXT: pop {r4, pc} 210; 211; ARMV4-LABEL: test4: 212; ARMV4: @ %bb.0: 213; ARMV4-NEXT: push {r4, lr} 214; ARMV4-NEXT: mov r4, r1 215; ARMV4-NEXT: mov r1, #5 216; ARMV4-NEXT: bl __atomic_load_1 217; ARMV4-NEXT: mov r1, r0 218; ARMV4-NEXT: mov r0, r4 219; ARMV4-NEXT: mov r2, #5 220; ARMV4-NEXT: bl __atomic_store_1 221; ARMV4-NEXT: pop {r4, lr} 222; ARMV4-NEXT: mov pc, lr 223; 224; ARMV6-LABEL: test4: 225; ARMV6: @ %bb.0: 226; ARMV6-NEXT: mov r2, #0 227; ARMV6-NEXT: ldrb r0, [r0] 228; ARMV6-NEXT: mcr p15, #0, r2, c7, c10, #5 229; ARMV6-NEXT: mcr p15, #0, r2, c7, c10, #5 230; ARMV6-NEXT: strb r0, [r1] 231; ARMV6-NEXT: mcr p15, #0, r2, c7, c10, #5 232; ARMV6-NEXT: bx lr 233; 234; THUMBM-LABEL: test4: 235; THUMBM: @ %bb.0: 236; THUMBM-NEXT: ldrb r0, [r0] 237; THUMBM-NEXT: dmb sy 238; THUMBM-NEXT: dmb sy 239; THUMBM-NEXT: strb r0, [r1] 240; THUMBM-NEXT: dmb sy 241; THUMBM-NEXT: bx lr 242 %val = load atomic i8, i8* %ptr1 seq_cst, align 1 243 store atomic i8 %val, i8* %ptr2 seq_cst, align 1 244 ret void 245} 246 247define i64 @test_old_load_64bit(i64* %p) { 248; ARM-LABEL: test_old_load_64bit: 249; ARM: @ %bb.0: 250; ARM-NEXT: ldrexd r0, r1, [r0] 251; ARM-NEXT: clrex 252; ARM-NEXT: dmb ish 253; ARM-NEXT: bx lr 254; 255; ARMOPTNONE-LABEL: test_old_load_64bit: 256; ARMOPTNONE: @ %bb.0: 257; ARMOPTNONE-NEXT: ldrexd r2, r3, [r0] 258; ARMOPTNONE-NEXT: mov r0, r2 259; ARMOPTNONE-NEXT: mov r1, r3 260; ARMOPTNONE-NEXT: clrex 261; ARMOPTNONE-NEXT: dmb ish 262; ARMOPTNONE-NEXT: bx lr 263; 264; THUMBTWO-LABEL: test_old_load_64bit: 265; THUMBTWO: @ %bb.0: 266; THUMBTWO-NEXT: ldrexd r0, r1, [r0] 267; THUMBTWO-NEXT: clrex 268; THUMBTWO-NEXT: dmb ish 269; THUMBTWO-NEXT: bx lr 270; 271; THUMBONE-LABEL: test_old_load_64bit: 272; THUMBONE: @ %bb.0: 273; THUMBONE-NEXT: push {r7, lr} 274; THUMBONE-NEXT: sub sp, #8 275; THUMBONE-NEXT: movs r2, #0 276; THUMBONE-NEXT: str r2, [sp] 277; THUMBONE-NEXT: str r2, [sp, #4] 278; THUMBONE-NEXT: mov r3, r2 279; THUMBONE-NEXT: bl __sync_val_compare_and_swap_8 280; THUMBONE-NEXT: add sp, #8 281; THUMBONE-NEXT: pop {r7, pc} 282; 283; ARMV4-LABEL: test_old_load_64bit: 284; ARMV4: @ %bb.0: 285; ARMV4-NEXT: push {r11, lr} 286; ARMV4-NEXT: mov r1, #5 287; ARMV4-NEXT: bl __atomic_load_8 288; ARMV4-NEXT: pop {r11, lr} 289; ARMV4-NEXT: mov pc, lr 290; 291; ARMV6-LABEL: test_old_load_64bit: 292; ARMV6: @ %bb.0: 293; ARMV6-NEXT: ldrexd r0, r1, [r0] 294; ARMV6-NEXT: mov r2, #0 295; ARMV6-NEXT: mcr p15, #0, r2, c7, c10, #5 296; ARMV6-NEXT: bx lr 297; 298; THUMBM-LABEL: test_old_load_64bit: 299; THUMBM: @ %bb.0: 300; THUMBM-NEXT: push {r7, lr} 301; THUMBM-NEXT: movs r1, #5 302; THUMBM-NEXT: bl __atomic_load_8 303; THUMBM-NEXT: pop {r7, pc} 304 %1 = load atomic i64, i64* %p seq_cst, align 8 305 ret i64 %1 306} 307 308define void @test_old_store_64bit(i64* %p, i64 %v) { 309; ARM-LABEL: test_old_store_64bit: 310; ARM: @ %bb.0: 311; ARM-NEXT: push {r4, r5, lr} 312; ARM-NEXT: mov r3, r2 313; ARM-NEXT: dmb ish 314; ARM-NEXT: mov r2, r1 315; ARM-NEXT: LBB5_1: @ %atomicrmw.start 316; ARM-NEXT: @ =>This Inner Loop Header: Depth=1 317; ARM-NEXT: ldrexd r4, r5, [r0] 318; ARM-NEXT: strexd r1, r2, r3, [r0] 319; ARM-NEXT: cmp r1, #0 320; ARM-NEXT: bne LBB5_1 321; ARM-NEXT: @ %bb.2: @ %atomicrmw.end 322; ARM-NEXT: dmb ish 323; ARM-NEXT: pop {r4, r5, pc} 324; 325; ARMOPTNONE-LABEL: test_old_store_64bit: 326; ARMOPTNONE: @ %bb.0: 327; ARMOPTNONE-NEXT: push {r4, r5, r7, lr} 328; ARMOPTNONE-NEXT: add r7, sp, #8 329; ARMOPTNONE-NEXT: push {r8, r10, r11} 330; ARMOPTNONE-NEXT: sub sp, sp, #20 331; ARMOPTNONE-NEXT: str r0, [sp] @ 4-byte Spill 332; ARMOPTNONE-NEXT: str r2, [sp, #4] @ 4-byte Spill 333; ARMOPTNONE-NEXT: str r1, [sp, #8] @ 4-byte Spill 334; ARMOPTNONE-NEXT: dmb ish 335; ARMOPTNONE-NEXT: ldr r1, [r0] 336; ARMOPTNONE-NEXT: ldr r0, [r0, #4] 337; ARMOPTNONE-NEXT: str r1, [sp, #12] @ 4-byte Spill 338; ARMOPTNONE-NEXT: str r0, [sp, #16] @ 4-byte Spill 339; ARMOPTNONE-NEXT: b LBB5_1 340; ARMOPTNONE-NEXT: LBB5_1: @ %atomicrmw.start 341; ARMOPTNONE-NEXT: @ =>This Loop Header: Depth=1 342; ARMOPTNONE-NEXT: @ Child Loop BB5_2 Depth 2 343; ARMOPTNONE-NEXT: ldr r1, [sp, #16] @ 4-byte Reload 344; ARMOPTNONE-NEXT: ldr r2, [sp, #12] @ 4-byte Reload 345; ARMOPTNONE-NEXT: ldr r3, [sp] @ 4-byte Reload 346; ARMOPTNONE-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 347; ARMOPTNONE-NEXT: ldr r10, [sp, #8] @ 4-byte Reload 348; ARMOPTNONE-NEXT: @ kill: def $r10 killed $r10 def $r10_r11 349; ARMOPTNONE-NEXT: mov r11, r0 350; ARMOPTNONE-NEXT: mov r8, r2 351; ARMOPTNONE-NEXT: mov r9, r1 352; ARMOPTNONE-NEXT: LBB5_2: @ %atomicrmw.start 353; ARMOPTNONE-NEXT: @ Parent Loop BB5_1 Depth=1 354; ARMOPTNONE-NEXT: @ => This Inner Loop Header: Depth=2 355; ARMOPTNONE-NEXT: ldrexd r4, r5, [r3] 356; ARMOPTNONE-NEXT: cmp r4, r8 357; ARMOPTNONE-NEXT: cmpeq r5, r9 358; ARMOPTNONE-NEXT: bne LBB5_4 359; ARMOPTNONE-NEXT: @ %bb.3: @ %atomicrmw.start 360; ARMOPTNONE-NEXT: @ in Loop: Header=BB5_2 Depth=2 361; ARMOPTNONE-NEXT: strexd r0, r10, r11, [r3] 362; ARMOPTNONE-NEXT: cmp r0, #0 363; ARMOPTNONE-NEXT: bne LBB5_2 364; ARMOPTNONE-NEXT: LBB5_4: @ %atomicrmw.start 365; ARMOPTNONE-NEXT: @ in Loop: Header=BB5_1 Depth=1 366; ARMOPTNONE-NEXT: mov r0, r5 367; ARMOPTNONE-NEXT: eor r3, r0, r1 368; ARMOPTNONE-NEXT: mov r1, r4 369; ARMOPTNONE-NEXT: eor r2, r1, r2 370; ARMOPTNONE-NEXT: orr r2, r2, r3 371; ARMOPTNONE-NEXT: cmp r2, #0 372; ARMOPTNONE-NEXT: str r1, [sp, #12] @ 4-byte Spill 373; ARMOPTNONE-NEXT: str r0, [sp, #16] @ 4-byte Spill 374; ARMOPTNONE-NEXT: bne LBB5_1 375; ARMOPTNONE-NEXT: b LBB5_5 376; ARMOPTNONE-NEXT: LBB5_5: @ %atomicrmw.end 377; ARMOPTNONE-NEXT: dmb ish 378; ARMOPTNONE-NEXT: sub sp, r7, #20 379; ARMOPTNONE-NEXT: pop {r8, r10, r11} 380; ARMOPTNONE-NEXT: pop {r4, r5, r7, pc} 381; 382; THUMBTWO-LABEL: test_old_store_64bit: 383; THUMBTWO: @ %bb.0: 384; THUMBTWO-NEXT: dmb ish 385; THUMBTWO-NEXT: LBB5_1: @ %atomicrmw.start 386; THUMBTWO-NEXT: @ =>This Inner Loop Header: Depth=1 387; THUMBTWO-NEXT: ldrexd r3, r9, [r0] 388; THUMBTWO-NEXT: strexd r3, r1, r2, [r0] 389; THUMBTWO-NEXT: cmp r3, #0 390; THUMBTWO-NEXT: bne LBB5_1 391; THUMBTWO-NEXT: @ %bb.2: @ %atomicrmw.end 392; THUMBTWO-NEXT: dmb ish 393; THUMBTWO-NEXT: bx lr 394; 395; THUMBONE-LABEL: test_old_store_64bit: 396; THUMBONE: @ %bb.0: 397; THUMBONE-NEXT: push {r7, lr} 398; THUMBONE-NEXT: bl __sync_lock_test_and_set_8 399; THUMBONE-NEXT: pop {r7, pc} 400; 401; ARMV4-LABEL: test_old_store_64bit: 402; ARMV4: @ %bb.0: 403; ARMV4-NEXT: push {r11, lr} 404; ARMV4-NEXT: sub sp, sp, #8 405; ARMV4-NEXT: mov r1, #5 406; ARMV4-NEXT: str r1, [sp] 407; ARMV4-NEXT: bl __atomic_store_8 408; ARMV4-NEXT: add sp, sp, #8 409; ARMV4-NEXT: pop {r11, lr} 410; ARMV4-NEXT: mov pc, lr 411; 412; ARMV6-LABEL: test_old_store_64bit: 413; ARMV6: @ %bb.0: 414; ARMV6-NEXT: push {r4, r5, r11, lr} 415; ARMV6-NEXT: @ kill: def $r3 killed $r3 killed $r2_r3 def $r2_r3 416; ARMV6-NEXT: mov r1, #0 417; ARMV6-NEXT: @ kill: def $r2 killed $r2 killed $r2_r3 def $r2_r3 418; ARMV6-NEXT: mcr p15, #0, r1, c7, c10, #5 419; ARMV6-NEXT: .LBB5_1: @ %atomicrmw.start 420; ARMV6-NEXT: @ =>This Inner Loop Header: Depth=1 421; ARMV6-NEXT: ldrexd r4, r5, [r0] 422; ARMV6-NEXT: strexd r1, r2, r3, [r0] 423; ARMV6-NEXT: cmp r1, #0 424; ARMV6-NEXT: bne .LBB5_1 425; ARMV6-NEXT: @ %bb.2: @ %atomicrmw.end 426; ARMV6-NEXT: mov r0, #0 427; ARMV6-NEXT: mcr p15, #0, r0, c7, c10, #5 428; ARMV6-NEXT: pop {r4, r5, r11, pc} 429; 430; THUMBM-LABEL: test_old_store_64bit: 431; THUMBM: @ %bb.0: 432; THUMBM-NEXT: push {r7, lr} 433; THUMBM-NEXT: sub sp, #8 434; THUMBM-NEXT: movs r1, #5 435; THUMBM-NEXT: str r1, [sp] 436; THUMBM-NEXT: bl __atomic_store_8 437; THUMBM-NEXT: add sp, #8 438; THUMBM-NEXT: pop {r7, pc} 439 store atomic i64 %v, i64* %p seq_cst, align 8 440 ret void 441} 442