Skip to content

Commit

Permalink
[ARM GlobalISel] Legalize G_FPTOSI and G_FPTOUI
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rovka committed Jan 30, 2018
1 parent c2a5bf9 commit 4faefed
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 3 deletions.
18 changes: 18 additions & 0 deletions lib/CodeGen/GlobalISel/LegalizerHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down Expand Up @@ -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();
Expand Down
15 changes: 12 additions & 3 deletions lib/Target/ARM/ARMLegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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})
Expand All @@ -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
Expand Down
143 changes: 143 additions & 0 deletions test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 4faefed

Please sign in to comment.