1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -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 6 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 7 target triple = "wasm32-unknown-unknown" 8 9 ; CHECK-LABEL: i32_trunc_s_f32: 10 ; CHECK-NEXT: .param f32{{$}} 11 ; CHECK-NEXT: .result i32{{$}} 12 ; CHECK-NEXT: block 13 ; CHECK-NEXT: f32.abs $push[[ABS:[0-9]+]]=, $0{{$}} 14 ; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p31{{$}} 15 ; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}} 16 ; CHECK-NEXT: br_if 0, $pop[[LT]]{{$}} 17 ; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, -2147483648{{$}} 18 ; CHECK-NEXT: return $pop[[ALT]]{{$}} 19 ; CHECK-NEXT: BB 20 ; CHECK-NEXT: end_block 21 ; CHECK-NEXT: i32.trunc_s/f32 $push[[NUM:[0-9]+]]=, $0{{$}} 22 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 23 define 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: .param f32{{$}} 30 ; CHECK-NEXT: .result i32{{$}} 31 ; CHECK-NEXT: block 32 ; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p32{{$}} 33 ; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}} 34 ; CHECK-NEXT: f32.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}} 35 ; CHECK-NEXT: f32.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}} 36 ; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}} 37 ; CHECK-NEXT: br_if 0, $pop[[AND]]{{$}} 38 ; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, 0{{$}} 39 ; CHECK-NEXT: return $pop[[ALT]]{{$}} 40 ; CHECK-NEXT: BB 41 ; CHECK-NEXT: end_block 42 ; CHECK-NEXT: i32.trunc_u/f32 $push[[NUM:[0-9]+]]=, $0{{$}} 43 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 44 define 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: .param f64{{$}} 51 ; CHECK-NEXT: .result i32{{$}} 52 ; CHECK-NEXT: block 53 ; CHECK-NEXT: f64.abs $push[[ABS:[0-9]+]]=, $0{{$}} 54 ; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p31{{$}} 55 ; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}} 56 ; CHECK-NEXT: br_if 0, $pop[[LT]]{{$}} 57 ; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, -2147483648{{$}} 58 ; CHECK-NEXT: return $pop[[ALT]]{{$}} 59 ; CHECK-NEXT: BB 60 ; CHECK-NEXT: end_block 61 ; CHECK-NEXT: i32.trunc_s/f64 $push[[NUM:[0-9]+]]=, $0{{$}} 62 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 63 define 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: .param f64{{$}} 70 ; CHECK-NEXT: .result i32{{$}} 71 ; CHECK-NEXT: block 72 ; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p32{{$}} 73 ; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}} 74 ; CHECK-NEXT: f64.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}} 75 ; CHECK-NEXT: f64.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}} 76 ; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}} 77 ; CHECK-NEXT: br_if 0, $pop[[AND]]{{$}} 78 ; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, 0{{$}} 79 ; CHECK-NEXT: return $pop[[ALT]]{{$}} 80 ; CHECK-NEXT: BB 81 ; CHECK-NEXT: end_block 82 ; CHECK-NEXT: i32.trunc_u/f64 $push[[NUM:[0-9]+]]=, $0{{$}} 83 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 84 define 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: .param f32{{$}} 91 ; CHECK-NEXT: .result i64{{$}} 92 ; CHECK-NEXT: block 93 ; CHECK-NEXT: f32.abs $push[[ABS:[0-9]+]]=, $0{{$}} 94 ; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p63{{$}} 95 ; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}} 96 ; CHECK-NEXT: br_if 0, $pop[[LT]]{{$}} 97 ; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, -9223372036854775808{{$}} 98 ; CHECK-NEXT: return $pop[[ALT]]{{$}} 99 ; CHECK-NEXT: BB 100 ; CHECK-NEXT: end_block 101 ; CHECK-NEXT: i64.trunc_s/f32 $push[[NUM:[0-9]+]]=, $0{{$}} 102 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 103 define 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: .param f32{{$}} 110 ; CHECK-NEXT: .result i64{{$}} 111 ; CHECK-NEXT: block 112 ; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p64{{$}} 113 ; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}} 114 ; CHECK-NEXT: f32.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}} 115 ; CHECK-NEXT: f32.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}} 116 ; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}} 117 ; CHECK-NEXT: br_if 0, $pop[[AND]]{{$}} 118 ; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, 0{{$}} 119 ; CHECK-NEXT: return $pop[[ALT]]{{$}} 120 ; CHECK-NEXT: BB 121 ; CHECK-NEXT: end_block 122 ; CHECK-NEXT: i64.trunc_u/f32 $push[[NUM:[0-9]+]]=, $0{{$}} 123 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 124 define 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: .param f64{{$}} 131 ; CHECK-NEXT: .result i64{{$}} 132 ; CHECK-NEXT: block 133 ; CHECK-NEXT: f64.abs $push[[ABS:[0-9]+]]=, $0{{$}} 134 ; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p63{{$}} 135 ; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}} 136 ; CHECK-NEXT: br_if 0, $pop[[LT]]{{$}} 137 ; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, -9223372036854775808{{$}} 138 ; CHECK-NEXT: return $pop[[ALT]]{{$}} 139 ; CHECK-NEXT: BB 140 ; CHECK-NEXT: end_block 141 ; CHECK-NEXT: i64.trunc_s/f64 $push[[NUM:[0-9]+]]=, $0{{$}} 142 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 143 define 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: .param f64{{$}} 150 ; CHECK-NEXT: .result i64{{$}} 151 ; CHECK-NEXT: block 152 ; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p64{{$}} 153 ; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}} 154 ; CHECK-NEXT: f64.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}} 155 ; CHECK-NEXT: f64.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}} 156 ; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}} 157 ; CHECK-NEXT: br_if 0, $pop[[AND]]{{$}} 158 ; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, 0{{$}} 159 ; CHECK-NEXT: return $pop[[ALT]]{{$}} 160 ; CHECK-NEXT: BB 161 ; CHECK-NEXT: end_block 162 ; CHECK-NEXT: i64.trunc_u/f64 $push[[NUM:[0-9]+]]=, $0{{$}} 163 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 164 define i64 @i64_trunc_u_f64(double %x) { 165 %a = fptoui double %x to i64 166 ret i64 %a 167 } 168