[llvm] 28415e5 - [SPARC] Lower fp16 ops to libcalls

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 19:30:06 PDT 2020


Author: LemonBoy
Date: 2020-06-09T19:29:42-07:00
New Revision: 28415e588f1c501967a9b596e6651787996f93ff

URL: https://github.com/llvm/llvm-project/commit/28415e588f1c501967a9b596e6651787996f93ff
DIFF: https://github.com/llvm/llvm-project/commit/28415e588f1c501967a9b596e6651787996f93ff.diff

LOG: [SPARC] Lower fp16 ops to libcalls

The fp16 ops are legalized by extending/chopping them as needed.
The tests are shamelessly stolen from the RISC-V backend.

Differential Revision: https://reviews.llvm.org/D77569

Added: 
    llvm/test/CodeGen/SPARC/fp16-promote.ll

Modified: 
    llvm/lib/Target/Sparc/SparcISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index f598d4233ce9..c9743c517074 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1465,6 +1465,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
 
   // Turn FP extload into load/fpextend
   for (MVT VT : MVT::fp_valuetypes()) {
+    setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
     setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
     setLoadExtAction(ISD::EXTLOAD, VT, MVT::f64, Expand);
   }
@@ -1474,6 +1475,8 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
     setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
 
   // Turn FP truncstore into trunc + store.
+  setTruncStoreAction(MVT::f32, MVT::f16, Expand);
+  setTruncStoreAction(MVT::f64, MVT::f16, Expand);
   setTruncStoreAction(MVT::f64, MVT::f32, Expand);
   setTruncStoreAction(MVT::f128, MVT::f32, Expand);
   setTruncStoreAction(MVT::f128, MVT::f64, Expand);
@@ -1515,6 +1518,12 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
   setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
   setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
 
+  // Lower f16 conversion operations into library calls
+  setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
+  setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);
+  setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);
+  setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand);
+
   setOperationAction(ISD::BITCAST, MVT::f32, Expand);
   setOperationAction(ISD::BITCAST, MVT::i32, Expand);
 

