[PATCH] [X86][FastISel] Teach how to select float-half conversion intrinsics.
Andrea Di Biagio
Andrea_DiBiagio at sn.scee.net
Mon Feb 16 08:46:43 PST 2015
Hi mkuper, ributzka, qcolombet,
This patch teaches X86FastISel how to select intrinsic 'convert_from_fp16' and intrinsic 'convert_to_fp16'.
If the target has F16C (and no -soft-float), we can select instruction VCVTPS2PHrr for a float-to-half conversion, and VCVTPH2PSrr for a half-to-float conversion.
Added test fast-isel-float-half-convertion.ll to check that fast-isel doesn't fail to select float-half conversions if the target has F16C.
Please let me know if ok to submit.
Thanks,
Andrea
http://reviews.llvm.org/D7673
Files:
lib/Target/X86/X86FastISel.cpp
test/CodeGen/X86/fast-isel-float-half-convertion.ll
Index: lib/Target/X86/X86FastISel.cpp
===================================================================
--- lib/Target/X86/X86FastISel.cpp
+++ lib/Target/X86/X86FastISel.cpp
@@ -2136,6 +2136,60 @@
// FIXME: Handle more intrinsics.
switch (II->getIntrinsicID()) {
default: return false;
+ case Intrinsic::convert_from_fp16:
+ case Intrinsic::convert_to_fp16: {
+ if (TM.Options.UseSoftFloat || !Subtarget->hasF16C())
+ return false;
+
+ const Value *Op = II->getArgOperand(0);
+ bool IsFloatToHalf = II->getIntrinsicID() == Intrinsic::convert_to_fp16;
+ // F16C allows converting from float to half and from half to float.
+ // In the case of float-to-half conversion, the type must be a float.
+ if (IsFloatToHalf && !Op->getType()->isFloatTy())
+ return false;
+
+ unsigned InputReg = getRegForValue(Op);
+ if (!IsFloatToHalf) {
+ assert(Op->getType()->isIntegerTy(16) && "Expected a 16-bit integer!");
+ // Explicitly sign-extend the input value to 32-bit.
+ InputReg = fastEmit_r(MVT::i16, MVT::i32, ISD::SIGN_EXTEND,
+ InputReg, /*Kill=*/false);
+ }
+
+ // Copy to a vector (VR128) register class.
+ const TargetRegisterClass *RC = TLI.getRegClassFor(MVT::v8i16);
+ unsigned ResultReg = createResultReg(RC);
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+ TII.get(TargetOpcode::COPY), ResultReg).addReg(InputReg);
+ InputReg = ResultReg;
+
+ // Now generate a VCVTPS2PHrr/VCVTPH2PSrr.
+ ResultReg = createResultReg(RC);
+ unsigned Opc = IsFloatToHalf ? X86::VCVTPS2PHrr : X86::VCVTPH2PSrr;
+ MachineInstrBuilder MIB;
+ MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
+ ResultReg).addReg(InputReg, RegState::Kill);
+ if (IsFloatToHalf)
+ // Instruction VCVTPS2PHrr requires an extra immediate operand that
+ // provides rounding control.
+ MIB.addImm(0);
+ InputReg = ResultReg;
+
+ // Emit another copy to register class.
+ RC = IsFloatToHalf ? &X86::GR32RegClass : &X86::FR32RegClass;
+ ResultReg = createResultReg(RC);
+ MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+ TII.get(TargetOpcode::COPY), ResultReg);
+ MIB.addReg(InputReg, RegState::Kill);
+
+ if (IsFloatToHalf)
+ // In the case of float-to-half conversions, the half float is in
+ // the lower 16-bits of ResultReg.
+ ResultReg = fastEmitInst_extractsubreg(MVT::i16, ResultReg, /*Kill=*/true,
+ X86::sub_16bit);
+ updateValueMap(II, ResultReg);
+ return true;
+ }
case Intrinsic::frameaddress: {
MachineFunction *MF = FuncInfo.MF;
if (MF->getTarget().getMCAsmInfo()->usesWindowsCFI())
Index: test/CodeGen/X86/fast-isel-float-half-convertion.ll
===================================================================
--- test/CodeGen/X86/fast-isel-float-half-convertion.ll
+++ test/CodeGen/X86/fast-isel-float-half-convertion.ll
@@ -0,0 +1,21 @@
+; RUN: llc -O0 -fast-isel-abort -mtriple=x86_64-unknown-unknown -mattr=+f16c < %s | FileCheck %s
+
+define i16 @test_fp32_to_fp16(float %a) {
+; CHECK-LABEL: test_fp32_to_fp16:
+; CHECK: vcvtps2ph
+entry:
+ %0 = call i16 @llvm.convert.to.fp16.f32(float %a)
+ ret i16 %0
+}
+
+define float @test_fp16_to_fp32(i16 signext %a) {
+; CHECK-LABEL: test_fp16_to_fp32:
+; CHECK: vcvtph2ps
+entry:
+ %0 = call float @llvm.convert.from.fp16.f32(i16 %a)
+ ret float %0
+}
+
+
+declare i16 @llvm.convert.to.fp16.f32(float)
+declare float @llvm.convert.from.fp16.f32(i16)
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7673.20036.patch
Type: text/x-patch
Size: 3596 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150216/58782850/attachment.bin>
More information about the llvm-commits
mailing list