OSDN Git Service

GlobalISel: Allow legalizing G_FADD to a libcall
authorDiana Picus <diana.picus@linaro.org>
Tue, 11 Apr 2017 10:52:34 +0000 (10:52 +0000)
committerDiana Picus <diana.picus@linaro.org>
Tue, 11 Apr 2017 10:52:34 +0000 (10:52 +0000)
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
lib/Target/ARM/ARMLegalizerInfo.cpp
test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll
test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir

index afab23d..20358f7 100644 (file)
@@ -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();
index a1097af..994bbd6 100644 (file)
@@ -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})
index 7ef1b4e..7d021fd 100644 (file)
@@ -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
+}
index c05725c..d154b48 100644 (file)
@@ -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
+...