Skip to content

Conversation

@dschuff
Copy link
Member

@dschuff dschuff commented Mar 6, 2025

Clang now lowers modf/modff/modfl as builtins using the llvm.modf intrinsic.

@dschuff dschuff changed the title modf libcall [WebAssembly] Add modf/modff/modfl to WebAssemblyRuntimeLibcallSignatures.cpp Mar 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 6, 2025

@llvm/pr-subscribers-backend-webassembly

Author: Derek Schuff (dschuff)

Changes
  • Add modf/modff/modfl to WebAssemblyRuntimeLibcallSignatures.cpp
  • update checks

Full diff: https://github.com/llvm/llvm-project/pull/130201.diff

2 Files Affected:

  • (modified) llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp (+28)
  • (modified) llvm/test/CodeGen/WebAssembly/libcalls.ll (+31-22)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
index 1fe0b1f2e0591..2bc69edd4880a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
@@ -45,9 +45,11 @@ enum RuntimeLibcallSignature {
   i64_func_i64,
   f32_func_f32_f32,
   f32_func_f32_i32,
+  f32_func_f32_iPTR,
   f32_func_i64_i64,
   f64_func_f64_f64,
   f64_func_f64_i32,
+  f64_func_f64_iPTR,
   f64_func_i64_i64,
   i16_func_f32,
   i16_func_f64,
@@ -69,6 +71,7 @@ enum RuntimeLibcallSignature {
   i16_i16_func_i16_i16,
   i32_i32_func_i32_i32,
   i64_i64_func_i64_i64,
+  i64_i64_func_i64_i64_iPTR,
   i64_i64_func_i64_i64_i64_i64,
   i64_i64_func_i64_i64_i64_i64_iPTR,
   i64_i64_i64_i64_func_i64_i64_i64_i64,
@@ -278,6 +281,10 @@ struct RuntimeLibcallSignatureTable {
     Table[RTLIB::FREXP_F32] = f32_func_f32_i32;
     Table[RTLIB::FREXP_F64] = f64_func_f64_i32;
     Table[RTLIB::FREXP_F128] = i64_i64_func_i64_i64_i32;
+    Table[RTLIB::MODF_F32] = f32_func_f32_iPTR;
+    Table[RTLIB::MODF_F64] = f64_func_f64_iPTR;
+    Table[RTLIB::MODF_F128] = i64_i64_func_i64_i64_iPTR;
+
 
     // Conversion
     // All F80 and PPCF128 routines are unsupported.
@@ -628,6 +635,11 @@ void WebAssembly::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
     Params.push_back(wasm::ValType::F32);
     Params.push_back(wasm::ValType::I32);
     break;
+  case f32_func_f32_iPTR:
+    Rets.push_back(wasm::ValType::F32);
+    Params.push_back(wasm::ValType::F32);
+    Params.push_back(PtrTy);
+    break;
   case f32_func_i64_i64:
     Rets.push_back(wasm::ValType::F32);
     Params.push_back(wasm::ValType::I64);
@@ -648,6 +660,11 @@ void WebAssembly::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
     Params.push_back(wasm::ValType::I64);
     Params.push_back(wasm::ValType::I64);
     break;
+  case f64_func_f64_iPTR:
+    Rets.push_back(wasm::ValType::F64);
+    Params.push_back(wasm::ValType::F64);
+    Params.push_back(PtrTy);
+    break;
   case i16_func_f32:
     Rets.push_back(wasm::ValType::I32);
     Params.push_back(wasm::ValType::F32);
@@ -761,6 +778,17 @@ void WebAssembly::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
     Params.push_back(wasm::ValType::I64);
     Params.push_back(wasm::ValType::I64);
     break;
+  case i64_i64_func_i64_i64_iPTR:
+    if (WebAssembly::canLowerMultivalueReturn(&Subtarget)) {
+      Rets.push_back(wasm::ValType::I64);
+      Rets.push_back(wasm::ValType::I64);
+    } else {
+      Params.push_back(PtrTy);
+    }
+    Params.push_back(wasm::ValType::I64);
+    Params.push_back(wasm::ValType::I64);
+    Params.push_back(PtrTy);
+    break;
   case i64_i64_func_i64_i64_i64_i64:
     if (WebAssembly::canLowerMultivalueReturn(&Subtarget)) {
       Rets.push_back(wasm::ValType::I64);
diff --git a/llvm/test/CodeGen/WebAssembly/libcalls.ll b/llvm/test/CodeGen/WebAssembly/libcalls.ll
index 39657fe2c5870..be144f31f2a95 100644
--- a/llvm/test/CodeGen/WebAssembly/libcalls.ll
+++ b/llvm/test/CodeGen/WebAssembly/libcalls.ll
@@ -23,6 +23,7 @@ declare double @llvm.exp10.f64(double)
 declare double @llvm.ldexp.f64.i32(double, i32)
 declare {double, i32} @llvm.frexp.f64.i32(double)
 declare i32 @llvm.lround(double)
+declare {double, double} @llvm.modf.f64(double)
 
 declare void @escape_value(i32)
 
@@ -203,38 +204,44 @@ define double @f64libcalls(double %x, double %y, i32 %z) {
 ; CHECK-NEXT:  # %bb.0:
 ; CHECK-NEXT:    global.get $push12=, __stack_pointer
 ; CHECK-NEXT:    i32.const $push13=, 16
-; CHECK-NEXT:    i32.sub $push19=, $pop12, $pop13
-; CHECK-NEXT:    local.tee $push18=, 3, $pop19
-; CHECK-NEXT:    global.set __stack_pointer, $pop18
-; CHECK-NEXT:    local.get $push23=, 0
-; CHECK-NEXT:    local.get $push20=, 0
-; CHECK-NEXT:    call $push0=, tan, $pop20
+; CHECK-NEXT:    i32.sub $push21=, $pop12, $pop13
+; CHECK-NEXT:    local.tee $push20=, 3, $pop21
+; CHECK-NEXT:    global.set __stack_pointer, $pop20
+; CHECK-NEXT:    local.get $push25=, 0
+; CHECK-NEXT:    local.get $push22=, 0
+; CHECK-NEXT:    call $push0=, tan, $pop22
 ; CHECK-NEXT:    call $push1=, cos, $pop0
 ; CHECK-NEXT:    call $push2=, log10, $pop1
-; CHECK-NEXT:    local.get $push21=, 1
-; CHECK-NEXT:    call $push3=, pow, $pop2, $pop21
-; CHECK-NEXT:    local.get $push22=, 2
-; CHECK-NEXT:    call $push4=, __powidf2, $pop3, $pop22
+; CHECK-NEXT:    local.get $push23=, 1
+; CHECK-NEXT:    call $push3=, pow, $pop2, $pop23
+; CHECK-NEXT:    local.get $push24=, 2
+; CHECK-NEXT:    call $push4=, __powidf2, $pop3, $pop24
 ; CHECK-NEXT:    call $push5=, log, $pop4
 ; CHECK-NEXT:    call $push6=, exp, $pop5
 ; CHECK-NEXT:    call $push7=, exp10, $pop6
 ; CHECK-NEXT:    call $push8=, cbrt, $pop7
 ; CHECK-NEXT:    call $push9=, lround, $pop8
-; CHECK-NEXT:    call $push10=, ldexp, $pop23, $pop9
-; CHECK-NEXT:    local.get $push24=, 3
-; CHECK-NEXT:    i32.const $push16=, 12
-; CHECK-NEXT:    i32.add $push17=, $pop24, $pop16
-; CHECK-NEXT:    call $push25=, frexp, $pop10, $pop17
-; CHECK-NEXT:    local.set 0, $pop25
+; CHECK-NEXT:    call $push10=, ldexp, $pop25, $pop9
 ; CHECK-NEXT:    local.get $push26=, 3
-; CHECK-NEXT:    i32.load $push11=, 12($pop26)
+; CHECK-NEXT:    i32.const $push18=, 4
+; CHECK-NEXT:    i32.add $push19=, $pop26, $pop18
+; CHECK-NEXT:    call $push27=, frexp, $pop10, $pop19
+; CHECK-NEXT:    local.set 0, $pop27
+; CHECK-NEXT:    local.get $push28=, 3
+; CHECK-NEXT:    i32.load $push11=, 4($pop28)
 ; CHECK-NEXT:    call escape_value, $pop11
-; CHECK-NEXT:    local.get $push27=, 3
+; CHECK-NEXT:    local.get $push31=, 0
+; CHECK-NEXT:    local.get $push29=, 3
+; CHECK-NEXT:    i32.const $push16=, 8
+; CHECK-NEXT:    i32.add $push17=, $pop29, $pop16
+; CHECK-NEXT:    call $push30=, modf, $pop31, $pop17
+; CHECK-NEXT:    local.set 0, $pop30
+; CHECK-NEXT:    local.get $push32=, 3
 ; CHECK-NEXT:    i32.const $push14=, 16
-; CHECK-NEXT:    i32.add $push15=, $pop27, $pop14
+; CHECK-NEXT:    i32.add $push15=, $pop32, $pop14
 ; CHECK-NEXT:    global.set __stack_pointer, $pop15
-; CHECK-NEXT:    local.get $push28=, 0
-; CHECK-NEXT:    return $pop28
+; CHECK-NEXT:    local.get $push33=, 0
+; CHECK-NEXT:    return $pop33
 
 
  %k = call double @llvm.tan.f64(double %x)
@@ -251,8 +258,10 @@ define double @f64libcalls(double %x, double %y, i32 %z) {
  %result = call {double, i32} @llvm.frexp.f64.i32(double %j)
  %result.0 = extractvalue { double, i32 } %result, 0
  %result.1 = extractvalue { double, i32 } %result, 1
+ %resultModf = call {double, double} @llvm.modf.f64(double %result.0)
+ %resultModf.0 = extractvalue { double, double } %resultModf, 0
  call void @escape_value(i32 %result.1)
- ret double %result.0
+ ret double %resultModf.0
 }
 
 ; fcmp ord and unord (RTLIB::O_F32 / RTLIB::UO_F32 etc) are a special case (see

@dschuff dschuff requested review from aheejin and sbc100 March 6, 2025 23:00
@dschuff dschuff changed the title [WebAssembly] Add modf/modff/modfl to WebAssemblyRuntimeLibcallSignatures.cpp [WebAssembly] Add Libcall signatures for modf and variants Mar 6, 2025
@dschuff dschuff merged commit 6916438 into llvm:main Mar 6, 2025
8 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants