1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=-nontrapping-fptoint | FileCheck %s 2 3; Test that basic conversion operations assemble as expected using 4; the trapping opcodes and explicit code to suppress the trapping. 5 6target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 7target triple = "wasm32-unknown-unknown" 8 9; CHECK-LABEL: i32_trunc_s_f32: 10; CHECK-NEXT: .functype i32_trunc_s_f32 (f32) -> (i32){{$}} 11; CHECK-NEXT: block 12; CHECK-NEXT: f32.abs $push[[ABS:[0-9]+]]=, $0{{$}} 13; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p31{{$}} 14; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}} 15; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[LT]] 16; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}} 17; CHECK-NEXT: i32.trunc_f32_s $push[[NUM:[0-9]+]]=, $0{{$}} 18; CHECK-NEXT: return $pop[[NUM]]{{$}} 19; CHECK-NEXT: BB 20; CHECK-NEXT: end_block 21; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, -2147483648{{$}} 22; CHECK-NEXT: return $pop[[ALT]]{{$}} 23define i32 @i32_trunc_s_f32(float %x) { 24 %a = fptosi float %x to i32 25 ret i32 %a 26} 27 28; CHECK-LABEL: i32_trunc_u_f32: 29; CHECK-NEXT: .functype i32_trunc_u_f32 (f32) -> (i32){{$}} 30; CHECK-NEXT: block 31; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p32{{$}} 32; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}} 33; CHECK-NEXT: f32.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}} 34; CHECK-NEXT: f32.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}} 35; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}} 36; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[AND]] 37; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}} 38; CHECK-NEXT: i32.trunc_f32_u $push[[NUM:[0-9]+]]=, $0{{$}} 39; CHECK-NEXT: return $pop[[NUM]]{{$}} 40; CHECK-NEXT: BB 41; CHECK-NEXT: end_block 42; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, 0{{$}} 43; CHECK-NEXT: return $pop[[ALT]]{{$}} 44define i32 @i32_trunc_u_f32(float %x) { 45 %a = fptoui float %x to i32 46 ret i32 %a 47} 48 49; CHECK-LABEL: i32_trunc_s_f64: 50; CHECK-NEXT: .functype i32_trunc_s_f64 (f64) -> (i32){{$}} 51; CHECK-NEXT: block 52; CHECK-NEXT: f64.abs $push[[ABS:[0-9]+]]=, $0{{$}} 53; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p31{{$}} 54; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}} 55; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[LT]] 56; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}} 57; CHECK-NEXT: i32.trunc_f64_s $push[[NUM:[0-9]+]]=, $0{{$}} 58; CHECK-NEXT: return $pop[[NUM]]{{$}} 59; CHECK-NEXT: BB 60; CHECK-NEXT: end_block 61; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, -2147483648{{$}} 62; CHECK-NEXT: return $pop[[ALT]]{{$}} 63define i32 @i32_trunc_s_f64(double %x) { 64 %a = fptosi double %x to i32 65 ret i32 %a 66} 67 68; CHECK-LABEL: i32_trunc_u_f64: 69; CHECK-NEXT: .functype i32_trunc_u_f64 (f64) -> (i32){{$}} 70; CHECK-NEXT: block 71; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p32{{$}} 72; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}} 73; CHECK-NEXT: f64.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}} 74; CHECK-NEXT: f64.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}} 75; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}} 76; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[AND]] 77; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}} 78; CHECK-NEXT: i32.trunc_f64_u $push[[NUM:[0-9]+]]=, $0{{$}} 79; CHECK-NEXT: return $pop[[NUM]]{{$}} 80; CHECK-NEXT: BB 81; CHECK-NEXT: end_block 82; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, 0{{$}} 83; CHECK-NEXT: return $pop[[ALT]]{{$}} 84define i32 @i32_trunc_u_f64(double %x) { 85 %a = fptoui double %x to i32 86 ret i32 %a 87} 88 89; CHECK-LABEL: i64_trunc_s_f32: 90; CHECK-NEXT: .functype i64_trunc_s_f32 (f32) -> (i64){{$}} 91; CHECK-NEXT: block 92; CHECK-NEXT: f32.abs $push[[ABS:[0-9]+]]=, $0{{$}} 93; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p63{{$}} 94; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}} 95; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[LT]] 96; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}} 97; CHECK-NEXT: i64.trunc_f32_s $push[[NUM:[0-9]+]]=, $0{{$}} 98; CHECK-NEXT: return $pop[[NUM]]{{$}} 99; CHECK-NEXT: BB 100; CHECK-NEXT: end_block 101; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, -9223372036854775808{{$}} 102; CHECK-NEXT: return $pop[[ALT]]{{$}} 103define i64 @i64_trunc_s_f32(float %x) { 104 %a = fptosi float %x to i64 105 ret i64 %a 106} 107 108; CHECK-LABEL: i64_trunc_u_f32: 109; CHECK-NEXT: .functype i64_trunc_u_f32 (f32) -> (i64){{$}} 110; CHECK-NEXT: block 111; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p64{{$}} 112; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}} 113; CHECK-NEXT: f32.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}} 114; CHECK-NEXT: f32.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}} 115; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}} 116; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[AND]] 117; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}} 118; CHECK-NEXT: i64.trunc_f32_u $push[[NUM:[0-9]+]]=, $0{{$}} 119; CHECK-NEXT: return $pop[[NUM]]{{$}} 120; CHECK-NEXT: BB 121; CHECK-NEXT: end_block 122; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, 0{{$}} 123; CHECK-NEXT: return $pop[[ALT]]{{$}} 124define i64 @i64_trunc_u_f32(float %x) { 125 %a = fptoui float %x to i64 126 ret i64 %a 127} 128 129; CHECK-LABEL: i64_trunc_s_f64: 130; CHECK-NEXT: .functype i64_trunc_s_f64 (f64) -> (i64){{$}} 131; CHECK-NEXT: block 132; CHECK-NEXT: f64.abs $push[[ABS:[0-9]+]]=, $0{{$}} 133; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p63{{$}} 134; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}} 135; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[LT]] 136; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}} 137; CHECK-NEXT: i64.trunc_f64_s $push[[NUM:[0-9]+]]=, $0{{$}} 138; CHECK-NEXT: return $pop[[NUM]]{{$}} 139; CHECK-NEXT: BB 140; CHECK-NEXT: end_block 141; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, -9223372036854775808{{$}} 142; CHECK-NEXT: return $pop[[ALT]]{{$}} 143define i64 @i64_trunc_s_f64(double %x) { 144 %a = fptosi double %x to i64 145 ret i64 %a 146} 147 148; CHECK-LABEL: i64_trunc_u_f64: 149; CHECK-NEXT: .functype i64_trunc_u_f64 (f64) -> (i64){{$}} 150; CHECK-NEXT: block 151; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p64{{$}} 152; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}} 153; CHECK-NEXT: f64.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}} 154; CHECK-NEXT: f64.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}} 155; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}} 156; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[AND]] 157; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}} 158; CHECK-NEXT: i64.trunc_f64_u $push[[NUM:[0-9]+]]=, $0{{$}} 159; CHECK-NEXT: return $pop[[NUM]]{{$}} 160; CHECK-NEXT: BB 161; CHECK-NEXT: end_block 162; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, 0{{$}} 163; CHECK-NEXT: return $pop[[ALT]]{{$}} 164define i64 @i64_trunc_u_f64(double %x) { 165 %a = fptoui double %x to i64 166 ret i64 %a 167} 168 169; CHECK-LABEL: llvm_wasm_trunc_signed_i32_f32: 170; CHECK-NEXT: .functype llvm_wasm_trunc_signed_i32_f32 (f32) -> (i32) 171; CHECK-NEXT: i32.trunc_f32_s $push[[L0:[0-9]+]]=, $0{{$}} 172; CHECK-NEXT: return $pop[[L0]]{{$}} 173declare i32 @llvm.wasm.trunc.signed.i32.f32(float) 174define i32 @llvm_wasm_trunc_signed_i32_f32(float %f) { 175 %a = call i32 @llvm.wasm.trunc.signed.i32.f32(float %f) 176 ret i32 %a 177} 178 179; CHECK-LABEL: llvm_wasm_trunc_unsigned_i32_f32: 180; CHECK-NEXT: .functype llvm_wasm_trunc_unsigned_i32_f32 (f32) -> (i32) 181; CHECK-NEXT: i32.trunc_f32_u $push[[L0:[0-9]+]]=, $0{{$}} 182; CHECK-NEXT: return $pop[[L0]]{{$}} 183declare i32 @llvm.wasm.trunc.unsigned.i32.f32(float) 184define i32 @llvm_wasm_trunc_unsigned_i32_f32(float %f) { 185 %a = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float %f) 186 ret i32 %a 187} 188 189; CHECK-LABEL: llvm_wasm_trunc_signed_i32_f64: 190; CHECK-NEXT: .functype llvm_wasm_trunc_signed_i32_f64 (f64) -> (i32) 191; CHECK-NEXT: i32.trunc_f64_s $push[[L0:[0-9]+]]=, $0{{$}} 192; CHECK-NEXT: return $pop[[L0]]{{$}} 193declare i32 @llvm.wasm.trunc.signed.i32.f64(double) 194define i32 @llvm_wasm_trunc_signed_i32_f64(double %f) { 195 %a = call i32 @llvm.wasm.trunc.signed.i32.f64(double %f) 196 ret i32 %a 197} 198 199; CHECK-LABEL: llvm_wasm_trunc_unsigned_i32_f64: 200; CHECK-NEXT: .functype llvm_wasm_trunc_unsigned_i32_f64 (f64) -> (i32) 201; CHECK-NEXT: i32.trunc_f64_u $push[[L0:[0-9]+]]=, $0{{$}} 202; CHECK-NEXT: return $pop[[L0]]{{$}} 203declare i32 @llvm.wasm.trunc.unsigned.i32.f64(double) 204define i32 @llvm_wasm_trunc_unsigned_i32_f64(double %f) { 205 %a = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double %f) 206 ret i32 %a 207} 208 209; CHECK-LABEL: llvm_wasm_trunc_signed_i64_f32: 210; CHECK-NEXT: .functype llvm_wasm_trunc_signed_i64_f32 (f32) -> (i64) 211; CHECK-NEXT: i64.trunc_f32_s $push[[L0:[0-9]+]]=, $0{{$}} 212; CHECK-NEXT: return $pop[[L0]]{{$}} 213declare i64 @llvm.wasm.trunc.signed.i64.f32(float) 214define i64 @llvm_wasm_trunc_signed_i64_f32(float %f) { 215 %a = call i64 @llvm.wasm.trunc.signed.i64.f32(float %f) 216 ret i64 %a 217} 218 219; CHECK-LABEL: llvm_wasm_trunc_unsigned_i64_f32: 220; CHECK-NEXT: .functype llvm_wasm_trunc_unsigned_i64_f32 (f32) -> (i64) 221; CHECK-NEXT: i64.trunc_f32_u $push[[L0:[0-9]+]]=, $0{{$}} 222; CHECK-NEXT: return $pop[[L0]]{{$}} 223declare i64 @llvm.wasm.trunc.unsigned.i64.f32(float) 224define i64 @llvm_wasm_trunc_unsigned_i64_f32(float %f) { 225 %a = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float %f) 226 ret i64 %a 227} 228 229; CHECK-LABEL: llvm_wasm_trunc_signed_i64_f64: 230; CHECK-NEXT: .functype llvm_wasm_trunc_signed_i64_f64 (f64) -> (i64) 231; CHECK-NEXT: i64.trunc_f64_s $push[[L0:[0-9]+]]=, $0{{$}} 232; CHECK-NEXT: return $pop[[L0]]{{$}} 233declare i64 @llvm.wasm.trunc.signed.i64.f64(double) 234define i64 @llvm_wasm_trunc_signed_i64_f64(double %f) { 235 %a = call i64 @llvm.wasm.trunc.signed.i64.f64(double %f) 236 ret i64 %a 237} 238 239; CHECK-LABEL: llvm_wasm_trunc_unsigned_i64_f64: 240; CHECK-NEXT: .functype llvm_wasm_trunc_unsigned_i64_f64 (f64) -> (i64) 241; CHECK-NEXT: i64.trunc_f64_u $push[[L0:[0-9]+]]=, $0{{$}} 242; CHECK-NEXT: return $pop[[L0]]{{$}} 243declare i64 @llvm.wasm.trunc.unsigned.i64.f64(double) 244define i64 @llvm_wasm_trunc_unsigned_i64_f64(double %f) { 245 %a = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double %f) 246 ret i64 %a 247} 248