CodeGen: extend f16 conversions to permit types > float.

This makes the two intrinsics @llvm.convert.from.f16 and
@llvm.convert.to.f16 accept types other than simple "float". This is
only strictly needed for the truncate operation, since otherwise
double rounding occurs and there's no way to represent the strict IEEE
conversion. However, for symmetry we allow larger types in the extend
too.

During legalization, we can expand an "fp16_to_double" operation into
two extends for convenience, but abort when the truncate isn't legal. A new
libcall is probably needed here.

Even after this commit, various target tweaks are needed to actually use the
extended intrinsics. I've put these into separate commits for clarity, so there
are no actual tests of f64 conversion here.

llvm-svn: 213248
diff --git a/llvm/test/CodeGen/AArch64/arm64-vcvt_f.ll b/llvm/test/CodeGen/AArch64/arm64-vcvt_f.ll
index cad8353..1f393c2 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vcvt_f.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vcvt_f.ll
@@ -66,7 +66,7 @@
 ; CHECK-LABEL: to_half:
 ; CHECK: fcvt h[[HALFVAL:[0-9]+]], s0
 ; CHECK: fmov {{w[0-9]+}}, {{s[0-9]+}}
-  %res = call i16 @llvm.convert.to.fp16(float %in)
+  %res = call i16 @llvm.convert.to.fp16.f32(float %in)
   ret i16 %res
 }
 
@@ -74,9 +74,9 @@
 ; CHECK-LABEL: from_half:
 ; CHECK: fmov {{s[0-9]+}}, {{w[0-9]+}}
 ; CHECK: fcvt s0, {{h[0-9]+}}
-  %res = call float @llvm.convert.from.fp16(i16 %in)
+  %res = call float @llvm.convert.from.fp16.f32(i16 %in)
   ret float %res
 }
 
-declare float @llvm.convert.from.fp16(i16) #1
-declare i16 @llvm.convert.to.fp16(float) #1
+declare float @llvm.convert.from.fp16.f32(i16) #1
+declare i16 @llvm.convert.to.fp16.f32(float) #1
diff --git a/llvm/test/CodeGen/AArch64/f16-convert.ll b/llvm/test/CodeGen/AArch64/f16-convert.ll
index 6fabdc5..72685e8 100644
--- a/llvm/test/CodeGen/AArch64/f16-convert.ll
+++ b/llvm/test/CodeGen/AArch64/f16-convert.ll
@@ -7,7 +7,7 @@
 ; CHECK-NEXT: ret
 
   %tmp = load i16* %a, align 2
-  %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   ret float %tmp1
 }
 
@@ -18,7 +18,7 @@
 ; CHECK-NEXT: ret
 
   %tmp = load i16* %a, align 2
-  %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   %conv = fpext float %tmp1 to double
   ret double %conv
 }
@@ -32,7 +32,7 @@
   %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)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   ret float %tmp1
 }
 
@@ -45,7 +45,7 @@
   %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)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   %conv = fpext float %tmp1 to double
   ret double %conv
 }
@@ -58,7 +58,7 @@
 
   %arrayidx = getelementptr inbounds i16* %a, i64 %i
   %tmp = load i16* %arrayidx, align 2
-  %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   ret float %tmp1
 }
 
@@ -70,7 +70,7 @@
 
   %arrayidx = getelementptr inbounds i16* %a, i64 %i
   %tmp = load i16* %arrayidx, align 2
-  %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   %conv = fpext float %tmp1 to double
   ret double %conv
 }
@@ -83,7 +83,7 @@
 
   %arrayidx = getelementptr inbounds i16* %a, i64 10
   %tmp = load i16* %arrayidx, align 2
-  %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   ret float %tmp1
 }
 
@@ -95,7 +95,7 @@
 
   %arrayidx = getelementptr inbounds i16* %a, i64 10
   %tmp = load i16* %arrayidx, align 2
-  %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   %conv = fpext float %tmp1 to double
   ret double %conv
 }
@@ -108,7 +108,7 @@
 
   %arrayidx = getelementptr inbounds i16* %a, i64 -10
   %tmp = load i16* %arrayidx, align 2
-  %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   ret float %tmp1
 }
 
@@ -120,7 +120,7 @@
 
   %arrayidx = getelementptr inbounds i16* %a, i64 -10
   %tmp = load i16* %arrayidx, align 2
-  %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
+  %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
   %conv = fpext float %tmp1 to double
   ret double %conv
 }
@@ -131,7 +131,7 @@
 ; CHECK-NEXT: str  h0, [x0]
 ; CHECK-NEXT: ret
 
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
   store i16 %tmp, i16* %a, align 2
   ret void
 }
