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