mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
a3edd6a038
Storing will generally be immediately preceded by rounding from an f32 or f64, so make sure to match those patterns directly to convert into the FPR16 register class directly rather than going through the integer GPRs. This also eliminates an extra step in the convert-from-f64 path which was first converting to f32 and then to f16 from there. rdar://17594379 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212638 91177308-0d34-0410-b5e6-96231b3b80d8
255 lines
7.2 KiB
LLVM
255 lines
7.2 KiB
LLVM
; 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* %a, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(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* %a, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
|
|
%conv = fpext float %tmp1 to double
|
|
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* %a, i64 %idxprom
|
|
%tmp = load i16* %arrayidx, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(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* %a, i64 %idxprom
|
|
%tmp = load i16* %arrayidx, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
|
|
%conv = fpext float %tmp1 to double
|
|
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* %a, i64 %i
|
|
%tmp = load i16* %arrayidx, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(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* %a, i64 %i
|
|
%tmp = load i16* %arrayidx, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
|
|
%conv = fpext float %tmp1 to double
|
|
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* %a, i64 10
|
|
%tmp = load i16* %arrayidx, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(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* %a, i64 10
|
|
%tmp = load i16* %arrayidx, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
|
|
%conv = fpext float %tmp1 to double
|
|
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* %a, i64 -10
|
|
%tmp = load i16* %arrayidx, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(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* %a, i64 -10
|
|
%tmp = load i16* %arrayidx, align 2
|
|
%tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
|
|
%conv = fpext float %tmp1 to double
|
|
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(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 h0, d0
|
|
; CHECK-NEXT: str h0, [x0]
|
|
; CHECK-NEXT: ret
|
|
|
|
%conv = fptrunc double %val to float
|
|
%tmp = tail call i16 @llvm.convert.to.fp16(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(float %val)
|
|
%idxprom = sext i32 %i to i64
|
|
%arrayidx = getelementptr inbounds 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 h0, d0
|
|
; 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(float %conv)
|
|
%idxprom = sext i32 %i to i64
|
|
%arrayidx = getelementptr inbounds 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(float %val)
|
|
%arrayidx = getelementptr inbounds 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 h0, d0
|
|
; 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(float %conv)
|
|
%arrayidx = getelementptr inbounds 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(float %val)
|
|
%arrayidx = getelementptr inbounds 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 h0, d0
|
|
; CHECK-NEXT: str h0, [x0, #20]
|
|
; CHECK-NEXT: ret
|
|
|
|
%conv = fptrunc double %val to float
|
|
%tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
|
|
%arrayidx = getelementptr inbounds 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(float %val)
|
|
%arrayidx = getelementptr inbounds 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 h0, d0
|
|
; CHECK-NEXT: stur h0, [x0, #-20]
|
|
; CHECK-NEXT: ret
|
|
|
|
%conv = fptrunc double %val to float
|
|
%tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
|
|
%arrayidx = getelementptr inbounds i16* %a, i64 -10
|
|
store i16 %tmp, i16* %arrayidx, align 2
|
|
ret void
|
|
}
|
|
|
|
declare i16 @llvm.convert.to.fp16(float) nounwind readnone
|
|
declare float @llvm.convert.from.fp16(i16) nounwind readnone
|