@@ -143,7 +143,7 @@
 ; CHECK-NEXT: ret
 
   %conv = fptrunc double %val to float
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
   store i16 %tmp, i16* %a, align 2
   ret void
 }
@@ -154,7 +154,7 @@
 ; CHECK-NEXT: str h0, [x0, w1, sxtw #1]
 ; CHECK-NEXT: ret
 
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
   %idxprom = sext i32 %i to i64
   %arrayidx = getelementptr inbounds i16* %a, i64 %idxprom
   store i16 %tmp, i16* %arrayidx, align 2
@@ -168,7 +168,7 @@
 ; CHECK-NEXT: ret
 
   %conv = fptrunc double %val to float
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
   %idxprom = sext i32 %i to i64
   %arrayidx = getelementptr inbounds i16* %a, i64 %idxprom
   store i16 %tmp, i16* %arrayidx, align 2
@@ -181,7 +181,7 @@
 ; CHECK-NEXT: str h0, [x0, x1, lsl #1]
 ; CHECK-NEXT: ret
 
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
   %arrayidx = getelementptr inbounds i16* %a, i64 %i
   store i16 %tmp, i16* %arrayidx, align 2
   ret void
@@ -194,7 +194,7 @@
 ; CHECK-NEXT: ret
 
   %conv = fptrunc double %val to float
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
   %arrayidx = getelementptr inbounds i16* %a, i64 %i
   store i16 %tmp, i16* %arrayidx, align 2
   ret void
@@ -206,7 +206,7 @@
 ; CHECK-NEXT: str h0, [x0, #20]
 ; CHECK-NEXT: ret
 
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
   %arrayidx = getelementptr inbounds i16* %a, i64 10
   store i16 %tmp, i16* %arrayidx, align 2
   ret void
@@ -219,7 +219,7 @@
 ; CHECK-NEXT: ret
 
   %conv = fptrunc double %val to float
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
   %arrayidx = getelementptr inbounds i16* %a, i64 10
   store i16 %tmp, i16* %arrayidx, align 2
   ret void
@@ -231,7 +231,7 @@
 ; CHECK-NEXT: stur h0, [x0, #-20]
 ; CHECK-NEXT: ret
 
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
   %arrayidx = getelementptr inbounds i16* %a, i64 -10
   store i16 %tmp, i16* %arrayidx, align 2
   ret void
@@ -244,11 +244,11 @@
 ; CHECK-NEXT: ret
 
   %conv = fptrunc double %val to float
-  %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
+  %tmp = tail call i16 @llvm.convert.to.fp16.f32(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
+declare i16 @llvm.convert.to.fp16.f32(float) nounwind readnone
+declare float @llvm.convert.from.fp16.f32(i16) nounwind readnone
diff --git a/llvm/test/CodeGen/ARM/fp16.ll b/llvm/test/CodeGen/ARM/fp16.ll
index fba7946..7a99c17 100644
--- a/llvm/test/CodeGen/ARM/fp16.ll
+++ b/llvm/test/CodeGen/ARM/fp16.ll
@@ -13,20 +13,20 @@
 entry:
   %0 = load i16* @x, align 2
   %1 = load i16* @y, align 2
-  %2 = tail call float @llvm.convert.from.fp16(i16 %0)
+  %2 = tail call float @llvm.convert.from.fp16.f32(i16 %0)
 ; CHECK: __gnu_h2f_ieee
 ; CHECK-FP16: vcvtb.f32.f16
-  %3 = tail call float @llvm.convert.from.fp16(i16 %1)
+  %3 = tail call float @llvm.convert.from.fp16.f32(i16 %1)
 ; CHECK: __gnu_h2f_ieee
 ; CHECK-FP16: vcvtb.f32.f16
   %4 = fadd float %2, %3
-  %5 = tail call i16 @llvm.convert.to.fp16(float %4)
+  %5 = tail call i16 @llvm.convert.to.fp16.f32(float %4)
 ; CHECK: __gnu_f2h_ieee
 ; CHECK-FP16: vcvtb.f16.f32
   store i16 %5, i16* @x, align 2
   ret void
 }
 
-declare float @llvm.convert.from.fp16(i16) nounwind readnone
+declare float @llvm.convert.from.fp16.f32(i16) nounwind readnone
 
-declare i16 @llvm.convert.to.fp16(float) nounwind readnone
+declare i16 @llvm.convert.to.fp16.f32(float) nounwind readnone
diff --git a/llvm/test/CodeGen/R600/fp16_to_fp32.ll b/llvm/test/CodeGen/R600/fp16_to_fp32.ll
index fa2e379..dec53e4a 100644
--- a/llvm/test/CodeGen/R600/fp16_to_fp32.ll
+++ b/llvm/test/CodeGen/R600/fp16_to_fp32.ll
@@ -1,6 +1,6 @@
 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
 
-declare i16 @llvm.convert.to.fp16(float) nounwind readnone
+declare i16 @llvm.convert.to.fp16.f32(float) nounwind readnone
 
 ; SI-LABEL: @test_convert_fp16_to_fp32:
 ; SI: BUFFER_LOAD_DWORD [[VAL:v[0-9]+]]
@@ -8,7 +8,7 @@
 ; SI: BUFFER_STORE_SHORT [[RESULT]]
 define void @test_convert_fp16_to_fp32(i16 addrspace(1)* noalias %out, float addrspace(1)* noalias %in) nounwind {
   %val = load float addrspace(1)* %in, align 4
-  %cvt = call i16 @llvm.convert.to.fp16(float %val) nounwind readnone
+  %cvt = call i16 @llvm.convert.to.fp16.f32(float %val) nounwind readnone
   store i16 %cvt, i16 addrspace(1)* %out, align 2
   ret void
 }
diff --git a/llvm/test/CodeGen/R600/fp32_to_fp16.ll b/llvm/test/CodeGen/R600/fp32_to_fp16.ll
index 9997cd3..3a051f8 100644
--- a/llvm/test/CodeGen/R600/fp32_to_fp16.ll
+++ b/llvm/test/CodeGen/R600/fp32_to_fp16.ll
@@ -1,6 +1,6 @@
 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
 
-declare float @llvm.convert.from.fp16(i16) nounwind readnone
+declare float @llvm.convert.from.fp16.f32(i16) nounwind readnone
 
 ; SI-LABEL: @test_convert_fp16_to_fp32:
 ; SI: BUFFER_LOAD_USHORT [[VAL:v[0-9]+]]
@@ -8,7 +8,7 @@
 ; SI: BUFFER_STORE_DWORD [[RESULT]]
 define void @test_convert_fp16_to_fp32(float addrspace(1)* noalias %out, i16 addrspace(1)* noalias %in) nounwind {
   %val = load i16 addrspace(1)* %in, align 2
-  %cvt = call float @llvm.convert.from.fp16(i16 %val) nounwind readnone
+  %cvt = call float @llvm.convert.from.fp16.f32(i16 %val) nounwind readnone
   store float %cvt, float addrspace(1)* %out, align 4
   ret void
 }
diff --git a/llvm/test/CodeGen/X86/cvt16.ll b/llvm/test/CodeGen/X86/cvt16.ll
index 951b5c3..f3d8049 100644
--- a/llvm/test/CodeGen/X86/cvt16.ll
+++ b/llvm/test/CodeGen/X86/cvt16.ll
@@ -21,7 +21,7 @@
 
 
 define void @test1(float %src, i16* %dest) {
-  %1 = tail call i16 @llvm.convert.to.fp16(float %src)
+  %1 = tail call i16 @llvm.convert.to.fp16.f32(float %src)
   store i16 %1, i16* %dest, align 2
   ret void
 }
@@ -34,7 +34,7 @@
 
 define float @test2(i16* nocapture %src) {
   %1 = load i16* %src, align 2
-  %2 = tail call float @llvm.convert.from.fp16(i16 %1)
+  %2 = tail call float @llvm.convert.from.fp16.f32(i16 %1)
   ret float %2
 }
 ; CHECK-LABEL: test2:
@@ -45,8 +45,8 @@
 
 
 define float @test3(float %src) nounwind uwtable readnone {
-  %1 = tail call i16 @llvm.convert.to.fp16(float %src)
-  %2 = tail call float @llvm.convert.from.fp16(i16 %1)
+  %1 = tail call i16 @llvm.convert.to.fp16.f32(float %src)
+  %2 = tail call float @llvm.convert.from.fp16.f32(i16 %1)
   ret float %2
 }
 
@@ -59,6 +59,6 @@
 ; F16C-NEXT: vcvtph2ps
 ; F16C: ret
 
-declare float @llvm.convert.from.fp16(i16) nounwind readnone
-declare i16 @llvm.convert.to.fp16(float) nounwind readnone
+declare float @llvm.convert.from.fp16.f32(i16) nounwind readnone
+declare i16 @llvm.convert.to.fp16.f32(float) nounwind readnone