1; RUN: llc < %s -mtriple=arm64-apple-ios -asm-verbose=false | FileCheck %s 2 3define float @load0(i16* nocapture readonly %a) nounwind { 4; CHECK-LABEL: load0: 5; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0] 6; CHECK-NEXT: fcvt s0, [[HREG]] 7; CHECK-NEXT: ret 8 9 %tmp = load i16, i16* %a, align 2 10 %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) 11 ret float %tmp1 12} 13 14define double @load1(i16* nocapture readonly %a) nounwind { 15; CHECK-LABEL: load1: 16; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0] 17; CHECK-NEXT: fcvt d0, [[HREG]] 18; CHECK-NEXT: ret 19 20 %tmp = load i16, i16* %a, align 2 21 %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) 22 ret double %conv 23} 24 25define float @load2(i16* nocapture readonly %a, i32 %i) nounwind { 26; CHECK-LABEL: load2: 27; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, w1, sxtw #1] 28; CHECK-NEXT: fcvt s0, [[HREG]] 29; CHECK-NEXT: ret 30 31 %idxprom = sext i32 %i to i64 32 %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom 33 %tmp = load i16, i16* %arrayidx, align 2 34 %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) 35 ret float %tmp1 36} 37 38define double @load3(i16* nocapture readonly %a, i32 %i) nounwind { 39; CHECK-LABEL: load3: 40; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, w1, sxtw #1] 41; CHECK-NEXT: fcvt d0, [[HREG]] 42; CHECK-NEXT: ret 43 44 %idxprom = sext i32 %i to i64 45 %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom 46 %tmp = load i16, i16* %arrayidx, align 2 47 %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) 48 ret double %conv 49} 50 51define float @load4(i16* nocapture readonly %a, i64 %i) nounwind { 52; CHECK-LABEL: load4: 53; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, x1, lsl #1] 54; CHECK-NEXT: fcvt s0, [[HREG]] 55; CHECK-NEXT: ret 56 57 %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i 58 %tmp = load i16, i16* %arrayidx, align 2 59 %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) 60 ret float %tmp1 61} 62 63define double @load5(i16* nocapture readonly %a, i64 %i) nounwind { 64; CHECK-LABEL: load5: 65; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, x1, lsl #1] 66; CHECK-NEXT: fcvt d0, [[HREG]] 67; CHECK-NEXT: ret 68 69 %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i 70 %tmp = load i16, i16* %arrayidx, align 2 71 %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) 72 ret double %conv 73} 74 75define float @load6(i16* nocapture readonly %a) nounwind { 76; CHECK-LABEL: load6: 77; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, #20] 78; CHECK-NEXT: fcvt s0, [[HREG]] 79; CHECK-NEXT: ret 80 81 %arrayidx = getelementptr inbounds i16, i16* %a, i64 10 82 %tmp = load i16, i16* %arrayidx, align 2 83 %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) 84 ret float %tmp1 85} 86 87define double @load7(i16* nocapture readonly %a) nounwind { 88; CHECK-LABEL: load7: 89; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, #20] 90; CHECK-NEXT: fcvt d0, [[HREG]] 91; CHECK-NEXT: ret 92 93 %arrayidx = getelementptr inbounds i16, i16* %a, i64 10 94 %tmp = load i16, i16* %arrayidx, align 2 95 %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) 96 ret double %conv 97} 98 99define float @load8(i16* nocapture readonly %a) nounwind { 100; CHECK-LABEL: load8: 101; CHECK-NEXT: ldur [[HREG:h[0-9]+]], [x0, #-20] 102; CHECK-NEXT: fcvt s0, [[HREG]] 103; CHECK-NEXT: ret 104 105 %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10 106 %tmp = load i16, i16* %arrayidx, align 2 107 %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) 108 ret float %tmp1 109} 110 111define double @load9(i16* nocapture readonly %a) nounwind { 112; CHECK-LABEL: load9: 113; CHECK-NEXT: ldur [[HREG:h[0-9]+]], [x0, #-20] 114; CHECK-NEXT: fcvt d0, [[HREG]] 115; CHECK-NEXT: ret 116 117 %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10 118 %tmp = load i16, i16* %arrayidx, align 2 119 %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) 120 ret double %conv 121} 122 123define void @store0(i16* nocapture %a, float %val) nounwind { 124; CHECK-LABEL: store0: 125; CHECK-NEXT: fcvt h0, s0 126; CHECK-NEXT: str h0, [x0] 127; CHECK-NEXT: ret 128 129 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) 130 store i16 %tmp, i16* %a, align 2 131 ret void 132} 133 134define void @store1(i16* nocapture %a, double %val) nounwind { 135; CHECK-LABEL: store1: 136; CHECK-NEXT: fcvt s0, d0 137; CHECK-NEXT: fcvt h0, s0 138; CHECK-NEXT: str h0, [x0] 139; CHECK-NEXT: ret 140 141 %conv = fptrunc double %val to float 142 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) 143 store i16 %tmp, i16* %a, align 2 144 ret void 145} 146 147define void @store2(i16* nocapture %a, i32 %i, float %val) nounwind { 148; CHECK-LABEL: store2: 149; CHECK-NEXT: fcvt h0, s0 150; CHECK-NEXT: str h0, [x0, w1, sxtw #1] 151; CHECK-NEXT: ret 152 153 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) 154 %idxprom = sext i32 %i to i64 155 %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom 156 store i16 %tmp, i16* %arrayidx, align 2 157 ret void 158} 159 160define void @store3(i16* nocapture %a, i32 %i, double %val) nounwind { 161; CHECK-LABEL: store3: 162; CHECK-NEXT: fcvt s0, d0 163; CHECK-NEXT: fcvt h0, s0 164; CHECK-NEXT: str h0, [x0, w1, sxtw #1] 165; CHECK-NEXT: ret 166 167 %conv = fptrunc double %val to float 168 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) 169 %idxprom = sext i32 %i to i64 170 %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom 171 store i16 %tmp, i16* %arrayidx, align 2 172 ret void 173} 174 175define void @store4(i16* nocapture %a, i64 %i, float %val) nounwind { 176; CHECK-LABEL: store4: 177; CHECK-NEXT: fcvt h0, s0 178; CHECK-NEXT: str h0, [x0, x1, lsl #1] 179; CHECK-NEXT: ret 180 181 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) 182 %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i 183 store i16 %tmp, i16* %arrayidx, align 2 184 ret void 185} 186 187define void @store5(i16* nocapture %a, i64 %i, double %val) nounwind { 188; CHECK-LABEL: store5: 189; CHECK-NEXT: fcvt s0, d0 190; CHECK-NEXT: fcvt h0, s0 191; CHECK-NEXT: str h0, [x0, x1, lsl #1] 192; CHECK-NEXT: ret 193 194 %conv = fptrunc double %val to float 195 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) 196 %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i 197 store i16 %tmp, i16* %arrayidx, align 2 198 ret void 199} 200 201define void @store6(i16* nocapture %a, float %val) nounwind { 202; CHECK-LABEL: store6: 203; CHECK-NEXT: fcvt h0, s0 204; CHECK-NEXT: str h0, [x0, #20] 205; CHECK-NEXT: ret 206 207 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) 208 %arrayidx = getelementptr inbounds i16, i16* %a, i64 10 209 store i16 %tmp, i16* %arrayidx, align 2 210 ret void 211} 212 213define void @store7(i16* nocapture %a, double %val) nounwind { 214; CHECK-LABEL: store7: 215; CHECK-NEXT: fcvt s0, d0 216; CHECK-NEXT: fcvt h0, s0 217; CHECK-NEXT: str h0, [x0, #20] 218; CHECK-NEXT: ret 219 220 %conv = fptrunc double %val to float 221 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) 222 %arrayidx = getelementptr inbounds i16, i16* %a, i64 10 223 store i16 %tmp, i16* %arrayidx, align 2 224 ret void 225} 226 227define void @store8(i16* nocapture %a, float %val) nounwind { 228; CHECK-LABEL: store8: 229; CHECK-NEXT: fcvt h0, s0 230; CHECK-NEXT: stur h0, [x0, #-20] 231; CHECK-NEXT: ret 232 233 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) 234 %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10 235 store i16 %tmp, i16* %arrayidx, align 2 236 ret void 237} 238 239define void @store9(i16* nocapture %a, double %val) nounwind { 240; CHECK-LABEL: store9: 241; CHECK-NEXT: fcvt s0, d0 242; CHECK-NEXT: fcvt h0, s0 243; CHECK-NEXT: stur h0, [x0, #-20] 244; CHECK-NEXT: ret 245 246 %conv = fptrunc double %val to float 247 %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) 248 %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10 249 store i16 %tmp, i16* %arrayidx, align 2 250 ret void 251} 252 253declare i16 @llvm.convert.to.fp16.f32(float) nounwind readnone 254declare float @llvm.convert.from.fp16.f32(i16) nounwind readnone 255declare i16 @llvm.convert.to.fp16.f64(double) nounwind readnone 256declare double @llvm.convert.from.fp16.f64(i16) nounwind readnone 257