From 0a032476a58887e28559d6373db357c2abbbd935 Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Tue, 11 Apr 2017 10:52:34 +0000 Subject: [PATCH] GlobalISel: Allow legalizing G_FADD to a libcall Use the same handling in the generic legalizer code as for the other libcalls (G_FREM, G_FPOW). Enable it on ARM for float and double so we can test it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299931 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 4 + lib/Target/ARM/ARMLegalizerInfo.cpp | 3 + test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll | 24 ++++- .../ARM/GlobalISel/arm-legalize-fp.mir | 94 ++++++++++++++++++- 4 files changed, 119 insertions(+), 6 deletions(-) diff --git a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index afab23d94f0..20358f7ee6c 100644 --- a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -66,6 +66,9 @@ void LegalizerHelper::extractParts(unsigned Reg, LLT Ty, int NumParts, static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) { switch (Opcode) { + case TargetOpcode::G_FADD: + assert((Size == 32 || Size == 64) && "Unsupported size"); + return Size == 64 ? RTLIB::ADD_F64 : RTLIB::ADD_F32; case TargetOpcode::G_FREM: return Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32; case TargetOpcode::G_FPOW: @@ -83,6 +86,7 @@ LegalizerHelper::libcall(MachineInstr &MI) { switch (MI.getOpcode()) { default: return UnableToLegalize; + case TargetOpcode::G_FADD: case TargetOpcode::G_FPOW: case TargetOpcode::G_FREM: { auto &Ctx = MIRBuilder.getMF().getFunction()->getContext(); diff --git a/lib/Target/ARM/ARMLegalizerInfo.cpp b/lib/Target/ARM/ARMLegalizerInfo.cpp index a1097af6e85..994bbd673dd 100644 --- a/lib/Target/ARM/ARMLegalizerInfo.cpp +++ b/lib/Target/ARM/ARMLegalizerInfo.cpp @@ -63,6 +63,9 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { setAction({G_LOAD, s64}, Legal); setAction({G_STORE, s64}, Legal); + } else { + for (auto Ty : {s32, s64}) + setAction({G_FADD, Ty}, Libcall); } for (unsigned Op : {G_FREM, G_FPOW}) diff --git a/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll b/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll index 7ef1b4e3639..7d021fdb43d 100644 --- a/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll +++ b/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll @@ -1,6 +1,6 @@ -; RUN: llc -mtriple arm-gnueabihf -mattr=+vfp2 -float-abi=hard -global-isel %s -o - | FileCheck %s -; RUN: llc -mtriple arm-- -mattr=+vfp2 -float-abi=soft -global-isel %s -o - | FileCheck %s -; RUN: llc -mtriple arm-- -float-abi=soft -global-isel %s -o - | FileCheck %s +; RUN: llc -mtriple arm-linux-gnueabihf -mattr=+vfp2 -float-abi=hard -global-isel %s -o - | FileCheck %s -check-prefix CHECK -check-prefix HARD +; RUN: llc -mtriple arm-linux-gnueabi -mattr=+vfp2,+soft-float -float-abi=soft -global-isel %s -o - | FileCheck %s -check-prefix CHECK -check-prefix SOFT-AEABI +; RUN: llc -mtriple arm-linux-gnu- -mattr=+vfp2,+soft-float -float-abi=soft -global-isel %s -o - | FileCheck %s -check-prefix CHECK -check-prefix SOFT-DEFAULT define arm_aapcscc float @test_frem_float(float %x, float %y) { ; CHECK-LABEL: test_frem_float: @@ -31,3 +31,21 @@ define arm_aapcscc double @test_fpow_double(double %x, double %y) { %r = call double @llvm.pow.f64(double %x, double %y) ret double %r } + +define arm_aapcscc float @test_add_float(float %x, float %y) { +; CHECK-LABEL: test_add_float: +; HARD: vadd.f32 +; SOFT-AEABI: blx __aeabi_fadd +; SOFT-DEFAULT: blx __addsf3 + %r = fadd float %x, %y + ret float %r +} + +define arm_aapcscc double @test_add_double(double %x, double %y) { +; CHECK-LABEL: test_add_double: +; HARD: vadd.f64 +; SOFT-AEABI: blx __aeabi_dadd +; SOFT-DEFAULT: blx __adddf3 + %r = fadd double %x, %y + ret double %r +} diff --git a/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir b/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir index c05725c07a6..d154b4887c1 100644 --- a/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir +++ b/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir @@ -1,12 +1,15 @@ -# RUN: llc -mtriple arm-gnueabihf -mattr=+vfp2 -float-abi=hard -global-isel -run-pass=legalizer %s -o - | FileCheck %s -check-prefix CHECK -check-prefix HARD -# RUN: llc -mtriple arm-- -mattr=+vfp2 -float-abi=soft -global-isel -run-pass=legalizer %s -o - | FileCheck %s -check-prefix CHECK -check-prefix SOFT -# RUN: llc -mtriple arm-- -float-abi=soft -global-isel -run-pass=legalizer %s -o - | FileCheck %s -check-prefix CHECK -check-prefix SOFT +# RUN: llc -mtriple arm-linux-gnueabihf -mattr=+vfp2 -float-abi=hard -global-isel -run-pass=legalizer %s -o - | FileCheck %s -check-prefix CHECK -check-prefix HARD +# RUN: llc -mtriple arm-linux-gnueabi -mattr=+vfp2,+soft-float -float-abi=soft -global-isel -run-pass=legalizer %s -o - | FileCheck %s -check-prefix CHECK -check-prefix SOFT -check-prefix SOFT-AEABI +# RUN: llc -mtriple arm-linux-gnu -mattr=+soft-float -float-abi=soft -global-isel -run-pass=legalizer %s -o - | FileCheck %s -check-prefix CHECK -check-prefix SOFT -check-prefix SOFT-DEFAULT --- | define void @test_frem_float() { ret void } define void @test_frem_double() { ret void } define void @test_fpow_float() { ret void } define void @test_fpow_double() { ret void } + + define void @test_fadd_float() { ret void } + define void @test_fadd_double() { ret void } ... --- name: test_frem_float @@ -192,3 +195,88 @@ body: | %r1 = COPY %8(s32) BX_RET 14, _, implicit %r0, implicit %r1 ... +--- +name: test_fadd_float +# CHECK-LABEL: name: test_fadd_float +legalized: false +# CHECK: legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } + - { id: 2, class: _ } +body: | + bb.0: + liveins: %r0, %r1 + + ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0 + ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1 + %0(s32) = COPY %r0 + %1(s32) = COPY %r1 + ; HARD: [[R:%[0-9]+]](s32) = G_FADD [[X]], [[Y]] + ; SOFT: ADJCALLSTACKDOWN + ; SOFT-DAG: %r0 = COPY [[X]] + ; SOFT-DAG: %r1 = COPY [[Y]] + ; SOFT-AEABI: BLX $__aeabi_fadd, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0 + ; SOFT-DEFAULT: BLX $__addsf3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0 + ; SOFT: [[R:%[0-9]+]](s32) = COPY %r0 + ; SOFT: ADJCALLSTACKUP + %2(s32) = G_FADD %0, %1 + ; CHECK: %r0 = COPY [[R]] + %r0 = COPY %2(s32) + BX_RET 14, _, implicit %r0 +... +--- +name: test_fadd_double +# CHECK-LABEL: name: test_fadd_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: _ } + - { id: 4, class: _ } + - { id: 5, class: _ } + - { id: 6, class: _ } + - { id: 7, class: _ } + - { id: 8, class: _ } +body: | + bb.0: + liveins: %r0, %r1, %r2, %r3 + + ; CHECK-DAG: [[X0:%[0-9]+]](s32) = COPY %r0 + ; CHECK-DAG: [[X1:%[0-9]+]](s32) = COPY %r1 + ; CHECK-DAG: [[Y0:%[0-9]+]](s32) = COPY %r2 + ; CHECK-DAG: [[Y1:%[0-9]+]](s32) = COPY %r3 + %0(s32) = COPY %r0 + %1(s32) = COPY %r1 + %2(s32) = COPY %r2 + %3(s32) = COPY %r3 + ; HARD-DAG: [[X:%[0-9]+]](s64) = G_SEQUENCE [[X0]] + ; HARD-DAG: [[Y:%[0-9]+]](s64) = G_SEQUENCE [[Y0]] + %4(s64) = G_SEQUENCE %0(s32), 0, %1(s32), 32 + %5(s64) = G_SEQUENCE %2(s32), 0, %3(s32), 32 + ; HARD: [[R:%[0-9]+]](s64) = G_FADD [[X]], [[Y]] + ; SOFT: ADJCALLSTACKDOWN + ; SOFT-DAG: %r{{[0-1]}} = COPY [[X0]] + ; SOFT-DAG: %r{{[0-1]}} = COPY [[X1]] + ; SOFT-DAG: %r{{[2-3]}} = COPY [[Y0]] + ; SOFT-DAG: %r{{[2-3]}} = COPY [[Y1]] + ; SOFT-AEABI: BLX $__aeabi_dadd, {{.*}}, implicit %r0, implicit %r1, implicit %r2, implicit %r3, implicit-def %r0, implicit-def %r1 + ; SOFT-DEFAULT: BLX $__adddf3, {{.*}}, implicit %r0, implicit %r1, implicit %r2, implicit %r3, implicit-def %r0, implicit-def %r1 + ; SOFT: ADJCALLSTACKUP + %6(s64) = G_FADD %4, %5 + ; HARD-DAG: G_EXTRACT [[R]](s64), 0 + ; HARD-DAG: G_EXTRACT [[R]](s64), 32 + %7(s32) = G_EXTRACT %6(s64), 0 + %8(s32) = G_EXTRACT %6(s64), 32 + %r0 = COPY %7(s32) + %r1 = COPY %8(s32) + BX_RET 14, _, implicit %r0, implicit %r1 +... -- 2.40.0