diff options
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 47 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMLegalizerInfo.cpp | 12 | ||||
| -rw-r--r-- | llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir | 79 |
3 files changed, 138 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 200d6b8abec..f1cb5c0ad02 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -126,6 +126,7 @@ llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, 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, MachineIRBuilder &MIRBuilder, unsigned Size, 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()); @@ -172,6 +195,30 @@ LegalizerHelper::libcall(MachineInstr &MI) { 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; + } } MI.eraseFromParent(); diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp index 3e694b80f80..7b560088510 100644 --- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp +++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp @@ -178,6 +178,12 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { 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 ARMSubtarget &ST) { 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 diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir index 4b93610ab99..297eb6f28f6 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir @@ -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 |

