1; PR52927: Relaxed atomics can load to/store from fp regs directly 2; RUN: llc < %s -mtriple=arm64-eabi -asm-verbose=false -verify-machineinstrs -mcpu=cyclone | FileCheck %s 3 4define float @atomic_load_relaxed_f32(ptr %p, i32 %off32, i64 %off64) #0 { 5; CHECK-LABEL: atomic_load_relaxed_f32: 6 %ptr_unsigned = getelementptr float, ptr %p, i32 4095 7 %val_unsigned = load atomic float, ptr %ptr_unsigned monotonic, align 4 8; CHECK: ldr {{s[0-9]+}}, [x0, #16380] 9 10 %ptr_regoff = getelementptr float, ptr %p, i32 %off32 11 %val_regoff = load atomic float, ptr %ptr_regoff unordered, align 4 12 %tot1 = fadd float %val_unsigned, %val_regoff 13; CHECK: ldr {{s[0-9]+}}, [x0, w1, sxtw #2] 14 15 %ptr_regoff64 = getelementptr float, ptr %p, i64 %off64 16 %val_regoff64 = load atomic float, ptr %ptr_regoff64 monotonic, align 4 17 %tot2 = fadd float %tot1, %val_regoff64 18; CHECK: ldr {{s[0-9]+}}, [x0, x2, lsl #2] 19 20 %ptr_unscaled = getelementptr float, ptr %p, i32 -64 21 %val_unscaled = load atomic float, ptr %ptr_unscaled unordered, align 4 22 %tot3 = fadd float %tot2, %val_unscaled 23; CHECK: ldur {{s[0-9]+}}, [x0, #-256] 24 25 ret float %tot3 26} 27 28define double @atomic_load_relaxed_f64(ptr %p, i32 %off32, i64 %off64) #0 { 29; CHECK-LABEL: atomic_load_relaxed_f64: 30 %ptr_unsigned = getelementptr double, ptr %p, i32 4095 31 %val_unsigned = load atomic double, ptr %ptr_unsigned monotonic, align 8 32; CHECK: ldr {{d[0-9]+}}, [x0, #32760] 33 34 %ptr_regoff = getelementptr double, ptr %p, i32 %off32 35 %val_regoff = load atomic double, ptr %ptr_regoff unordered, align 8 36 %tot1 = fadd double %val_unsigned, %val_regoff 37; CHECK: ldr {{d[0-9]+}}, [x0, w1, sxtw #3] 38 39 %ptr_regoff64 = getelementptr double, ptr %p, i64 %off64 40 %val_regoff64 = load atomic double, ptr %ptr_regoff64 monotonic, align 8 41 %tot2 = fadd double %tot1, %val_regoff64 42; CHECK: ldr {{d[0-9]+}}, [x0, x2, lsl #3] 43 44 %ptr_unscaled = getelementptr double, ptr %p, i32 -32 45 %val_unscaled = load atomic double, ptr %ptr_unscaled unordered, align 8 46 %tot3 = fadd double %tot2, %val_unscaled 47; CHECK: ldur {{d[0-9]+}}, [x0, #-256] 48 49 ret double %tot3 50} 51 52define void @atomic_store_relaxed_f32(ptr %p, i32 %off32, i64 %off64, float %val) #0 { 53; CHECK-LABEL: atomic_store_relaxed_f32: 54 %ptr_unsigned = getelementptr float, ptr %p, i32 4095 55 store atomic float %val, ptr %ptr_unsigned monotonic, align 4 56; CHECK: str {{s[0-9]+}}, [x0, #16380] 57 58 %ptr_regoff = getelementptr float, ptr %p, i32 %off32 59 store atomic float %val, ptr %ptr_regoff unordered, align 4 60; CHECK: str {{s[0-9]+}}, [x0, w1, sxtw #2] 61 62 %ptr_regoff64 = getelementptr float, ptr %p, i64 %off64 63 store atomic float %val, ptr %ptr_regoff64 monotonic, align 4 64; CHECK: str {{s[0-9]+}}, [x0, x2, lsl #2] 65 66 %ptr_unscaled = getelementptr float, ptr %p, i32 -64 67 store atomic float %val, ptr %ptr_unscaled unordered, align 4 68; CHECK: stur {{s[0-9]+}}, [x0, #-256] 69 70 ret void 71} 72 73define void @atomic_store_relaxed_f64(ptr %p, i32 %off32, i64 %off64, double %val) #0 { 74; CHECK-LABEL: atomic_store_relaxed_f64: 75 %ptr_unsigned = getelementptr double, ptr %p, i32 4095 76 store atomic double %val, ptr %ptr_unsigned monotonic, align 8 77; CHECK: str {{d[0-9]+}}, [x0, #32760] 78 79 %ptr_regoff = getelementptr double, ptr %p, i32 %off32 80 store atomic double %val, ptr %ptr_regoff unordered, align 8 81; CHECK: str {{d[0-9]+}}, [x0, w1, sxtw #3] 82 83 %ptr_regoff64 = getelementptr double, ptr %p, i64 %off64 84 store atomic double %val, ptr %ptr_regoff64 unordered, align 8 85; CHECK: str {{d[0-9]+}}, [x0, x2, lsl #3] 86 87 %ptr_unscaled = getelementptr double, ptr %p, i32 -32 88 store atomic double %val, ptr %ptr_unscaled monotonic, align 8 89; CHECK: stur {{d[0-9]+}}, [x0, #-256] 90 91 ret void 92} 93 94define half @atomic_load_relaxed_f16(ptr %p, i32 %off32, i64 %off64) #0 { 95; CHECK-LABEL: atomic_load_relaxed_f16: 96 %ptr_unsigned = getelementptr half, ptr %p, i32 4095 97 %val_unsigned = load atomic half, ptr %ptr_unsigned monotonic, align 4 98; CHECK: ldrh {{w[0-9]+}}, [x0, #8190] 99 100 %ptr_regoff = getelementptr half, ptr %p, i32 %off32 101 %val_regoff = load atomic half, ptr %ptr_regoff unordered, align 4 102 %tot1 = fadd half %val_unsigned, %val_regoff 103; CHECK: ldrh {{w[0-9]+}}, [x0, w1, sxtw #1] 104 105 %ptr_regoff64 = getelementptr half, ptr %p, i64 %off64 106 %val_regoff64 = load atomic half, ptr %ptr_regoff64 monotonic, align 4 107 %tot2 = fadd half %tot1, %val_regoff64 108; CHECK: ldrh {{w[0-9]+}}, [x0, x2, lsl #1] 109 110 %ptr_unscaled = getelementptr half, ptr %p, i32 -64 111 %val_unscaled = load atomic half, ptr %ptr_unscaled unordered, align 4 112 %tot3 = fadd half %tot2, %val_unscaled 113; CHECK: ldurh {{w[0-9]+}}, [x0, #-128] 114 115 ret half %tot3 116} 117 118define bfloat @atomic_load_relaxed_bf16(ptr %p, i32 %off32, i64 %off64) #0 { 119; CHECK-LABEL: atomic_load_relaxed_bf16: 120 %ptr_unsigned = getelementptr bfloat, ptr %p, i32 4095 121 %val_unsigned = load atomic bfloat, ptr %ptr_unsigned monotonic, align 4 122; CHECK: ldrh {{w[0-9]+}}, [x0, #8190] 123 124 %ptr_regoff = getelementptr bfloat, ptr %p, i32 %off32 125 %val_regoff = load atomic bfloat, ptr %ptr_regoff unordered, align 4 126 %tot1 = fadd bfloat %val_unsigned, %val_regoff 127; CHECK: ldrh {{w[0-9]+}}, [x0, w1, sxtw #1] 128 129 %ptr_regoff64 = getelementptr bfloat, ptr %p, i64 %off64 130 %val_regoff64 = load atomic bfloat, ptr %ptr_regoff64 monotonic, align 4 131 %tot2 = fadd bfloat %tot1, %val_regoff64 132; CHECK: ldrh {{w[0-9]+}}, [x0, x2, lsl #1] 133 134 %ptr_unscaled = getelementptr bfloat, ptr %p, i32 -64 135 %val_unscaled = load atomic bfloat, ptr %ptr_unscaled unordered, align 4 136 %tot3 = fadd bfloat %tot2, %val_unscaled 137; CHECK: ldurh {{w[0-9]+}}, [x0, #-128] 138 139 ret bfloat %tot3 140} 141 142define void @atomic_store_relaxed_f16(ptr %p, i32 %off32, i64 %off64, half %val) #0 { 143; CHECK-LABEL: atomic_store_relaxed_f16: 144 %ptr_unsigned = getelementptr half, ptr %p, i32 4095 145 store atomic half %val, ptr %ptr_unsigned monotonic, align 4 146; CHECK: strh {{w[0-9]+}}, [x0, #8190] 147 148 %ptr_regoff = getelementptr half, ptr %p, i32 %off32 149 store atomic half %val, ptr %ptr_regoff unordered, align 4 150; CHECK: strh {{w[0-9]+}}, [x0, w1, sxtw #1] 151 152 %ptr_regoff64 = getelementptr half, ptr %p, i64 %off64 153 store atomic half %val, ptr %ptr_regoff64 monotonic, align 4 154; CHECK: strh {{w[0-9]+}}, [x0, x2, lsl #1] 155 156 %ptr_unscaled = getelementptr half, ptr %p, i32 -64 157 store atomic half %val, ptr %ptr_unscaled unordered, align 4 158; CHECK: sturh {{w[0-9]+}}, [x0, #-128] 159 160 ret void 161} 162 163define void @atomic_store_relaxed_bf16(ptr %p, i32 %off32, i64 %off64, bfloat %val) #0 { 164; CHECK-LABEL: atomic_store_relaxed_bf16: 165 %ptr_unsigned = getelementptr bfloat, ptr %p, i32 4095 166 store atomic bfloat %val, ptr %ptr_unsigned monotonic, align 4 167; CHECK: strh {{w[0-9]+}}, [x0, #8190] 168 169 %ptr_regoff = getelementptr bfloat, ptr %p, i32 %off32 170 store atomic bfloat %val, ptr %ptr_regoff unordered, align 4 171; CHECK: strh {{w[0-9]+}}, [x0, w1, sxtw #1] 172 173 %ptr_regoff64 = getelementptr bfloat, ptr %p, i64 %off64 174 store atomic bfloat %val, ptr %ptr_regoff64 monotonic, align 4 175; CHECK: strh {{w[0-9]+}}, [x0, x2, lsl #1] 176 177 %ptr_unscaled = getelementptr bfloat, ptr %p, i32 -64 178 store atomic bfloat %val, ptr %ptr_unscaled unordered, align 4 179; CHECK: sturh {{w[0-9]+}}, [x0, #-128] 180 181 ret void 182} 183 184attributes #0 = { nounwind } 185