Home | History | Annotate | Download | only in WebAssembly
      1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
      2 
      3 ; Test that basic 32-bit floating-point operations assemble as expected.
      4 
      5 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
      6 target triple = "wasm32-unknown-unknown"
      7 
      8 declare float @llvm.fabs.f32(float)
      9 declare float @llvm.copysign.f32(float, float)
     10 declare float @llvm.sqrt.f32(float)
     11 declare float @llvm.ceil.f32(float)
     12 declare float @llvm.floor.f32(float)
     13 declare float @llvm.trunc.f32(float)
     14 declare float @llvm.nearbyint.f32(float)
     15 declare float @llvm.rint.f32(float)
     16 declare float @llvm.fma.f32(float, float, float)
     17 
     18 ; CHECK-LABEL: fadd32:
     19 ; CHECK-NEXT: .param f32, f32{{$}}
     20 ; CHECK-NEXT: .result f32{{$}}
     21 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}}
     22 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}}
     23 ; CHECK-NEXT: f32.add $push[[LR:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
     24 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     25 define float @fadd32(float %x, float %y) {
     26   %a = fadd float %x, %y
     27   ret float %a
     28 }
     29 
     30 ; CHECK-LABEL: fsub32:
     31 ; CHECK: f32.sub $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
     32 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     33 define float @fsub32(float %x, float %y) {
     34   %a = fsub float %x, %y
     35   ret float %a
     36 }
     37 
     38 ; CHECK-LABEL: fmul32:
     39 ; CHECK: f32.mul $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
     40 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     41 define float @fmul32(float %x, float %y) {
     42   %a = fmul float %x, %y
     43   ret float %a
     44 }
     45 
     46 ; CHECK-LABEL: fdiv32:
     47 ; CHECK: f32.div $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
     48 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     49 define float @fdiv32(float %x, float %y) {
     50   %a = fdiv float %x, %y
     51   ret float %a
     52 }
     53 
     54 ; CHECK-LABEL: fabs32:
     55 ; CHECK: f32.abs $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
     56 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     57 define float @fabs32(float %x) {
     58   %a = call float @llvm.fabs.f32(float %x)
     59   ret float %a
     60 }
     61 
     62 ; CHECK-LABEL: fneg32:
     63 ; CHECK: f32.neg $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
     64 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     65 define float @fneg32(float %x) {
     66   %a = fsub float -0., %x
     67   ret float %a
     68 }
     69 
     70 ; CHECK-LABEL: copysign32:
     71 ; CHECK: f32.copysign $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
     72 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     73 define float @copysign32(float %x, float %y) {
     74   %a = call float @llvm.copysign.f32(float %x, float %y)
     75   ret float %a
     76 }
     77 
     78 ; CHECK-LABEL: sqrt32:
     79 ; CHECK: f32.sqrt $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
     80 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     81 define float @sqrt32(float %x) {
     82   %a = call float @llvm.sqrt.f32(float %x)
     83   ret float %a
     84 }
     85 
     86 ; CHECK-LABEL: ceil32:
     87 ; CHECK: f32.ceil $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
     88 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     89 define float @ceil32(float %x) {
     90   %a = call float @llvm.ceil.f32(float %x)
     91   ret float %a
     92 }
     93 
     94 ; CHECK-LABEL: floor32:
     95 ; CHECK: f32.floor $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
     96 ; CHECK-NEXT: return $pop[[LR]]{{$}}
     97 define float @floor32(float %x) {
     98   %a = call float @llvm.floor.f32(float %x)
     99   ret float %a
    100 }
    101 
    102 ; CHECK-LABEL: trunc32:
    103 ; CHECK: f32.trunc $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
    104 ; CHECK-NEXT: return $pop[[LR]]{{$}}
    105 define float @trunc32(float %x) {
    106   %a = call float @llvm.trunc.f32(float %x)
    107   ret float %a
    108 }
    109 
    110 ; CHECK-LABEL: nearest32:
    111 ; CHECK: f32.nearest $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
    112 ; CHECK-NEXT: return $pop[[LR]]{{$}}
    113 define float @nearest32(float %x) {
    114   %a = call float @llvm.nearbyint.f32(float %x)
    115   ret float %a
    116 }
    117 
    118 ; CHECK-LABEL: nearest32_via_rint:
    119 ; CHECK: f32.nearest $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
    120 ; CHECK-NEXT: return $pop[[LR]]{{$}}
    121 define float @nearest32_via_rint(float %x) {
    122   %a = call float @llvm.rint.f32(float %x)
    123   ret float %a
    124 }
    125 
    126 ; Min and max tests. LLVM currently only forms fminnan and fmaxnan nodes in
    127 ; cases where there's a single fcmp with a select and it can prove that one
    128 ; of the arms is never NaN, so we only test that case. In the future if LLVM
    129 ; learns to form fminnan/fmaxnan in more cases, we can write more general
    130 ; tests.
    131 
    132 ; CHECK-LABEL: fmin32:
    133 ; CHECK: f32.min $push1=, $pop{{[0-9]+}}, $pop[[LR]]{{$}}
    134 ; CHECK-NEXT: return $pop1{{$}}
    135 define float @fmin32(float %x) {
    136   %a = fcmp ult float %x, 0.0
    137   %b = select i1 %a, float %x, float 0.0
    138   ret float %b
    139 }
    140 
    141 ; CHECK-LABEL: fmax32:
    142 ; CHECK: f32.max $push1=, $pop{{[0-9]+}}, $pop[[LR]]{{$}}
    143 ; CHECK-NEXT: return $pop1{{$}}
    144 define float @fmax32(float %x) {
    145   %a = fcmp ugt float %x, 0.0
    146   %b = select i1 %a, float %x, float 0.0
    147   ret float %b
    148 }
    149 
    150 ; CHECK-LABEL: fma32:
    151 ; CHECK: {{^}} f32.call $push[[LR:[0-9]+]]=, fmaf@FUNCTION, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
    152 ; CHECK-NEXT: return $pop[[LR]]{{$}}
    153 define float @fma32(float %a, float %b, float %c) {
    154   %d = call float @llvm.fma.f32(float %a, float %b, float %c)
    155   ret float %d
    156 }
    157