Hi, all: I am trying to test half float point support in llvm, I found clang can generate bitcode for __fp16, while llc can't generate code for it, the error message is like this LLVM ERROR: Cannot select: 0x26a68e0: i16 = fp32_to_fp16 0x26a67d8 [ORD=2] [ID=4] 0x26a67d8: f32,ch = CopyFromReg 0x2693060, 0x26a66d0 [ORD=2] [ID=3] 0x26a66d0: f32 = Register %vreg1 [ID=1] In function: test Anyone know what is the problem; I just suspect intrinsic " llvm.convert.to.fp16" is not well implemented? Attaching my test: #test.c clang -cc1 -O0 test.c -emit-llvm -o test.bc typedef __fp16 half; void test() { half x = 0.1f; x += 2.0f; half y = x + x; } The generated bitcode: llc -O0 test.bc ; ModuleID = 'test.c' target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" ; Function Attrs: nounwind define void @test() #0 { %x = alloca i16, align 2 %y = alloca i16, align 2 %1 = call i16 @llvm.convert.to.fp16(float 0x3FB99999A0000000) store i16 %1, i16* %x, align 2 %2 = load i16* %x, align 2 %3 = call float @llvm.convert.from.fp16(i16 %2) %4 = fadd float %3, 2.000000e+00 %5 = call i16 @llvm.convert.to.fp16(float %4) store i16 %5, i16* %x, align 2 %6 = load i16* %x, align 2 %7 = call float @llvm.convert.from.fp16(i16 %6) %8 = load i16* %x, align 2 %9 = call float @llvm.convert.from.fp16(i16 %8) %10 = fadd float %7, %9 %11 = call i16 @llvm.convert.to.fp16(float %10) store i16 %11, i16* %y, align 2 ret void } ; Function Attrs: nounwind readnone declare i16 @llvm.convert.to.fp16(float) #1 ; Function Attrs: nounwind readnone declare float @llvm.convert.from.fp16(i16) #1 attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { nounwind readnone } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.5.0 (trunk 211249)"} Thanks Wan Xiaofei
Hi Wan, Unfortunately, on x86 we don't have ISel tablegen patterns to select 'fp32_to_fp16' and fp16_to_fp32' dag nodes. I actually already have a patch that I plan to send (hopefully by the end of today) on the mailing list that implements the missing support for those dag nodes and allows selecting vcvtph2ps/vcvtps2ph instructions if the target supports F16C (I hope this is your case :-) ). If your target doesn't support F16C then things are complicated. We definitely shouldn't crash with a fatal error in the backend and emit instead calls to the compiler runtime. The compiler knows about the existence of libcalls like '__gnu_f2h_ieee' and '__gnu_h2f_ieee2'. However, I am not sure if those are really supported by our compiler runtime... -Andrea On Thu, Jun 19, 2014 at 8:49 AM, Wan, Xiaofei <xiaofei.wan at intel.com> wrote:> Hi, all: > > I am trying to test half float point support in llvm, I found clang can generate bitcode for __fp16, while llc can't generate code for it, the error message is like this > > LLVM ERROR: Cannot select: 0x26a68e0: i16 = fp32_to_fp16 0x26a67d8 [ORD=2] [ID=4] > 0x26a67d8: f32,ch = CopyFromReg 0x2693060, 0x26a66d0 [ORD=2] [ID=3] > 0x26a66d0: f32 = Register %vreg1 [ID=1] > In function: test > > Anyone know what is the problem; I just suspect intrinsic " llvm.convert.to.fp16" is not well implemented? > > Attaching my test: > > #test.c clang -cc1 -O0 test.c -emit-llvm -o test.bc > typedef __fp16 half; > void test() > { > half x = 0.1f; > x += 2.0f; > half y = x + x; > } > > The generated bitcode: > > llc -O0 test.bc > > ; ModuleID = 'test.c' > target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" > target triple = "x86_64-unknown-linux-gnu" > > ; Function Attrs: nounwind > define void @test() #0 { > %x = alloca i16, align 2 > %y = alloca i16, align 2 > %1 = call i16 @llvm.convert.to.fp16(float 0x3FB99999A0000000) > store i16 %1, i16* %x, align 2 > %2 = load i16* %x, align 2 > %3 = call float @llvm.convert.from.fp16(i16 %2) > %4 = fadd float %3, 2.000000e+00 > %5 = call i16 @llvm.convert.to.fp16(float %4) > store i16 %5, i16* %x, align 2 > %6 = load i16* %x, align 2 > %7 = call float @llvm.convert.from.fp16(i16 %6) > %8 = load i16* %x, align 2 > %9 = call float @llvm.convert.from.fp16(i16 %8) > %10 = fadd float %7, %9 > %11 = call i16 @llvm.convert.to.fp16(float %10) > store i16 %11, i16* %y, align 2 > ret void > } > > ; Function Attrs: nounwind readnone > declare i16 @llvm.convert.to.fp16(float) #1 > > ; Function Attrs: nounwind readnone > declare float @llvm.convert.from.fp16(i16) #1 > > attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } > attributes #1 = { nounwind readnone } > > !llvm.ident = !{!0} > > !0 = metadata !{metadata !"clang version 3.5.0 (trunk 211249)"} > > Thanks > Wan Xiaofei > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Thanks, Andrea. I notice that currently for ARM, it use libcall '__gnu_f2h_ieee' and '__gnu_h2f_ieee2' for 'fp32_to_fp16' and fp16_to_fp32'. Are these two libcalls in glibc? I don't find them in c/c++ runtime libraries. I just want to test fp16 support on common x86 platforms so I am not sure whether it supports F16C, based on my knowledge F16C is not supported on common x86 platform. It is possible not to call compiler intrinsics to do 'fp32_to_fp16' and fp16_to_fp32' when generating BC? Call external functions instead, any runtime which wants to support fp16 should implement these two conversion functions. Thanks Wan Xiaofei -----Original Message----- From: Andrea Di Biagio [mailto:andrea.dibiagio at gmail.com] Sent: Thursday, June 19, 2014 8:41 PM To: Wan, Xiaofei Cc: llvmdev at cs.uiuc.edu Subject: Re: [LLVMdev] __fp16 suport in llvm back-end Hi Wan, Unfortunately, on x86 we don't have ISel tablegen patterns to select 'fp32_to_fp16' and fp16_to_fp32' dag nodes. I actually already have a patch that I plan to send (hopefully by the end of today) on the mailing list that implements the missing support for those dag nodes and allows selecting vcvtph2ps/vcvtps2ph instructions if the target supports F16C (I hope this is your case :-) ). If your target doesn't support F16C then things are complicated. We definitely shouldn't crash with a fatal error in the backend and emit instead calls to the compiler runtime. The compiler knows about the existence of libcalls like '__gnu_f2h_ieee' and '__gnu_h2f_ieee2'. However, I am not sure if those are really supported by our compiler runtime... -Andrea On Thu, Jun 19, 2014 at 8:49 AM, Wan, Xiaofei <xiaofei.wan at intel.com> wrote:> Hi, all: > > I am trying to test half float point support in llvm, I found clang > can generate bitcode for __fp16, while llc can't generate code for it, > the error message is like this > > LLVM ERROR: Cannot select: 0x26a68e0: i16 = fp32_to_fp16 0x26a67d8 [ORD=2] [ID=4] > 0x26a67d8: f32,ch = CopyFromReg 0x2693060, 0x26a66d0 [ORD=2] [ID=3] > 0x26a66d0: f32 = Register %vreg1 [ID=1] In function: test > > Anyone know what is the problem; I just suspect intrinsic " llvm.convert.to.fp16" is not well implemented? > > Attaching my test: > > #test.c clang -cc1 -O0 test.c -emit-llvm -o test.bc typedef __fp16 > half; void test() { > half x = 0.1f; > x += 2.0f; > half y = x + x; > } > > The generated bitcode: > > llc -O0 test.bc > > ; ModuleID = 'test.c' > target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" > target triple = "x86_64-unknown-linux-gnu" > > ; Function Attrs: nounwind > define void @test() #0 { > %x = alloca i16, align 2 > %y = alloca i16, align 2 > %1 = call i16 @llvm.convert.to.fp16(float 0x3FB99999A0000000) > store i16 %1, i16* %x, align 2 > %2 = load i16* %x, align 2 > %3 = call float @llvm.convert.from.fp16(i16 %2) > %4 = fadd float %3, 2.000000e+00 > %5 = call i16 @llvm.convert.to.fp16(float %4) > store i16 %5, i16* %x, align 2 > %6 = load i16* %x, align 2 > %7 = call float @llvm.convert.from.fp16(i16 %6) > %8 = load i16* %x, align 2 > %9 = call float @llvm.convert.from.fp16(i16 %8) > %10 = fadd float %7, %9 > %11 = call i16 @llvm.convert.to.fp16(float %10) > store i16 %11, i16* %y, align 2 > ret void > } > > ; Function Attrs: nounwind readnone > declare i16 @llvm.convert.to.fp16(float) #1 > > ; Function Attrs: nounwind readnone > declare float @llvm.convert.from.fp16(i16) #1 > > attributes #0 = { nounwind "less-precise-fpmad"="false" > "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" > "no-nans-fp-math"="false" "no-realign-stack" > "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" > "use-soft-float"="false" } attributes #1 = { nounwind readnone } > > !llvm.ident = !{!0} > > !0 = metadata !{metadata !"clang version 3.5.0 (trunk 211249)"} > > Thanks > Wan Xiaofei > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Apparently Analagous Threads
- [LLVMdev] Help!!!!Help!!!! " LLVM ERROR: Cannot select: 0x9fc9680: i32 = fp32_to_fp16 0x9fc0750 [ID=16] " problem!!!!!!!!!!!!!!!!!!
- [LLVMdev] Help!!!!Help!!!! " LLVM ERROR: Cannot select: 0x9fc9680: i32 = fp32_to_fp16 0x9fc0750 [ID=16] " problem!!!!!!!!!!!!!!!!!!
- [LLVMdev] Help!!!!Help!!!! " LLVM ERROR: Cannot select: 0x9fc9680: i32 = fp32_to_fp16 0x9fc0750 [ID=16] " problem!!!!!!!!!!!!!!!!!!
- [LLVMdev] RFC: Do we still need @llvm.convert.to.fp16 and the reverse?
- [LLVMdev] Help!!!!Help!!!! " LLVM ERROR: Cannot select: 0x9fc9680: i32 = fp32_to_fp16 0x9fc0750 [ID=16] " problem!!!!!!!!!!!!!!!!!!