1; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+v8.4a %s -o - | FileCheck %s 2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+lse2 %s -o - | FileCheck %s 3 4define void @test_atomic_load(ptr %addr) { 5; CHECK-LABEL: test_atomic_load: 6 7; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x0] 8; CHECK: stp [[LO]], [[HI]], [x0] 9 %res.0 = load atomic i128, ptr %addr monotonic, align 16 10 store i128 %res.0, ptr %addr 11 12; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x0] 13; CHECK: stp [[LO]], [[HI]], [x0] 14 %res.1 = load atomic i128, ptr %addr unordered, align 16 15 store i128 %res.1, ptr %addr 16 17; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x0] 18; CHECK: dmb ish 19; CHECK: stp [[LO]], [[HI]], [x0] 20 %res.2 = load atomic i128, ptr %addr acquire, align 16 21 store i128 %res.2, ptr %addr 22 23; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x0] 24; CHECK: dmb ish 25; CHECK: stp [[LO]], [[HI]], [x0] 26 %res.3 = load atomic i128, ptr %addr seq_cst, align 16 27 store i128 %res.3, ptr %addr 28 29 30 31; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x0, #32] 32; CHECK-DAG: stp [[LO]], [[HI]], [x0] 33 %addr8.1 = getelementptr i8, ptr %addr, i32 32 34 %res.5 = load atomic i128, ptr %addr8.1 monotonic, align 16 35 store i128 %res.5, ptr %addr 36 37; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x0, #504] 38; CHECK: stp [[LO]], [[HI]], [x0] 39 %addr8.2 = getelementptr i8, ptr %addr, i32 504 40 %res.6 = load atomic i128, ptr %addr8.2 monotonic, align 16 41 store i128 %res.6, ptr %addr 42 43; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x0, #-512] 44; CHECK: stp [[LO]], [[HI]], [x0] 45 %addr8.3 = getelementptr i8, ptr %addr, i32 -512 46 %res.7 = load atomic i128, ptr %addr8.3 monotonic, align 16 47 store i128 %res.7, ptr %addr 48 49 ret void 50} 51 52define void @test_libcall_load(ptr %addr) { 53; CHECK-LABEL: test_libcall_load: 54; CHECK: bl __atomic_load 55 %res.8 = load atomic i128, ptr %addr unordered, align 8 56 store i128 %res.8, ptr %addr 57 58 ret void 59} 60 61define void @test_nonfolded_load1(ptr %addr) { 62; CHECK-LABEL: test_nonfolded_load1: 63 64; CHECK: add x[[ADDR:[0-9]+]], x0, #4 65; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x[[ADDR]]] 66; CHECK: stp [[LO]], [[HI]], [x0] 67 %addr8.1 = getelementptr i8, ptr %addr, i32 4 68 %res.1 = load atomic i128, ptr %addr8.1 monotonic, align 16 69 store i128 %res.1, ptr %addr 70 71 ret void 72} 73 74define void @test_nonfolded_load2(ptr %addr) { 75; CHECK-LABEL: test_nonfolded_load2: 76 77; CHECK: add x[[ADDR:[0-9]+]], x0, #512 78; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x[[ADDR]]] 79; CHECK: stp [[LO]], [[HI]], [x0] 80 %addr8.1 = getelementptr i8, ptr %addr, i32 512 81 %res.1 = load atomic i128, ptr %addr8.1 monotonic, align 16 82 store i128 %res.1, ptr %addr 83 84 ret void 85} 86 87define void @test_nonfolded_load3(ptr %addr) { 88; CHECK-LABEL: test_nonfolded_load3: 89 90; CHECK: sub x[[ADDR:[0-9]+]], x0, #520 91; CHECK: ldp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x[[ADDR]]] 92; CHECK: stp [[LO]], [[HI]], [x0] 93 %addr8.1 = getelementptr i8, ptr %addr, i32 -520 94 %res.1 = load atomic i128, ptr %addr8.1 monotonic, align 16 95 store i128 %res.1, ptr %addr 96 97 ret void 98} 99 100define void @test_atomic_store(ptr %addr, i128 %val) { 101; CHECK-LABEL: test_atomic_store: 102 103; CHECK: stp x2, x3, [x0] 104 store atomic i128 %val, ptr %addr monotonic, align 16 105 106; CHECK: stp x2, x3, [x0] 107 store atomic i128 %val, ptr %addr unordered, align 16 108 109; CHECK: dmb ish 110; CHECK: stp x2, x3, [x0] 111 store atomic i128 %val, ptr %addr release, align 16 112 113; CHECK: dmb ish 114; CHECK: stp x2, x3, [x0] 115; CHECK: dmb ish 116 store atomic i128 %val, ptr %addr seq_cst, align 16 117 118 119 120; CHECK: stp x2, x3, [x0, #8] 121 %addr8.1 = getelementptr i8, ptr %addr, i32 8 122 store atomic i128 %val, ptr %addr8.1 monotonic, align 16 123 124; CHECK: stp x2, x3, [x0, #504] 125 %addr8.2 = getelementptr i8, ptr %addr, i32 504 126 store atomic i128 %val, ptr %addr8.2 monotonic, align 16 127 128; CHECK: stp x2, x3, [x0, #-512] 129 %addr8.3 = getelementptr i8, ptr %addr, i32 -512 130 store atomic i128 %val, ptr %addr8.3 monotonic, align 16 131 132 ret void 133} 134 135define void @test_libcall_store(ptr %addr, i128 %val) { 136; CHECK-LABEL: test_libcall_store: 137; CHECK: bl __atomic_store 138 store atomic i128 %val, ptr %addr unordered, align 8 139 140 ret void 141} 142 143define void @test_nonfolded_store1(ptr %addr, i128 %val) { 144; CHECK-LABEL: test_nonfolded_store1: 145 146; CHECK: add x[[ADDR:[0-9]+]], x0, #4 147; CHECK: stp x2, x3, [x[[ADDR]]] 148 %addr8.1 = getelementptr i8, ptr %addr, i32 4 149 store atomic i128 %val, ptr %addr8.1 monotonic, align 16 150 151 ret void 152} 153 154define void @test_nonfolded_store2(ptr %addr, i128 %val) { 155; CHECK-LABEL: test_nonfolded_store2: 156 157; CHECK: add x[[ADDR:[0-9]+]], x0, #512 158; CHECK: stp x2, x3, [x[[ADDR]]] 159 %addr8.1 = getelementptr i8, ptr %addr, i32 512 160 store atomic i128 %val, ptr %addr8.1 monotonic, align 16 161 162 ret void 163} 164 165define void @test_nonfolded_store3(ptr %addr, i128 %val) { 166; CHECK-LABEL: test_nonfolded_store3: 167 168; CHECK: sub x[[ADDR:[0-9]+]], x0, #520 169; CHECK: stp x2, x3, [x[[ADDR]]] 170 %addr8.1 = getelementptr i8, ptr %addr, i32 -520 171 store atomic i128 %val, ptr %addr8.1 monotonic, align 16 172 173 ret void 174} 175