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