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