[llvm] r359600 - [WebAssembly] Support f16 libcalls

Dan Gohman via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 30 12:18:00 PDT 2019


Author: djg
Date: Tue Apr 30 12:17:59 2019
New Revision: 359600

URL: http://llvm.org/viewvc/llvm-project?rev=359600&view=rev
Log:
[WebAssembly] Support f16 libcalls

Add support for f16 libcalls in WebAssembly. This entails adding signatures
for the remaining F16 libcalls, and renaming gnu_f2h_ieee/gnu_h2f_ieee to
truncsfhf2/extendhfsf2 for consistency between f32 and f64/f128 (compiler-rt
already supports this).

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

Reviewer: dschuff

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
    llvm/trunk/test/CodeGen/WebAssembly/f16.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=359600&r1=359599&r2=359600&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Tue Apr 30 12:17:59 2019
@@ -271,6 +271,11 @@ WebAssemblyTargetLowering::WebAssemblyTa
     MaxStoresPerMemsetOptSize = 1;
   }
 
+  // Override the __gnu_f2h_ieee/__gnu_h2f_ieee names so that the f32 name is
+  // consistent with the f64 and f128 names.
+  setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2");
+  setLibcallName(RTLIB::FPROUND_F32_F16, "__truncsfhf2");
+
   // Always convert switches to br_tables unless there is only one case, which
   // is equivalent to a simple branch. This reduces code size for wasm, and we
   // defer possible jump table optimizations to the VM.

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp?rev=359600&r1=359599&r2=359600&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp Tue Apr 30 12:17:59 2019
@@ -51,6 +51,8 @@ enum RuntimeLibcallSignature {
   f64_func_f64_i32,
   f64_func_i64_i64,
   i16_func_f32,
+  i16_func_f64,
+  i16_func_i64_i64,
   i8_func_i8_i8,
   func_f32_iPTR_iPTR,
   func_f64_iPTR_iPTR,
@@ -228,13 +230,15 @@ struct RuntimeLibcallSignatureTable {
     Table[RTLIB::FMAX_F128] = func_iPTR_i64_i64_i64_i64;
 
     // Conversion
-    // All F80 and PPCF128 routines are unspported.
+    // All F80 and PPCF128 routines are unsupported.
     Table[RTLIB::FPEXT_F64_F128] = func_iPTR_f64;
     Table[RTLIB::FPEXT_F32_F128] = func_iPTR_f32;
     Table[RTLIB::FPEXT_F32_F64] = f64_func_f32;
     Table[RTLIB::FPEXT_F16_F32] = f32_func_i16;
     Table[RTLIB::FPROUND_F32_F16] = i16_func_f32;
+    Table[RTLIB::FPROUND_F64_F16] = i16_func_f64;
     Table[RTLIB::FPROUND_F64_F32] = f32_func_f64;
+    Table[RTLIB::FPROUND_F128_F16] = i16_func_i64_i64;
     Table[RTLIB::FPROUND_F128_F32] = f32_func_i64_i64;
     Table[RTLIB::FPROUND_F128_F64] = f64_func_i64_i64;
     Table[RTLIB::FPTOSINT_F32_I32] = i32_func_f32;
@@ -482,6 +486,10 @@ struct StaticLibcallNameMap {
         Map[NameLibcall.first] = NameLibcall.second;
       }
     }
+    // Override the __gnu_f2h_ieee/__gnu_h2f_ieee names so that the f32 name is
+    // consistent with the f64 and f128 names.
+    Map["__extendhfsf2"] = RTLIB::FPEXT_F16_F32;
+    Map["__truncsfhf2"] = RTLIB::FPROUND_F32_F16;
   }
 };
 
