Derek Schuff | bfb02ae | 2018-01-19 17:45:54 +0000 | [diff] [blame] | 1 | ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s |
| 2 | |
| 3 | ; Test a subset of compiler-rt/libm libcalls expected to be emitted by the wasm backend |
| 4 | |
| 5 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" |
| 6 | target triple = "wasm32-unknown-unknown-wasm" |
| 7 | |
| 8 | declare fp128 @llvm.sqrt.f128(fp128) |
| 9 | declare fp128 @llvm.floor.f128(fp128) |
| 10 | declare fp128 @llvm.trunc.f128(fp128) |
| 11 | declare fp128 @llvm.nearbyint.f128(fp128) |
| 12 | declare fp128 @llvm.pow.f128(fp128, fp128) |
| 13 | |
| 14 | declare double @llvm.cos.f64(double) |
| 15 | declare double @llvm.log10.f64(double) |
| 16 | |
| 17 | |
| 18 | ; CHECK-LABEL: fp128libcalls: |
| 19 | define fp128 @fp128libcalls(fp128 %x, fp128 %y) { |
| 20 | ; compiler-rt call |
| 21 | ; CHECK: call __addtf3 |
| 22 | %a = fadd fp128 %x, %y |
| 23 | ; CHECK: call __multf3 |
| 24 | %b = fmul fp128 %a, %y |
| 25 | ; CHECK: call __divtf3 |
| 26 | %c = fdiv fp128 %b, %y |
| 27 | ; libm calls |
| 28 | ; CHECK: call sqrtl |
| 29 | %d = call fp128 @llvm.sqrt.f128(fp128 %c) |
| 30 | ; CHECK: call floorl |
| 31 | %e = call fp128 @llvm.floor.f128(fp128 %d) |
| 32 | ; CHECK: call powl |
| 33 | %f = call fp128 @llvm.pow.f128(fp128 %e, fp128 %y) |
| 34 | ; CHECK: call truncl |
| 35 | %g = call fp128 @llvm.trunc.f128(fp128 %f) |
| 36 | ; CHECK: call nearbyintl |
| 37 | %h = call fp128 @llvm.nearbyint.f128(fp128 %g) |
| 38 | ret fp128 %h |
| 39 | } |
| 40 | |
| 41 | ; CHECK-LABEL: i128libcalls: |
| 42 | define i128 @i128libcalls(i128 %x, i128 %y) { |
| 43 | ; Basic ops should be expanded |
| 44 | ; CHECK_NOT: call |
| 45 | %a = add i128 %x, %y |
| 46 | ; CHECK: call __multi3 |
| 47 | %b = mul i128 %a, %y |
| 48 | ; CHECK: call __umodti3 |
| 49 | %c = urem i128 %b, %y |
| 50 | ret i128 %c |
| 51 | } |
| 52 | |
| 53 | ; CHECK-LABEL: f64libcalls: |
| 54 | define double @f64libcalls(double %x, double %y) { |
| 55 | ; CHECK: f64.call $push{{[0-9]}}=, cos@FUNCTION |
| 56 | %a = call double @llvm.cos.f64(double %x) |
| 57 | ; CHECK: f64.call $push{{[0-9]}}=, log10@FUNCTION |
| 58 | %b = call double @llvm.log10.f64(double %a) |
| 59 | ret double %b |
| 60 | } |
| 61 | |
| 62 | ; fcmp ord and unord (RTLIB::O_F32 / RTLIB::UO_F32 etc) are a special case (see |
| 63 | ; comment in WebAssemblyRunimeLibcallSignatures.cpp) so check them separately. |
| 64 | ; no libcalls are needed for f32 and f64 |
| 65 | |
| 66 | ; CHECK-LABEL: unordd: |
| 67 | define i1 @unordd(double %x, double %y) { |
| 68 | ; CHECK-NOT: call |
| 69 | ; CHECK: f64.ne |
| 70 | %a = fcmp uno double %x, %y |
| 71 | ; CHECK-NOT: call |
| 72 | ; CHECK: f64.eq |
| 73 | %b = fcmp ord double %x, %y |
| 74 | ; CHECK: i32.xor |
| 75 | %c = xor i1 %a, %b |
| 76 | ret i1 %c |
| 77 | } |
| 78 | |
| 79 | ; CHECK-LABEL: unordf: |
| 80 | define i1 @unordf(float %x, float %y) { |
| 81 | ; CHECK-NOT: call |
| 82 | ; CHECK: f32.ne |
| 83 | %a = fcmp uno float %x, %y |
| 84 | ; CHECK-NOT: call |
| 85 | ; CHECK: f32.eq |
| 86 | %b = fcmp ord float %x, %y |
| 87 | ; CHECK: i32.xor |
| 88 | %c = xor i1 %a, %b |
| 89 | ret i1 %c |
| 90 | } |
| 91 | |
| 92 | ; CHECK-LABEL: unordt: |
| 93 | define i1 @unordt(fp128 %x, fp128 %y) { |
| 94 | ; CHECK: i32.call $push[[CALL:[0-9]]]=, __unordtf2 |
| 95 | ; CHECK-NEXT: i32.const $push[[ZERO:[0-9]+]]=, 0 |
| 96 | ; CHECK-NEXT: i32.ne $push{{[0-9]}}=, $pop[[CALL]], $pop[[ZERO]] |
| 97 | %a = fcmp uno fp128 %x, %y |
| 98 | ret i1 %a |
| 99 | } |
| 100 | |
| 101 | ; CHECK-LABEL: ordt: |
| 102 | define i1 @ordt(fp128 %x, fp128 %y) { |
| 103 | ; CHECK: i32.call $push[[CALL:[0-9]]]=, __unordtf2 |
| 104 | ; CHECK-NEXT: i32.eqz $push{{[0-9]}}=, $pop[[CALL]] |
| 105 | %a = fcmp ord fp128 %x, %y |
| 106 | ret i1 %a |
| 107 | } |