diff  --git a/llvm/test/CodeGen/SPARC/fp16-promote.ll b/llvm/test/CodeGen/SPARC/fp16-promote.ll
new file mode 100644
index 000000000000..8a60dfb54206
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/fp16-promote.ll
@@ -0,0 +1,376 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -march=sparc < %s | FileCheck %s -check-prefix=V8 -check-prefix=V8-BE
+; RUN: llc -march=sparcel < %s | FileCheck %s -check-prefix=V8 -check-prefix=V8-EL
+; RUN: llc -march=sparc -O0 < %s | FileCheck %s -check-prefix=V8-UNOPT
+; RUN: llc -march=sparc -mattr=v9 < %s | FileCheck %s -check-prefix=V9
+; RUN: llc -mtriple=sparc64-unknown-linux < %s | FileCheck %s -check-prefix=SPARC64
+
+define void @test_load_store(half* %p, half* %q) nounwind {
+; V8-LABEL: test_load_store:
+; V8:       ! %bb.0:
+; V8-NEXT:    lduh [%o0], %o0
+; V8-NEXT:    retl
+; V8-NEXT:    sth %o0, [%o1]
+;
+; V8-UNOPT-LABEL: test_load_store:
+; V8-UNOPT:       ! %bb.0:
+; V8-UNOPT-NEXT:    lduh [%o0], %o0
+; V8-UNOPT-NEXT:    retl
+; V8-UNOPT-NEXT:    sth %o0, [%o1]
+;
+; V9-LABEL: test_load_store:
+; V9:       ! %bb.0:
+; V9-NEXT:    lduh [%o0], %o0
+; V9-NEXT:    retl
+; V9-NEXT:    sth %o0, [%o1]
+;
+; SPARC64-LABEL: test_load_store:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    lduh [%o0], %o0
+; SPARC64-NEXT:    retl
+; SPARC64-NEXT:    sth %o0, [%o1]
+  %a = load half, half* %p
+  store half %a, half* %q
+  ret void
+}
+
+define float @test_fpextend_float(half* %p) nounwind {
+; V8-LABEL: test_fpextend_float:
+; V8:       ! %bb.0:
+; V8-NEXT:    save %sp, -96, %sp
+; V8-NEXT:    call __gnu_h2f_ieee
+; V8-NEXT:    lduh [%i0], %o0
+; V8-NEXT:    ret
+; V8-NEXT:    restore
+;
+; V8-UNOPT-LABEL: test_fpextend_float:
+; V8-UNOPT:       ! %bb.0:
+; V8-UNOPT-NEXT:    save %sp, -96, %sp
+; V8-UNOPT-NEXT:    call __gnu_h2f_ieee
+; V8-UNOPT-NEXT:    lduh [%i0], %o0
+; V8-UNOPT-NEXT:    ret
+; V8-UNOPT-NEXT:    restore
+;
+; V9-LABEL: test_fpextend_float:
+; V9:       ! %bb.0:
+; V9-NEXT:    save %sp, -96, %sp
+; V9-NEXT:    call __gnu_h2f_ieee
+; V9-NEXT:    lduh [%i0], %o0
+; V9-NEXT:    ret
+; V9-NEXT:    restore
+;
+; SPARC64-LABEL: test_fpextend_float:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -176, %sp
+; SPARC64-NEXT:    call __gnu_h2f_ieee
+; SPARC64-NEXT:    lduh [%i0], %o0
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore
+  %a = load half, half* %p
+  %r = fpext half %a to float
+  ret float %r
+}
+
+define double @test_fpextend_double(half* %p) nounwind {
+; V8-LABEL: test_fpextend_double:
+; V8:       ! %bb.0:
+; V8-NEXT:    save %sp, -96, %sp
+; V8-NEXT:    call __gnu_h2f_ieee
+; V8-NEXT:    lduh [%i0], %o0
+; V8-NEXT:    fstod %f0, %f0
+; V8-NEXT:    ret
+; V8-NEXT:    restore
+;
+; V8-UNOPT-LABEL: test_fpextend_double:
+; V8-UNOPT:       ! %bb.0:
+; V8-UNOPT-NEXT:    save %sp, -96, %sp
+; V8-UNOPT-NEXT:    call __gnu_h2f_ieee
+; V8-UNOPT-NEXT:    lduh [%i0], %o0
+; V8-UNOPT-NEXT:    fstod %f0, %f0
+; V8-UNOPT-NEXT:    ret
+; V8-UNOPT-NEXT:    restore
+;
+; V9-LABEL: test_fpextend_double:
+; V9:       ! %bb.0:
+; V9-NEXT:    save %sp, -96, %sp
+; V9-NEXT:    call __gnu_h2f_ieee
+; V9-NEXT:    lduh [%i0], %o0
+; V9-NEXT:    fstod %f0, %f0
+; V9-NEXT:    ret
+; V9-NEXT:    restore
+;
+; SPARC64-LABEL: test_fpextend_double:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -176, %sp
+; SPARC64-NEXT:    call __gnu_h2f_ieee
+; SPARC64-NEXT:    lduh [%i0], %o0
+; SPARC64-NEXT:    fstod %f0, %f0
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore
+  %a = load half, half* %p
+  %r = fpext half %a to double
+  ret double %r
+}
+
+define void @test_fptrunc_float(float %f, half* %p) nounwind {
+; V8-LABEL: test_fptrunc_float:
+; V8:       ! %bb.0:
+; V8-NEXT:    save %sp, -96, %sp
+; V8-NEXT:    call __gnu_f2h_ieee
+; V8-NEXT:    mov %i0, %o0
+; V8-NEXT:    sth %o0, [%i1]
+; V8-NEXT:    ret
+; V8-NEXT:    restore
+;
+; V8-UNOPT-LABEL: test_fptrunc_float:
+; V8-UNOPT:       ! %bb.0:
+; V8-UNOPT-NEXT:    save %sp, -104, %sp
+; V8-UNOPT-NEXT:    st %i0, [%fp+-4]
+; V8-UNOPT-NEXT:    ld [%fp+-4], %f0
+; V8-UNOPT-NEXT:    mov %i0, %o0
+; V8-UNOPT-NEXT:    st %i1, [%fp+-8] ! 4-byte Folded Spill
+; V8-UNOPT-NEXT:    call __gnu_f2h_ieee
+; V8-UNOPT-NEXT:    st %f0, [%fp+-12]
+; V8-UNOPT-NEXT:    ld [%fp+-8], %i0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT:    sth %o0, [%i0]
+; V8-UNOPT-NEXT:    ret
+; V8-UNOPT-NEXT:    restore
+;
+; V9-LABEL: test_fptrunc_float:
+; V9:       ! %bb.0:
+; V9-NEXT:    save %sp, -96, %sp
+; V9-NEXT:    call __gnu_f2h_ieee
+; V9-NEXT:    mov %i0, %o0
+; V9-NEXT:    sth %o0, [%i1]
+; V9-NEXT:    ret
+; V9-NEXT:    restore
+;
+; SPARC64-LABEL: test_fptrunc_float:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -176, %sp
+; SPARC64-NEXT:    call __gnu_f2h_ieee
+; SPARC64-NEXT:    nop
+; SPARC64-NEXT:    sth %o0, [%i1]
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore
+  %a = fptrunc float %f to half
+  store half %a, half* %p
+  ret void
+}
+
+define void @test_fptrunc_double(double %d, half* %p) nounwind {
+; V8-LABEL: test_fptrunc_double:
+; V8:       ! %bb.0:
+; V8-NEXT:    save %sp, -112, %sp
+; V8-NEXT:    ! kill: def $i1 killed $i1 killed $i0_i1 def $i0_i1
+; V8-NEXT:    ! kill: def $i0 killed $i0 killed $i0_i1 def $i0_i1
+; V8-NEXT:    std %i0, [%fp+-8]
+; V8-NEXT:    ldd [%fp+-8], %f0
+; V8-NEXT:    std %f0, [%fp+-16]
+; V8-NEXT:    call __truncdfhf2
+; V8-NEXT:    ldd [%fp+-16], %o0
+; V8-NEXT:    sth %o0, [%i2]
+; V8-NEXT:    ret
+; V8-NEXT:    restore
+;
+; V8-UNOPT-LABEL: test_fptrunc_double:
+; V8-UNOPT:       ! %bb.0:
+; V8-UNOPT-NEXT:    save %sp, -112, %sp
+; V8-UNOPT-NEXT:    ! implicit-def: $i4_i5
+; V8-UNOPT-NEXT:    mov %i0, %i4
+; V8-UNOPT-NEXT:    mov %i1, %i5
+; V8-UNOPT-NEXT:    std %i4, [%fp+-8]
+; V8-UNOPT-NEXT:    ldd [%fp+-8], %f0
+; V8-UNOPT-NEXT:    std %f0, [%fp+-16]
+; V8-UNOPT-NEXT:    ldd [%fp+-16], %i0
+; V8-UNOPT-NEXT:    mov %i0, %i3
+; V8-UNOPT-NEXT:    ! kill: def $i1 killed $i1 killed $i0_i1
+; V8-UNOPT-NEXT:    mov %i3, %o0
+; V8-UNOPT-NEXT:    mov %i1, %o1
+; V8-UNOPT-NEXT:    call __truncdfhf2
+; V8-UNOPT-NEXT:    st %i2, [%fp+-20]
+; V8-UNOPT-NEXT:    ld [%fp+-20], %i0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT:    sth %o0, [%i0]
+; V8-UNOPT-NEXT:    ret
+; V8-UNOPT-NEXT:    restore
+;
+; V9-LABEL: test_fptrunc_double:
+; V9:       ! %bb.0:
+; V9-NEXT:    save %sp, -112, %sp
+; V9-NEXT:    ! kill: def $i1 killed $i1 killed $i0_i1 def $i0_i1
+; V9-NEXT:    ! kill: def $i0 killed $i0 killed $i0_i1 def $i0_i1
+; V9-NEXT:    std %i0, [%fp+-8]
+; V9-NEXT:    ldd [%fp+-8], %f0
+; V9-NEXT:    std %f0, [%fp+-16]
+; V9-NEXT:    call __truncdfhf2
+; V9-NEXT:    ldd [%fp+-16], %o0
+; V9-NEXT:    sth %o0, [%i2]
+; V9-NEXT:    ret
+; V9-NEXT:    restore
+;
+; SPARC64-LABEL: test_fptrunc_double:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -176, %sp
+; SPARC64-NEXT:    call __truncdfhf2
+; SPARC64-NEXT:    nop
+; SPARC64-NEXT:    sth %o0, [%i1]
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore
+  %a = fptrunc double %d to half
+  store half %a, half* %p
+  ret void
+}
+
+define void @test_fadd(half* %p, half* %q) nounwind {
+; V8-LABEL: test_fadd:
+; V8:       ! %bb.0:
+; V8-NEXT:    save %sp, -104, %sp
+; V8-NEXT:    call __gnu_h2f_ieee
+; V8-NEXT:    lduh [%i0], %o0
+; V8-NEXT:    st %f0, [%fp+-8] ! 4-byte Folded Spill
+; V8-NEXT:    call __gnu_h2f_ieee
+; V8-NEXT:    lduh [%i1], %o0
+; V8-NEXT:    ld [%fp+-8], %f1 ! 4-byte Folded Reload
+; V8-NEXT:    fadds %f1, %f0, %f0
+; V8-NEXT:    st %f0, [%fp+-4]
+; V8-NEXT:    call __gnu_f2h_ieee
+; V8-NEXT:    ld [%fp+-4], %o0
+; V8-NEXT:    sth %o0, [%i0]
+; V8-NEXT:    ret
+; V8-NEXT:    restore
+;
+; V8-UNOPT-LABEL: test_fadd:
+; V8-UNOPT:       ! %bb.0:
+; V8-UNOPT-NEXT:    save %sp, -112, %sp
+; V8-UNOPT-NEXT:    lduh [%i0], %o0
+; V8-UNOPT-NEXT:    st %i1, [%fp+-8] ! 4-byte Folded Spill
+; V8-UNOPT-NEXT:    call __gnu_h2f_ieee
+; V8-UNOPT-NEXT:    st %i0, [%fp+-12]
+; V8-UNOPT-NEXT:    ld [%fp+-8], %i0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT:    lduh [%i0], %o0
+; V8-UNOPT-NEXT:    call __gnu_h2f_ieee
+; V8-UNOPT-NEXT:    st %f0, [%fp+-16]
+; V8-UNOPT-NEXT:    ld [%fp+-16], %f1 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT:    fadds %f1, %f0, %f0
+; V8-UNOPT-NEXT:    st %f0, [%fp+-4]
+; V8-UNOPT-NEXT:    call __gnu_f2h_ieee
+; V8-UNOPT-NEXT:    ld [%fp+-4], %o0
+; V8-UNOPT-NEXT:    ld [%fp+-12], %i0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT:    sth %o0, [%i0]
+; V8-UNOPT-NEXT:    ret
+; V8-UNOPT-NEXT:    restore
+;
+; V9-LABEL: test_fadd:
+; V9:       ! %bb.0:
+; V9-NEXT:    save %sp, -104, %sp
+; V9-NEXT:    call __gnu_h2f_ieee
+; V9-NEXT:    lduh [%i0], %o0
+; V9-NEXT:    st %f0, [%fp+-8] ! 4-byte Folded Spill
+; V9-NEXT:    call __gnu_h2f_ieee
+; V9-NEXT:    lduh [%i1], %o0
+; V9-NEXT:    ld [%fp+-8], %f1 ! 4-byte Folded Reload
+; V9-NEXT:    fadds %f1, %f0, %f0
+; V9-NEXT:    st %f0, [%fp+-4]
+; V9-NEXT:    call __gnu_f2h_ieee
+; V9-NEXT:    ld [%fp+-4], %o0
+; V9-NEXT:    sth %o0, [%i0]
+; V9-NEXT:    ret
+; V9-NEXT:    restore
+;
+; SPARC64-LABEL: test_fadd:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -192, %sp
+; SPARC64-NEXT:    call __gnu_h2f_ieee
+; SPARC64-NEXT:    lduh [%i0], %o0
+; SPARC64-NEXT:    st %f0, [%fp+2043] ! 4-byte Folded Spill
+; SPARC64-NEXT:    call __gnu_h2f_ieee
+; SPARC64-NEXT:    lduh [%i1], %o0
+; SPARC64-NEXT:    ld [%fp+2043], %f1 ! 4-byte Folded Reload
+; SPARC64-NEXT:    call __gnu_f2h_ieee
+; SPARC64-NEXT:    fadds %f1, %f0, %f1
+; SPARC64-NEXT:    sth %o0, [%i0]
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore
+  %a = load half, half* %p
+  %b = load half, half* %q
+  %r = fadd half %a, %b
+  store half %r, half* %p
+  ret void
+}
+
+define void @test_fmul(half* %p, half* %q) nounwind {
+; V8-LABEL: test_fmul:
+; V8:       ! %bb.0:
+; V8-NEXT:    save %sp, -104, %sp
+; V8-NEXT:    call __gnu_h2f_ieee
+; V8-NEXT:    lduh [%i0], %o0
+; V8-NEXT:    st %f0, [%fp+-8] ! 4-byte Folded Spill
+; V8-NEXT:    call __gnu_h2f_ieee
+; V8-NEXT:    lduh [%i1], %o0
+; V8-NEXT:    ld [%fp+-8], %f1 ! 4-byte Folded Reload
+; V8-NEXT:    fmuls %f1, %f0, %f0
+; V8-NEXT:    st %f0, [%fp+-4]
+; V8-NEXT:    call __gnu_f2h_ieee
+; V8-NEXT:    ld [%fp+-4], %o0
+; V8-NEXT:    sth %o0, [%i0]
+; V8-NEXT:    ret
+; V8-NEXT:    restore
+;
+; V8-UNOPT-LABEL: test_fmul:
+; V8-UNOPT:       ! %bb.0:
+; V8-UNOPT-NEXT:    save %sp, -112, %sp
+; V8-UNOPT-NEXT:    lduh [%i0], %o0
+; V8-UNOPT-NEXT:    st %i1, [%fp+-8] ! 4-byte Folded Spill
+; V8-UNOPT-NEXT:    call __gnu_h2f_ieee
+; V8-UNOPT-NEXT:    st %i0, [%fp+-12]
+; V8-UNOPT-NEXT:    ld [%fp+-8], %i0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT:    lduh [%i0], %o0
+; V8-UNOPT-NEXT:    call __gnu_h2f_ieee
+; V8-UNOPT-NEXT:    st %f0, [%fp+-16]
+; V8-UNOPT-NEXT:    ld [%fp+-16], %f1 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT:    fmuls %f1, %f0, %f0
+; V8-UNOPT-NEXT:    st %f0, [%fp+-4]
+; V8-UNOPT-NEXT:    call __gnu_f2h_ieee
+; V8-UNOPT-NEXT:    ld [%fp+-4], %o0
+; V8-UNOPT-NEXT:    ld [%fp+-12], %i0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT:    sth %o0, [%i0]
+; V8-UNOPT-NEXT:    ret
+; V8-UNOPT-NEXT:    restore
+;
+; V9-LABEL: test_fmul:
+; V9:       ! %bb.0:
+; V9-NEXT:    save %sp, -104, %sp
+; V9-NEXT:    call __gnu_h2f_ieee
+; V9-NEXT:    lduh [%i0], %o0
+; V9-NEXT:    st %f0, [%fp+-8] ! 4-byte Folded Spill
+; V9-NEXT:    call __gnu_h2f_ieee
+; V9-NEXT:    lduh [%i1], %o0
+; V9-NEXT:    ld [%fp+-8], %f1 ! 4-byte Folded Reload
+; V9-NEXT:    fmuls %f1, %f0, %f0
+; V9-NEXT:    st %f0, [%fp+-4]
+; V9-NEXT:    call __gnu_f2h_ieee
+; V9-NEXT:    ld [%fp+-4], %o0
+; V9-NEXT:    sth %o0, [%i0]
+; V9-NEXT:    ret
+; V9-NEXT:    restore
+;
+; SPARC64-LABEL: test_fmul:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -192, %sp
+; SPARC64-NEXT:    call __gnu_h2f_ieee
+; SPARC64-NEXT:    lduh [%i0], %o0
+; SPARC64-NEXT:    st %f0, [%fp+2043] ! 4-byte Folded Spill
+; SPARC64-NEXT:    call __gnu_h2f_ieee
+; SPARC64-NEXT:    lduh [%i1], %o0
+; SPARC64-NEXT:    ld [%fp+2043], %f1 ! 4-byte Folded Reload
+; SPARC64-NEXT:    call __gnu_f2h_ieee
+; SPARC64-NEXT:    fmuls %f1, %f0, %f1
+; SPARC64-NEXT:    sth %o0, [%i0]
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore
+  %a = load half, half* %p
+  %b = load half, half* %q
+  %r = fmul half %a, %b
+  store half %r, half* %p
+  ret void
+}


        


More information about the llvm-commits mailing list