diff options
-rw-r--r-- | llvm/lib/Target/ARM/ARMLegalizerInfo.cpp | 5 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll | 22 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir | 95 |
3 files changed, 117 insertions, 5 deletions
diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp index ccafba968ca..a1097af6e85 100644 --- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp +++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp @@ -65,8 +65,9 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { setAction({G_STORE, s64}, Legal); } - setAction({G_FREM, s32}, Libcall); - setAction({G_FREM, s64}, Libcall); + for (unsigned Op : {G_FREM, G_FPOW}) + for (auto Ty : {s32, s64}) + setAction({Op, Ty}, Libcall); computeTables(); } diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll index 7c653556514..7ef1b4e3639 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll @@ -1,6 +1,6 @@ -; RUN: llc -mtriple arm-unknown -mattr=+vfp2 -float-abi=hard -global-isel %s -o - | FileCheck %s -; RUN: llc -mtriple arm-unknown -mattr=+vfp2 -float-abi=soft -global-isel %s -o - | FileCheck %s -; RUN: llc -mtriple arm-unknwon -float-abi=soft -global-isel %s -o - | FileCheck %s +; 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 define arm_aapcscc float @test_frem_float(float %x, float %y) { ; CHECK-LABEL: test_frem_float: @@ -15,3 +15,19 @@ define arm_aapcscc double @test_frem_double(double %x, double %y) { %r = frem double %x, %y ret double %r } + +declare float @llvm.pow.f32(float %x, float %y) +define arm_aapcscc float @test_fpow_float(float %x, float %y) { +; CHECK-LABEL: test_fpow_float: +; CHECK: blx powf + %r = call float @llvm.pow.f32(float %x, float %y) + ret float %r +} + +declare double @llvm.pow.f64(double %x, double %y) +define arm_aapcscc double @test_fpow_double(double %x, double %y) { +; CHECK-LABEL: test_fpow_double: +; CHECK: blx pow + %r = call double @llvm.pow.f64(double %x, double %y) + ret double %r +} diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir index 87308bf1718..c05725c07a6 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir @@ -4,6 +4,9 @@ --- | 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 } ... --- name: test_frem_float @@ -97,3 +100,95 @@ body: | %r1 = COPY %8(s32) BX_RET 14, _, implicit %r0, implicit %r1 ... +--- +name: test_fpow_float +# CHECK-LABEL: name: test_fpow_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 + ; CHECK: ADJCALLSTACKDOWN + ; SOFT-DAG: %r0 = COPY [[X]] + ; SOFT-DAG: %r1 = COPY [[Y]] + ; HARD-DAG: %s0 = COPY [[X]] + ; HARD-DAG: %s1 = COPY [[Y]] + ; SOFT: BLX $powf, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0 + ; HARD: BLX $powf, {{.*}}, implicit %s0, implicit %s1, implicit-def %s0 + ; SOFT: [[R:%[0-9]+]](s32) = COPY %r0 + ; HARD: [[R:%[0-9]+]](s32) = COPY %s0 + ; CHECK: ADJCALLSTACKUP + %2(s32) = G_FPOW %0, %1 + ; CHECK: %r0 = COPY [[R]] + %r0 = COPY %2(s32) + BX_RET 14, _, implicit %r0 +... +--- +name: test_fpow_double +# CHECK-LABEL: name: test_fpow_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 + + ; The inputs may be in the wrong order (depending on the target's + ; endianness), but that's orthogonal to what we're trying to test here. + ; For soft float, we only need to check that the first value, received + ; through R0-R1, ends up in R0-R1 or R1-R0, and the second value, received + ; through R2-R3, ends up in R2-R3 or R3-R2, when passed to pow. + ; For hard float, the values need to end up in D0 and D1. + ; 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 + ; CHECK: 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]] + ; HARD-DAG: %d0 = COPY [[X]] + ; HARD-DAG: %d1 = COPY [[Y]] + ; SOFT: BLX $pow, {{.*}}, implicit %r0, implicit %r1, implicit %r2, implicit %r3, implicit-def %r0, implicit-def %r1 + ; HARD: BLX $pow, {{.*}}, implicit %d0, implicit %d1, implicit-def %d0 + ; CHECK: ADJCALLSTACKUP + %6(s64) = G_FPOW %4, %5 + %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 +... |