@@ -595,6 +603,15 @@ void llvm::getLibcallSignature(const Web
     Rets.push_back(wasm::ValType::I32);
     Params.push_back(wasm::ValType::F32);
     break;
+  case i16_func_f64:
+    Rets.push_back(wasm::ValType::I32);
+    Params.push_back(wasm::ValType::F64);
+    break;
+  case i16_func_i64_i64:
+    Rets.push_back(wasm::ValType::I32);
+    Params.push_back(wasm::ValType::I64);
+    Params.push_back(wasm::ValType::I64);
+    break;
   case i8_func_i8_i8:
     Rets.push_back(wasm::ValType::I32);
     Params.push_back(wasm::ValType::I32);

Modified: llvm/trunk/test/CodeGen/WebAssembly/f16.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/f16.ll?rev=359600&r1=359599&r2=359600&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/f16.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/f16.ll Tue Apr 30 12:17:59 2019
@@ -6,22 +6,65 @@
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
 
-; CHECK-LABEL: demote:
-; CHECK-NEXT: .functype demote (f32) -> (f32){{$}}
+; CHECK-LABEL: demote.f32:
+; CHECK-NEXT: .functype demote.f32 (f32) -> (f32){{$}}
 ; CHECK-NEXT: local.get	$push[[L0:[0-9]+]]=, 0{{$}}
-; CHECK-NEXT: i32.call	$push[[L1:[0-9]+]]=, __gnu_f2h_ieee, $pop[[L0]]{{$}}
-; CHECK-NEXT: f32.call	$push[[L2:[0-9]+]]=, __gnu_h2f_ieee, $pop[[L1]]{{$}}
+; CHECK-NEXT: i32.call	$push[[L1:[0-9]+]]=, __truncsfhf2, $pop[[L0]]{{$}}
+; CHECK-NEXT: f32.call	$push[[L2:[0-9]+]]=, __extendhfsf2, $pop[[L1]]{{$}}
 ; CHECK-NEXT: return  	$pop[[L2]]{{$}}
-define half @demote(float %f) {
+define half @demote.f32(float %f) {
     %t = fptrunc float %f to half
     ret half %t
 }
 
-; CHECK-LABEL: promote:
-; CHECK-NEXT: .functype promote (f32) -> (f32){{$}}
+; CHECK-LABEL: promote.f32:
+; CHECK-NEXT: .functype promote.f32 (f32) -> (f32){{$}}
 ; CHECK-NEXT: local.get	$push0=, 0{{$}}
 ; CHECK-NEXT: return  	$pop0{{$}}
-define float @promote(half %f) {
+define float @promote.f32(half %f) {
     %t = fpext half %f to float
     ret float %t
 }
+
+; CHECK-LABEL: demote.f64:
+; CHECK-NEXT: .functype demote.f64 (f64) -> (f32){{$}}
+; CHECK-NEXT: local.get	$push[[L0:[0-9]+]]=, 0{{$}}
+; CHECK-NEXT: i32.call	$push[[L1:[0-9]+]]=, __truncdfhf2, $pop[[L0]]{{$}}
+; CHECK-NEXT: f32.call	$push[[L2:[0-9]+]]=, __extendhfsf2, $pop[[L1]]{{$}}
+; CHECK-NEXT: return  	$pop[[L2]]{{$}}
+define half @demote.f64(double %f) {
+    %t = fptrunc double %f to half
+    ret half %t
+}
+
+; CHECK-LABEL: promote.f64:
+; CHECK-NEXT: .functype promote.f64 (f32) -> (f64){{$}}
+; CHECK-NEXT: local.get	$push[[L0:[0-9]+]]=, 0{{$}}
+; CHECK-NEXT: f64.promote_f32 $push[[L1:[0-9]+]]=, $pop[[L0]]{{$}}
+; CHECK-NEXT: return  	$pop[[L1]]{{$}}
+define double @promote.f64(half %f) {
+    %t = fpext half %f to double
+    ret double %t
+}
+
+; CHECK-LABEL: demote.f128:
+; CHECK-NEXT: .functype demote.f128 (i64, i64) -> (f32){{$}}
+; CHECK-NEXT: local.get	$push[[L0:[0-9]+]]=, 0{{$}}
+; CHECK-NEXT: local.get	$push[[L1:[0-9]+]]=, 1{{$}}
+; CHECK-NEXT: i32.call	$push[[L2:[0-9]+]]=, __trunctfhf2, $pop[[L0]], $pop[[L1]]{{$}}
+; CHECK-NEXT: f32.call	$push[[L3:[0-9]+]]=, __extendhfsf2, $pop[[L2]]{{$}}
+; CHECK-NEXT: return  	$pop[[L3]]{{$}}
+define half @demote.f128(fp128 %f) {
+    %t = fptrunc fp128 %f to half
+    ret half %t
+}
+
+; CHECK-LABEL: promote.f128:
+; CHECK-NEXT: .functype promote.f128 (i32, f32) -> (){{$}}
+; CHECK: call __extendsftf2
+; CHECK: i64.store
+; CHECK: i64.store
+define fp128 @promote.f128(half %f) {
+    %t = fpext half %f to fp128
+    ret fp128 %t
+}




More information about the llvm-commits mailing list