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