diff options
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMLegalizerInfo.cpp | 11 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir | 143 |
3 files changed, 173 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 4fcb6a639d8..773e51c6e34 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -154,6 +154,10 @@ static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType, return RTLIB::getFPTOSINT(FromMVT, ToMVT); case TargetOpcode::G_FPTOUI: return RTLIB::getFPTOUINT(FromMVT, ToMVT); + case TargetOpcode::G_SITOFP: + return RTLIB::getSINTTOFP(FromMVT, ToMVT); + case TargetOpcode::G_UITOFP: + return RTLIB::getUINTTOFP(FromMVT, ToMVT); } llvm_unreachable("Unsupported libcall function"); } @@ -238,6 +242,21 @@ LegalizerHelper::libcall(MachineInstr &MI) { return Status; break; } + case TargetOpcode::G_SITOFP: + case TargetOpcode::G_UITOFP: { + // FIXME: Support other types + unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); + unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); + if (FromSize != 32 || (ToSize != 32 && ToSize != 64)) + return UnableToLegalize; + LegalizeResult Status = conversionLibcall( + MI, MIRBuilder, + ToSize == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx), + Type::getInt32Ty(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 4082d4e68ab..2d09bcae3d8 100644 --- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp +++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp @@ -192,6 +192,12 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { for (auto Ty : {s32, s64}) setAction({Op, 1, Ty}, Legal); } + + for (unsigned Op : {G_SITOFP, G_UITOFP}) { + setAction({Op, 1, s32}, Legal); + for (auto Ty : {s32, s64}) + setAction({Op, Ty}, Legal); + } } else { for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) for (auto Ty : {s32, s64}) @@ -218,6 +224,11 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { setAction({Op, 1, s64}, Libcall); } + for (unsigned Op : {G_SITOFP, G_UITOFP}) { + for (auto Ty : {s32, s64}) + setAction({Op, Ty}, 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 152cb81d749..f38107666f7 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir @@ -34,6 +34,11 @@ define void @test_fptoui_float() { ret void } define void @test_fptoui_double() { ret void } + define void @test_sitofp_float() { ret void } + define void @test_sitofp_double() { ret void } + define void @test_uitofp_float() { ret void } + define void @test_uitofp_double() { ret void } + define void @test_fcmp_true_s32() { ret void } define void @test_fcmp_false_s32() { ret void } @@ -955,6 +960,144 @@ body: | %r0 = COPY %3(s32) BX_RET 14, %noreg, implicit %r0 ... +--- +name: test_sitofp_float +# CHECK-LABEL: name: test_sitofp_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_SITOFP [[X]] + ; SOFT-NOT: G_SITOFP + ; SOFT: ADJCALLSTACKDOWN + ; SOFT-DAG: %r0 = COPY [[X]] + ; SOFT-AEABI: BL &__aeabi_i2f, {{.*}}, implicit %r0, implicit-def %r0 + ; SOFT-DEFAULT: BL &__floatsisf, {{.*}}, implicit %r0, implicit-def %r0 + ; SOFT: [[R:%[0-9]+]]:_(s32) = COPY %r0 + ; SOFT: ADJCALLSTACKUP + ; SOFT-NOT: G_SITOFP + %1(s32) = G_SITOFP %0(s32) + ; CHECK: %r0 = COPY [[R]] + %r0 = COPY %1(s32) + BX_RET 14, %noreg, implicit %r0 +... +--- +name: test_sitofp_double +# CHECK-LABEL: name: test_sitofp_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: [[X:%[0-9]+]]:_(s32) = COPY %r0 + %0(s32) = COPY %r0 + ; HARD: [[R:%[0-9]+]]:_(s64) = G_SITOFP [[X]] + ; SOFT-NOT: G_SITOFP + ; SOFT: ADJCALLSTACKDOWN + ; SOFT: %r0 = COPY [[X]] + ; SOFT-AEABI: BL &__aeabi_i2d, {{.*}}, implicit %r0, implicit-def %r0, implicit-def %r1 + ; SOFT-DEFAULT: BL &__floatsidf, {{.*}}, implicit %r0, implicit-def %r0, implicit-def %r1 + ; SOFT-DAG: [[R0:%[0-9]+]]:_(s32) = COPY %r0 + ; SOFT-DAG: [[R1:%[0-9]+]]:_(s32) = COPY %r1 + ; SOFT: ADJCALLSTACKUP + ; SOFT-NOT: G_SITOFP + %1(s64) = G_SITOFP %0(s32) + ; HARD: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[R]] + %2(s32), %3(s32) = G_UNMERGE_VALUES %1(s64) + ; CHECK-DAG: %r0 = COPY [[R0]](s32) + ; CHECK-DAG: %r1 = COPY [[R1]](s32) + %r0 = COPY %2(s32) + %r1 = COPY %3(s32) + BX_RET 14, %noreg, implicit %r0, implicit %r1 +... +--- +name: test_uitofp_float +# CHECK-LABEL: name: test_uitofp_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_UITOFP [[X]] + ; SOFT-NOT: G_UITOFP + ; SOFT: ADJCALLSTACKDOWN + ; SOFT-DAG: %r0 = COPY [[X]] + ; SOFT-AEABI: BL &__aeabi_ui2f, {{.*}}, implicit %r0, implicit-def %r0 + ; SOFT-DEFAULT: BL &__floatunsisf, {{.*}}, implicit %r0, implicit-def %r0 + ; SOFT: [[R:%[0-9]+]]:_(s32) = COPY %r0 + ; SOFT: ADJCALLSTACKUP + ; SOFT-NOT: G_UITOFP + %1(s32) = G_UITOFP %0(s32) + ; CHECK: %r0 = COPY [[R]] + %r0 = COPY %1(s32) + BX_RET 14, %noreg, implicit %r0 +... +--- +name: test_uitofp_double +# CHECK-LABEL: name: test_uitofp_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: [[X:%[0-9]+]]:_(s32) = COPY %r0 + %0(s32) = COPY %r0 + ; HARD: [[R:%[0-9]+]]:_(s64) = G_UITOFP [[X]] + ; SOFT-NOT: G_UITOFP + ; SOFT: ADJCALLSTACKDOWN + ; SOFT: %r0 = COPY [[X]] + ; SOFT-AEABI: BL &__aeabi_ui2d, {{.*}}, implicit %r0, implicit-def %r0, implicit-def %r1 + ; SOFT-DEFAULT: BL &__floatunsidf, {{.*}}, implicit %r0, implicit-def %r0, implicit-def %r1 + ; SOFT-DAG: [[R0:%[0-9]+]]:_(s32) = COPY %r0 + ; SOFT-DAG: [[R1:%[0-9]+]]:_(s32) = COPY %r1 + ; SOFT: ADJCALLSTACKUP + ; SOFT-NOT: G_UITOFP + %1(s64) = G_UITOFP %0(s32) + ; HARD: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[R]] + %2(s32), %3(s32) = G_UNMERGE_VALUES %1(s64) + ; CHECK-DAG: %r0 = COPY [[R0]](s32) + ; CHECK-DAG: %r1 = COPY [[R1]](s32) + %r0 = COPY %2(s32) + %r1 = COPY %3(s32) + BX_RET 14, %noreg, implicit %r0, implicit %r1 +... ... name: test_fcmp_true_s32 # CHECK-LABEL: name: test_fcmp_true_s32 |