[llvm] r322651 - [ARM GlobalISel] Legalize G_FPEXT and G_FPTRUNC
Diana Picus via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 17 05:34:11 PST 2018
Author: rovka
Date: Wed Jan 17 05:34:10 2018
New Revision: 322651
URL: http://llvm.org/viewvc/llvm-project?rev=322651&view=rev
Log:
[ARM GlobalISel] Legalize G_FPEXT and G_FPTRUNC
Mark G_FPEXT and G_FPTRUNC as legal or libcall, depending on hardware
support, but only for conversions between float and double.
Also add the necessary boilerplate so that the LegalizerHelper can
introduce the required libcalls. This also works only for float and
double, but isn't too difficult to extend when the need arises.
Modified:
llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir
Modified: llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp?rev=322651&r1=322650&r2=322651&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp Wed Jan 17 05:34:10 2018
@@ -126,6 +126,7 @@ llvm::createLibcall(MachineIRBuilder &MI
return LegalizerHelper::Legalized;
}
+// Useful for libcalls where all operands have the same type.
static LegalizerHelper::LegalizeResult
simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
Type *OpType) {
@@ -138,6 +139,28 @@ simpleLibcall(MachineInstr &MI, MachineI
Args);
}
+static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType,
+ Type *FromType) {
+ auto ToMVT = MVT::getVT(ToType);
+ auto FromMVT = MVT::getVT(FromType);
+
+ switch (Opcode) {
+ case TargetOpcode::G_FPEXT:
+ return RTLIB::getFPEXT(FromMVT, ToMVT);
+ case TargetOpcode::G_FPTRUNC:
+ return RTLIB::getFPROUND(FromMVT, ToMVT);
+ }
+ llvm_unreachable("Unsupported libcall function");
+}
+
+static LegalizerHelper::LegalizeResult
+conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType,
+ Type *FromType) {
+ RTLIB::Libcall Libcall = getConvRTLibDesc(MI.getOpcode(), ToType, FromType);
+ return createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ToType},
+ {{MI.getOperand(1).getReg(), FromType}});
+}
+
LegalizerHelper::LegalizeResult
LegalizerHelper::libcall(MachineInstr &MI) {
LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
@@ -171,6 +194,30 @@ LegalizerHelper::libcall(MachineInstr &M
if (Status != Legalized)
return Status;
break;
+ }
+ case TargetOpcode::G_FPEXT: {
+ // FIXME: Support other floating point types (half, fp128 etc)
+ unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
+ unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
+ if (ToSize != 64 || FromSize != 32)
+ return UnableToLegalize;
+ LegalizeResult Status = conversionLibcall(
+ MI, MIRBuilder, Type::getDoubleTy(Ctx), Type::getFloatTy(Ctx));
+ if (Status != Legalized)
+ return Status;
+ break;
+ }
+ case TargetOpcode::G_FPTRUNC: {
+ // FIXME: Support other floating point types (half, fp128 etc)
+ unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
+ unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
+ if (ToSize != 32 || FromSize != 64)
+ return UnableToLegalize;
+ LegalizeResult Status = conversionLibcall(
+ MI, MIRBuilder, Type::getFloatTy(Ctx), Type::getDoubleTy(Ctx));
+ if (Status != Legalized)
+ return Status;
+ break;
}
}
Modified: llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp?rev=322651&r1=322650&r2=322651&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp Wed Jan 17 05:34:10 2018
@@ -178,6 +178,12 @@ ARMLegalizerInfo::ARMLegalizerInfo(const
setAction({G_MERGE_VALUES, 1, s32}, Legal);
setAction({G_UNMERGE_VALUES, s32}, Legal);
setAction({G_UNMERGE_VALUES, 1, s64}, Legal);
+
+ setAction({G_FPEXT, s64}, Legal);
+ setAction({G_FPEXT, 1, s32}, Legal);
+
+ setAction({G_FPTRUNC, s32}, Legal);
+ setAction({G_FPTRUNC, 1, s64}, Legal);
} else {
for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
for (auto Ty : {s32, s64})
@@ -192,6 +198,12 @@ ARMLegalizerInfo::ARMLegalizerInfo(const
setAction({G_FCMP, 1, s32}, Custom);
setAction({G_FCMP, 1, s64}, Custom);
+ setAction({G_FPEXT, s64}, Legal);
+ setAction({G_FPEXT, 1, s32}, Libcall);
+
+ setAction({G_FPTRUNC, s32}, Legal);
+ setAction({G_FPTRUNC, 1, s64}, Libcall);
+
if (AEABI(ST))
setFCmpLibcallsAEABI();
else
Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir?rev=322651&r1=322650&r2=322651&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir (original)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir Wed Jan 17 05:34:10 2018
@@ -26,6 +26,9 @@
define void @test_fneg_float() { ret void }
define void @test_fneg_double() { ret void }
+ define void @test_fpext_float_to_double() { ret void }
+ define void @test_fptrunc_double_to_float() { ret void }
+
define void @test_fcmp_true_s32() { ret void }
define void @test_fcmp_false_s32() { ret void }
@@ -734,6 +737,82 @@ body: |
BX_RET 14, %noreg, implicit %r0, implicit %r1
...
---
+name: test_fpext_float_to_double
+# CHECK-LABEL: name: test_fpext_float_to_double
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+ - { id: 3, class: _ }
+body: |
+ bb.0:
+ liveins: %r0
+
+ ; CHECK-DAG: [[X:%[0-9]+]]:_(s32) = COPY %r0
+ %0(s32) = COPY %r0
+ ; HARD: [[R:%[0-9]+]]:_(s64) = G_FPEXT [[X]]
+ ; SOFT-NOT: G_FPEXT
+ ; SOFT: ADJCALLSTACKDOWN
+ ; SOFT-DAG: %r0 = COPY [[X]]
+ ; SOFT-AEABI: BL &__aeabi_f2d, {{.*}}, implicit %r0, implicit-def %r0, implicit-def %r1
+ ; SOFT-DEFAULT: BL &__extendsfdf2, {{.*}}, implicit %r0, implicit-def %r0, implicit-def %r1
+ ; SOFT: [[R0:%[0-9]+]]:_(s32) = COPY %r0
+ ; SOFT: [[R1:%[0-9]+]]:_(s32) = COPY %r1
+ ; SOFT: ADJCALLSTACKUP
+ ; SOFT-NOT: G_FPEXT
+ %1(s64) = G_FPEXT %0(s32)
+ ; HARD: G_UNMERGE_VALUES [[R]](s64)
+ ; SOFT-DAG: %r{{[0-1]}} = COPY [[R0]]
+ ; SOFT-DAG: %r{{[0-1]}} = COPY [[R1]]
+ %2(s32), %3(s32) = G_UNMERGE_VALUES %1(s64)
+ %r0 = COPY %2(s32)
+ %r1 = COPY %3(s32)
+ BX_RET 14, %noreg, implicit %r0, implicit %r1
+...
+---
+name: test_fptrunc_double_to_float
+# CHECK-LABEL: name: test_fptrunc_double_to_float
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+ - { id: 3, class: _ }
+body: |
+ bb.0:
+ liveins: %r0, %r1
+
+ ; CHECK-DAG: [[X0:%[0-9]+]]:_(s32) = COPY %r0
+ ; CHECK-DAG: [[X1:%[0-9]+]]:_(s32) = COPY %r1
+ ; HARD: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[X0]]
+ %0(s32) = COPY %r0
+ %1(s32) = COPY %r1
+ %2(s64) = G_MERGE_VALUES %0(s32), %1(s32)
+ ; HARD: [[R:%[0-9]+]]:_(s32) = G_FPTRUNC [[X]]
+ ; SOFT-NOT: G_FPTRUNC
+ ; SOFT: ADJCALLSTACKDOWN
+ ; SOFT-DAG: %r0 = COPY [[X0]]
+ ; SOFT-DAG: %r1 = COPY [[X1]]
+ ; SOFT-AEABI: BL &__aeabi_d2f, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+ ; SOFT-DEFAULT: BL &__truncdfsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+ ; SOFT: [[R:%[0-9]+]]:_(s32) = COPY %r0
+ ; SOFT: ADJCALLSTACKUP
+ ; SOFT-NOT: G_FPTRUNC
+ %3(s32) = G_FPTRUNC %2(s64)
+ ; CHECK: %r0 = COPY [[R]]
+ %r0 = COPY %3(s32)
+ BX_RET 14, %noreg, implicit %r0
+---
+...
name: test_fcmp_true_s32
# CHECK-LABEL: name: test_fcmp_true_s32
legalized: false
More information about the llvm-commits
mailing list