From caf8a11b656afdaf12d0a3566c7d42e302bd7539 Mon Sep 17 00:00:00 2001 From: David Green Date: Sun, 26 May 2019 10:30:22 +0000 Subject: [PATCH] [ARM] Promote fp16 frem Promote fp16 frem operations on ARM to floats so they call fmodf. Differential Revision: https://reviews.llvm.org/D62321 llvm-svn: 361713 --- llvm/lib/Target/ARM/ARMISelLowering.cpp | 5 +++++ llvm/test/CodeGen/ARM/fp16-fullfp16.ll | 27 +++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 643d280..8e5c076 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -1142,6 +1142,11 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, } } + // FP16 often need to be promoted to call lib functions + if (Subtarget->hasFullFP16()) { + setOperationAction(ISD::FREM, MVT::f16, Promote); + } + if (Subtarget->hasNEON()) { // vmin and vmax aren't available in a scalar form, so we use // a NEON instruction with an undef lane instead. diff --git a/llvm/test/CodeGen/ARM/fp16-fullfp16.ll b/llvm/test/CodeGen/ARM/fp16-fullfp16.ll index 5f14463..d5ded1f 100644 --- a/llvm/test/CodeGen/ARM/fp16-fullfp16.ll +++ b/llvm/test/CodeGen/ARM/fp16-fullfp16.ll @@ -57,14 +57,25 @@ define void @test_fdiv(half* %p, half* %q) { ret void } -; FIXME -;define void @test_frem(half* %p, half* %q) { -; %a = load half, half* %p, align 2 -; %b = load half, half* %q, align 2 -; %r = frem half %a, %b -; store half %r, half* %p -; ret void -;} +define arm_aapcs_vfpcc void @test_frem(half* %p, half* %q) { +; CHECK-LABEL: test_frem: +; CHECK: .save {r4, lr} +; CHECK-NEXT: push {r4, lr} +; CHECK-NEXT: vldr.16 s2, [r1] +; CHECK-NEXT: vldr.16 s0, [r0] +; CHECK-NEXT: mov r4, r0 +; CHECK-NEXT: vcvtb.f32.f16 s0, s0 +; CHECK-NEXT: vcvtb.f32.f16 s1, s2 +; CHECK-NEXT: bl fmodf +; CHECK-NEXT: vcvtb.f16.f32 s0, s0 +; CHECK-NEXT: vstr.16 s0, [r4] +; CHECK-NEXT: pop {r4, pc} + %a = load half, half* %p, align 2 + %b = load half, half* %q, align 2 + %r = frem half %a, %b + store half %r, half* %p + ret void +} define void @test_load_store(half* %p, half* %q) { ; CHECK-LABEL: test_load_store: -- 2.7.4