From 4faefeda45b7b6222208ece8e8944ddc64474801 Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Tue, 30 Jan 2018 07:54:52 +0000 Subject: [PATCH] [ARM GlobalISel] Legalize G_FPTOSI and G_FPTOUI Legal if we have hardware support for floating point, libcalls otherwise. Also add the necessary support for libcalls in the legalizer helper. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@323726 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 18 +++ lib/Target/ARM/ARMLegalizerInfo.cpp | 15 +- .../ARM/GlobalISel/arm-legalize-fp.mir | 143 ++++++++++++++++++ 3 files changed, 173 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 2121b7229587..4fcb6a639d8a 100644 --- a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -150,6 +150,10 @@ static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType, return RTLIB::getFPEXT(FromMVT, ToMVT); case TargetOpcode::G_FPTRUNC: return RTLIB::getFPROUND(FromMVT, ToMVT); + case TargetOpcode::G_FPTOSI: + return RTLIB::getFPTOSINT(FromMVT, ToMVT); + case TargetOpcode::G_FPTOUI: + return RTLIB::getFPTOUINT(FromMVT, ToMVT); } llvm_unreachable("Unsupported libcall function"); } @@ -220,6 +224,20 @@ LegalizerHelper::libcall(MachineInstr &MI) { return Status; break; } + case TargetOpcode::G_FPTOSI: + case TargetOpcode::G_FPTOUI: { + // FIXME: Support other types + unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); + unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); + if (ToSize != 32 || (FromSize != 32 && FromSize != 64)) + return UnableToLegalize; + LegalizeResult Status = conversionLibcall( + MI, MIRBuilder, Type::getInt32Ty(Ctx), + FromSize == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx)); + if (Status != Legalized) + return Status; + break; + } } MI.eraseFromParent(); diff --git a/lib/Target/ARM/ARMLegalizerInfo.cpp b/lib/Target/ARM/ARMLegalizerInfo.cpp index 690017df6852..4082d4e68abf 100644 --- a/lib/Target/ARM/ARMLegalizerInfo.cpp +++ b/lib/Target/ARM/ARMLegalizerInfo.cpp @@ -134,9 +134,6 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { setAction({G_PTRTOINT, s32}, Legal); setAction({G_PTRTOINT, 1, p0}, Legal); - setAction({G_FPTOSI, s32}, Legal); - setAction({G_FPTOSI, 1, s32}, Legal); - for (unsigned Op : {G_ASHR, G_LSHR, G_SHL}) setAction({Op, s32}, Legal); @@ -189,6 +186,12 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { setAction({G_FPTRUNC, s32}, Legal); setAction({G_FPTRUNC, 1, s64}, Legal); + + for (unsigned Op : {G_FPTOSI, G_FPTOUI}) { + setAction({Op, s32}, Legal); + for (auto Ty : {s32, s64}) + setAction({Op, 1, Ty}, Legal); + } } else { for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) for (auto Ty : {s32, s64}) @@ -209,6 +212,12 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { setAction({G_FPTRUNC, s32}, Legal); setAction({G_FPTRUNC, 1, s64}, Libcall); + for (unsigned Op : {G_FPTOSI, G_FPTOUI}) { + setAction({Op, s32}, Legal); + setAction({Op, 1, s32}, Libcall); + setAction({Op, 1, s64}, Libcall); + } + if (AEABI(ST)) setFCmpLibcallsAEABI(); else diff --git a/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir b/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir index 297eb6f28f6d..152cb81d749a 100644 --- a/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir +++ b/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir @@ -29,6 +29,11 @@ define void @test_fpext_float_to_double() { ret void } define void @test_fptrunc_double_to_float() { ret void } + define void @test_fptosi_float() { ret void } + define void @test_fptosi_double() { ret void } + define void @test_fptoui_float() { ret void } + define void @test_fptoui_double() { ret void } + define void @test_fcmp_true_s32() { ret void } define void @test_fcmp_false_s32() { ret void } @@ -812,6 +817,144 @@ body: | %r0 = COPY %3(s32) BX_RET 14, %noreg, implicit %r0 --- +--- +name: test_fptosi_float +# CHECK-LABEL: name: test_fptosi_float +legalized: false +# CHECK: legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %r0 + + ; CHECK-DAG: [[X:%[0-9]+]]:_(s32) = COPY %r0 + %0(s32) = COPY %r0 + ; HARD: [[R:%[0-9]+]]:_(s32) = G_FPTOSI [[X]] + ; SOFT-NOT: G_FPTOSI + ; SOFT: ADJCALLSTACKDOWN + ; SOFT-DAG: %r0 = COPY [[X]] + ; SOFT-AEABI: BL &__aeabi_f2iz, {{.*}}, implicit %r0, implicit-def %r0 + ; SOFT-DEFAULT: BL &__fixsfsi, {{.*}}, implicit %r0, implicit-def %r0 + ; SOFT: [[R:%[0-9]+]]:_(s32) = COPY %r0 + ; SOFT: ADJCALLSTACKUP + ; SOFT-NOT: G_FPTOSI + %1(s32) = G_FPTOSI %0(s32) + ; CHECK: %r0 = COPY [[R]] + %r0 = COPY %1(s32) + BX_RET 14, %noreg, implicit %r0 +... +--- +name: test_fptosi_double +# CHECK-LABEL: name: test_fptosi_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, %r1 + + ; CHECK-DAG: [[X0:%[0-9]+]]:_(s32) = COPY %r0 + ; CHECK-DAG: [[X1:%[0-9]+]]:_(s32) = COPY %r1 + %0(s32) = COPY %r0 + %1(s32) = COPY %r1 + ; HARD: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[X0]] + %2(s64) = G_MERGE_VALUES %0(s32), %1(s32) + ; HARD: [[R:%[0-9]+]]:_(s32) = G_FPTOSI [[X]] + ; SOFT-NOT: G_FPTOSI + ; SOFT: ADJCALLSTACKDOWN + ; SOFT-DAG: %r{{[0-1]}} = COPY [[X0]] + ; SOFT-DAG: %r{{[0-1]}} = COPY [[X1]] + ; SOFT-AEABI: BL &__aeabi_d2iz, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0 + ; SOFT-DEFAULT: BL &__fixdfsi, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0 + ; SOFT: [[R:%[0-9]+]]:_(s32) = COPY %r0 + ; SOFT: ADJCALLSTACKUP + ; SOFT-NOT: G_FPTOSI + %3(s32) = G_FPTOSI %2(s64) + ; CHECK: %r0 = COPY [[R]](s32) + %r0 = COPY %3(s32) + BX_RET 14, %noreg, implicit %r0 +... +--- +name: test_fptoui_float +# CHECK-LABEL: name: test_fptoui_float +legalized: false +# CHECK: legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %r0 + + ; CHECK-DAG: [[X:%[0-9]+]]:_(s32) = COPY %r0 + %0(s32) = COPY %r0 + ; HARD: [[R:%[0-9]+]]:_(s32) = G_FPTOUI [[X]] + ; SOFT-NOT: G_FPTOUI + ; SOFT: ADJCALLSTACKDOWN + ; SOFT-DAG: %r0 = COPY [[X]] + ; SOFT-AEABI: BL &__aeabi_f2uiz, {{.*}}, implicit %r0, implicit-def %r0 + ; SOFT-DEFAULT: BL &__fixunssfsi, {{.*}}, implicit %r0, implicit-def %r0 + ; SOFT: [[R:%[0-9]+]]:_(s32) = COPY %r0 + ; SOFT: ADJCALLSTACKUP + ; SOFT-NOT: G_FPTOUI + %1(s32) = G_FPTOUI %0(s32) + ; CHECK: %r0 = COPY [[R]] + %r0 = COPY %1(s32) + BX_RET 14, %noreg, implicit %r0 +... +--- +name: test_fptoui_double +# CHECK-LABEL: name: test_fptoui_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, %r1 + + ; CHECK-DAG: [[X0:%[0-9]+]]:_(s32) = COPY %r0 + ; CHECK-DAG: [[X1:%[0-9]+]]:_(s32) = COPY %r1 + %0(s32) = COPY %r0 + %1(s32) = COPY %r1 + ; HARD: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[X0]] + %2(s64) = G_MERGE_VALUES %0(s32), %1(s32) + ; HARD: [[R:%[0-9]+]]:_(s32) = G_FPTOUI [[X]] + ; SOFT-NOT: G_FPTOUI + ; SOFT: ADJCALLSTACKDOWN + ; SOFT-DAG: %r{{[0-1]}} = COPY [[X0]] + ; SOFT-DAG: %r{{[0-1]}} = COPY [[X1]] + ; SOFT-AEABI: BL &__aeabi_d2uiz, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0 + ; SOFT-DEFAULT: BL &__fixunsdfsi, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0 + ; SOFT: [[R:%[0-9]+]]:_(s32) = COPY %r0 + ; SOFT: ADJCALLSTACKUP + ; SOFT-NOT: G_FPTOUI + %3(s32) = G_FPTOUI %2(s64) + ; CHECK: %r0 = COPY [[R]](s32) + %r0 = COPY %3(s32) + BX_RET 14, %noreg, implicit %r0 +... ... name: test_fcmp_true_s32 # CHECK-LABEL: name: test_fcmp_true_s32