| ; RUN: llc < %s -mtriple=arm64-apple-ios -asm-verbose=false | FileCheck %s |
| |
| define float @load0(i16* nocapture readonly %a) nounwind { |
| ; CHECK-LABEL: load0: |
| ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0] |
| ; CHECK-NEXT: fcvt s0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %tmp = load i16, i16* %a, align 2 |
| %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) |
| ret float %tmp1 |
| } |
| |
| define double @load1(i16* nocapture readonly %a) nounwind { |
| ; CHECK-LABEL: load1: |
| ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0] |
| ; CHECK-NEXT: fcvt d0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %tmp = load i16, i16* %a, align 2 |
| %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) |
| ret double %conv |
| } |
| |
| define float @load2(i16* nocapture readonly %a, i32 %i) nounwind { |
| ; CHECK-LABEL: load2: |
| ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, w1, sxtw #1] |
| ; CHECK-NEXT: fcvt s0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %idxprom = sext i32 %i to i64 |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom |
| %tmp = load i16, i16* %arrayidx, align 2 |
| %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) |
| ret float %tmp1 |
| } |
| |
| define double @load3(i16* nocapture readonly %a, i32 %i) nounwind { |
| ; CHECK-LABEL: load3: |
| ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, w1, sxtw #1] |
| ; CHECK-NEXT: fcvt d0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %idxprom = sext i32 %i to i64 |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom |
| %tmp = load i16, i16* %arrayidx, align 2 |
| %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) |
| ret double %conv |
| } |
| |
| define float @load4(i16* nocapture readonly %a, i64 %i) nounwind { |
| ; CHECK-LABEL: load4: |
| ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, x1, lsl #1] |
| ; CHECK-NEXT: fcvt s0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i |
| %tmp = load i16, i16* %arrayidx, align 2 |
| %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) |
| ret float %tmp1 |
| } |
| |
| define double @load5(i16* nocapture readonly %a, i64 %i) nounwind { |
| ; CHECK-LABEL: load5: |
| ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, x1, lsl #1] |
| ; CHECK-NEXT: fcvt d0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i |
| %tmp = load i16, i16* %arrayidx, align 2 |
| %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) |
| ret double %conv |
| } |
| |
| define float @load6(i16* nocapture readonly %a) nounwind { |
| ; CHECK-LABEL: load6: |
| ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, #20] |
| ; CHECK-NEXT: fcvt s0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 10 |
| %tmp = load i16, i16* %arrayidx, align 2 |
| %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) |
| ret float %tmp1 |
| } |
| |
| define double @load7(i16* nocapture readonly %a) nounwind { |
| ; CHECK-LABEL: load7: |
| ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, #20] |
| ; CHECK-NEXT: fcvt d0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 10 |
| %tmp = load i16, i16* %arrayidx, align 2 |
| %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) |
| ret double %conv |
| } |
| |
| define float @load8(i16* nocapture readonly %a) nounwind { |
| ; CHECK-LABEL: load8: |
| ; CHECK-NEXT: ldur [[HREG:h[0-9]+]], [x0, #-20] |
| ; CHECK-NEXT: fcvt s0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10 |
| %tmp = load i16, i16* %arrayidx, align 2 |
| %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp) |
| ret float %tmp1 |
| } |
| |
| define double @load9(i16* nocapture readonly %a) nounwind { |
| ; CHECK-LABEL: load9: |
| ; CHECK-NEXT: ldur [[HREG:h[0-9]+]], [x0, #-20] |
| ; CHECK-NEXT: fcvt d0, [[HREG]] |
| ; CHECK-NEXT: ret |
| |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10 |
| %tmp = load i16, i16* %arrayidx, align 2 |
| %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp) |
| ret double %conv |
| } |
| |
| define void @store0(i16* nocapture %a, float %val) nounwind { |
| ; CHECK-LABEL: store0: |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: str h0, [x0] |
| ; CHECK-NEXT: ret |
| |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) |
| store i16 %tmp, i16* %a, align 2 |
| ret void |
| } |
| |
| define void @store1(i16* nocapture %a, double %val) nounwind { |
| ; CHECK-LABEL: store1: |
| ; CHECK-NEXT: fcvt s0, d0 |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: str h0, [x0] |
| ; CHECK-NEXT: ret |
| |
| %conv = fptrunc double %val to float |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) |
| store i16 %tmp, i16* %a, align 2 |
| ret void |
| } |
| |
| define void @store2(i16* nocapture %a, i32 %i, float %val) nounwind { |
| ; CHECK-LABEL: store2: |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: str h0, [x0, w1, sxtw #1] |
| ; CHECK-NEXT: ret |
| |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) |
| %idxprom = sext i32 %i to i64 |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom |
| store i16 %tmp, i16* %arrayidx, align 2 |
| ret void |
| } |
| |
| define void @store3(i16* nocapture %a, i32 %i, double %val) nounwind { |
| ; CHECK-LABEL: store3: |
| ; CHECK-NEXT: fcvt s0, d0 |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: str h0, [x0, w1, sxtw #1] |
| ; CHECK-NEXT: ret |
| |
| %conv = fptrunc double %val to float |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) |
| %idxprom = sext i32 %i to i64 |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom |
| store i16 %tmp, i16* %arrayidx, align 2 |
| ret void |
| } |
| |
| define void @store4(i16* nocapture %a, i64 %i, float %val) nounwind { |
| ; CHECK-LABEL: store4: |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: str h0, [x0, x1, lsl #1] |
| ; CHECK-NEXT: ret |
| |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i |
| store i16 %tmp, i16* %arrayidx, align 2 |
| ret void |
| } |
| |
| define void @store5(i16* nocapture %a, i64 %i, double %val) nounwind { |
| ; CHECK-LABEL: store5: |
| ; CHECK-NEXT: fcvt s0, d0 |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: str h0, [x0, x1, lsl #1] |
| ; CHECK-NEXT: ret |
| |
| %conv = fptrunc double %val to float |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i |
| store i16 %tmp, i16* %arrayidx, align 2 |
| ret void |
| } |
| |
| define void @store6(i16* nocapture %a, float %val) nounwind { |
| ; CHECK-LABEL: store6: |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: str h0, [x0, #20] |
| ; CHECK-NEXT: ret |
| |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 10 |
| store i16 %tmp, i16* %arrayidx, align 2 |
| ret void |
| } |
| |
| define void @store7(i16* nocapture %a, double %val) nounwind { |
| ; CHECK-LABEL: store7: |
| ; CHECK-NEXT: fcvt s0, d0 |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: str h0, [x0, #20] |
| ; CHECK-NEXT: ret |
| |
| %conv = fptrunc double %val to float |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 10 |
| store i16 %tmp, i16* %arrayidx, align 2 |
| ret void |
| } |
| |
| define void @store8(i16* nocapture %a, float %val) nounwind { |
| ; CHECK-LABEL: store8: |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: stur h0, [x0, #-20] |
| ; CHECK-NEXT: ret |
| |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val) |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10 |
| store i16 %tmp, i16* %arrayidx, align 2 |
| ret void |
| } |
| |
| define void @store9(i16* nocapture %a, double %val) nounwind { |
| ; CHECK-LABEL: store9: |
| ; CHECK-NEXT: fcvt s0, d0 |
| ; CHECK-NEXT: fcvt h0, s0 |
| ; CHECK-NEXT: stur h0, [x0, #-20] |
| ; CHECK-NEXT: ret |
| |
| %conv = fptrunc double %val to float |
| %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv) |
| %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10 |
| store i16 %tmp, i16* %arrayidx, align 2 |
| ret void |
| } |
| |
| declare i16 @llvm.convert.to.fp16.f32(float) nounwind readnone |
| declare float @llvm.convert.from.fp16.f32(i16) nounwind readnone |
| declare i16 @llvm.convert.to.fp16.f64(double) nounwind readnone |
| declare double @llvm.convert.from.fp16.f64(i16) nounwind readnone |