Skip to content

Commit 6916438

Browse files
authored
[WebAssembly] Add Libcall signatures for modf and variants (#130201)
Clang now lowers modf/modff/modfl as builtins using the llvm.modf intrinsic.
1 parent bf12954 commit 6916438

File tree

2 files changed

+58
-22
lines changed

2 files changed

+58
-22
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ enum RuntimeLibcallSignature {
4545
i64_func_i64,
4646
f32_func_f32_f32,
4747
f32_func_f32_i32,
48+
f32_func_f32_iPTR,
4849
f32_func_i64_i64,
4950
f64_func_f64_f64,
5051
f64_func_f64_i32,
52+
f64_func_f64_iPTR,
5153
f64_func_i64_i64,
5254
i16_func_f32,
5355
i16_func_f64,
@@ -69,6 +71,7 @@ enum RuntimeLibcallSignature {
6971
i16_i16_func_i16_i16,
7072
i32_i32_func_i32_i32,
7173
i64_i64_func_i64_i64,
74+
i64_i64_func_i64_i64_iPTR,
7275
i64_i64_func_i64_i64_i64_i64,
7376
i64_i64_func_i64_i64_i64_i64_iPTR,
7477
i64_i64_i64_i64_func_i64_i64_i64_i64,
@@ -278,6 +281,9 @@ struct RuntimeLibcallSignatureTable {
278281
Table[RTLIB::FREXP_F32] = f32_func_f32_i32;
279282
Table[RTLIB::FREXP_F64] = f64_func_f64_i32;
280283
Table[RTLIB::FREXP_F128] = i64_i64_func_i64_i64_i32;
284+
Table[RTLIB::MODF_F32] = f32_func_f32_iPTR;
285+
Table[RTLIB::MODF_F64] = f64_func_f64_iPTR;
286+
Table[RTLIB::MODF_F128] = i64_i64_func_i64_i64_iPTR;
281287

282288
// Conversion
283289
// All F80 and PPCF128 routines are unsupported.
@@ -628,6 +634,11 @@ void WebAssembly::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
628634
Params.push_back(wasm::ValType::F32);
629635
Params.push_back(wasm::ValType::I32);
630636
break;
637+
case f32_func_f32_iPTR:
638+
Rets.push_back(wasm::ValType::F32);
639+
Params.push_back(wasm::ValType::F32);
640+
Params.push_back(PtrTy);
641+
break;
631642
case f32_func_i64_i64:
632643
Rets.push_back(wasm::ValType::F32);
633644
Params.push_back(wasm::ValType::I64);
@@ -648,6 +659,11 @@ void WebAssembly::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
648659
Params.push_back(wasm::ValType::I64);
649660
Params.push_back(wasm::ValType::I64);
650661
break;
662+
case f64_func_f64_iPTR:
663+
Rets.push_back(wasm::ValType::F64);
664+
Params.push_back(wasm::ValType::F64);
665+
Params.push_back(PtrTy);
666+
break;
651667
case i16_func_f32:
652668
Rets.push_back(wasm::ValType::I32);
653669
Params.push_back(wasm::ValType::F32);
@@ -761,6 +777,17 @@ void WebAssembly::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
761777
Params.push_back(wasm::ValType::I64);
762778
Params.push_back(wasm::ValType::I64);
763779
break;
780+
case i64_i64_func_i64_i64_iPTR:
781+
if (WebAssembly::canLowerMultivalueReturn(&Subtarget)) {
782+
Rets.push_back(wasm::ValType::I64);
783+
Rets.push_back(wasm::ValType::I64);
784+
} else {
785+
Params.push_back(PtrTy);
786+
}
787+
Params.push_back(wasm::ValType::I64);
788+
Params.push_back(wasm::ValType::I64);
789+
Params.push_back(PtrTy);
790+
break;
764791
case i64_i64_func_i64_i64_i64_i64:
765792
if (WebAssembly::canLowerMultivalueReturn(&Subtarget)) {
766793
Rets.push_back(wasm::ValType::I64);

llvm/test/CodeGen/WebAssembly/libcalls.ll

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ declare double @llvm.exp10.f64(double)
2323
declare double @llvm.ldexp.f64.i32(double, i32)
2424
declare {double, i32} @llvm.frexp.f64.i32(double)
2525
declare i32 @llvm.lround(double)
26+
declare {double, double} @llvm.modf.f64(double)
2627

2728
declare void @escape_value(i32)
2829

@@ -203,38 +204,44 @@ define double @f64libcalls(double %x, double %y, i32 %z) {
203204
; CHECK-NEXT: # %bb.0:
204205
; CHECK-NEXT: global.get $push12=, __stack_pointer
205206
; CHECK-NEXT: i32.const $push13=, 16
206-
; CHECK-NEXT: i32.sub $push19=, $pop12, $pop13
207-
; CHECK-NEXT: local.tee $push18=, 3, $pop19
208-
; CHECK-NEXT: global.set __stack_pointer, $pop18
209-
; CHECK-NEXT: local.get $push23=, 0
210-
; CHECK-NEXT: local.get $push20=, 0
211-
; CHECK-NEXT: call $push0=, tan, $pop20
207+
; CHECK-NEXT: i32.sub $push21=, $pop12, $pop13
208+
; CHECK-NEXT: local.tee $push20=, 3, $pop21
209+
; CHECK-NEXT: global.set __stack_pointer, $pop20
210+
; CHECK-NEXT: local.get $push25=, 0
211+
; CHECK-NEXT: local.get $push22=, 0
212+
; CHECK-NEXT: call $push0=, tan, $pop22
212213
; CHECK-NEXT: call $push1=, cos, $pop0
213214
; CHECK-NEXT: call $push2=, log10, $pop1
214-
; CHECK-NEXT: local.get $push21=, 1
215-
; CHECK-NEXT: call $push3=, pow, $pop2, $pop21
216-
; CHECK-NEXT: local.get $push22=, 2
217-
; CHECK-NEXT: call $push4=, __powidf2, $pop3, $pop22
215+
; CHECK-NEXT: local.get $push23=, 1
216+
; CHECK-NEXT: call $push3=, pow, $pop2, $pop23
217+
; CHECK-NEXT: local.get $push24=, 2
218+
; CHECK-NEXT: call $push4=, __powidf2, $pop3, $pop24
218219
; CHECK-NEXT: call $push5=, log, $pop4
219220
; CHECK-NEXT: call $push6=, exp, $pop5
220221
; CHECK-NEXT: call $push7=, exp10, $pop6
221222
; CHECK-NEXT: call $push8=, cbrt, $pop7
222223
; CHECK-NEXT: call $push9=, lround, $pop8
223-
; CHECK-NEXT: call $push10=, ldexp, $pop23, $pop9
224-
; CHECK-NEXT: local.get $push24=, 3
225-
; CHECK-NEXT: i32.const $push16=, 12
226-
; CHECK-NEXT: i32.add $push17=, $pop24, $pop16
227-
; CHECK-NEXT: call $push25=, frexp, $pop10, $pop17
228-
; CHECK-NEXT: local.set 0, $pop25
224+
; CHECK-NEXT: call $push10=, ldexp, $pop25, $pop9
229225
; CHECK-NEXT: local.get $push26=, 3
230-
; CHECK-NEXT: i32.load $push11=, 12($pop26)
226+
; CHECK-NEXT: i32.const $push18=, 4
227+
; CHECK-NEXT: i32.add $push19=, $pop26, $pop18
228+
; CHECK-NEXT: call $push27=, frexp, $pop10, $pop19
229+
; CHECK-NEXT: local.set 0, $pop27
230+
; CHECK-NEXT: local.get $push28=, 3
231+
; CHECK-NEXT: i32.load $push11=, 4($pop28)
231232
; CHECK-NEXT: call escape_value, $pop11
232-
; CHECK-NEXT: local.get $push27=, 3
233+
; CHECK-NEXT: local.get $push31=, 0
234+
; CHECK-NEXT: local.get $push29=, 3
235+
; CHECK-NEXT: i32.const $push16=, 8
236+
; CHECK-NEXT: i32.add $push17=, $pop29, $pop16
237+
; CHECK-NEXT: call $push30=, modf, $pop31, $pop17
238+
; CHECK-NEXT: local.set 0, $pop30
239+
; CHECK-NEXT: local.get $push32=, 3
233240
; CHECK-NEXT: i32.const $push14=, 16
234-
; CHECK-NEXT: i32.add $push15=, $pop27, $pop14
241+
; CHECK-NEXT: i32.add $push15=, $pop32, $pop14
235242
; CHECK-NEXT: global.set __stack_pointer, $pop15
236-
; CHECK-NEXT: local.get $push28=, 0
237-
; CHECK-NEXT: return $pop28
243+
; CHECK-NEXT: local.get $push33=, 0
244+
; CHECK-NEXT: return $pop33
238245

239246

240247
%k = call double @llvm.tan.f64(double %x)
@@ -251,8 +258,10 @@ define double @f64libcalls(double %x, double %y, i32 %z) {
251258
%result = call {double, i32} @llvm.frexp.f64.i32(double %j)
252259
%result.0 = extractvalue { double, i32 } %result, 0
253260
%result.1 = extractvalue { double, i32 } %result, 1
261+
%resultModf = call {double, double} @llvm.modf.f64(double %result.0)
262+
%resultModf.0 = extractvalue { double, double } %resultModf, 0
254263
call void @escape_value(i32 %result.1)
255-
ret double %result.0
264+
ret double %resultModf.0
256265
}
257266

258267
; fcmp ord and unord (RTLIB::O_F32 / RTLIB::UO_F32 etc) are a special case (see

0 commit comments

Comments
 (0)