1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s 2 3 ; Test that basic conversion 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 ; CHECK-LABEL: i32_wrap_i64: 9 ; CHECK-NEXT: .param i64{{$}} 10 ; CHECK-NEXT: .result i32{{$}} 11 ; CHECK-NEXT: i32.wrap/i64 $push[[NUM:[0-9]+]]=, $0{{$}} 12 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 13 define i32 @i32_wrap_i64(i64 %x) { 14 %a = trunc i64 %x to i32 15 ret i32 %a 16 } 17 18 ; CHECK-LABEL: i64_extend_s_i32: 19 ; CHECK-NEXT: .param i32{{$}} 20 ; CHECK-NEXT: .result i64{{$}} 21 ; CHECK-NEXT: i64.extend_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}} 22 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 23 define i64 @i64_extend_s_i32(i32 %x) { 24 %a = sext i32 %x to i64 25 ret i64 %a 26 } 27 28 ; CHECK-LABEL: i64_extend_u_i32: 29 ; CHECK-NEXT: .param i32{{$}} 30 ; CHECK-NEXT: .result i64{{$}} 31 ; CHECK-NEXT: i64.extend_u/i32 $push[[NUM:[0-9]+]]=, $0{{$}} 32 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 33 define i64 @i64_extend_u_i32(i32 %x) { 34 %a = zext i32 %x to i64 35 ret i64 %a 36 } 37 38 ; CHECK-LABEL: i32_trunc_s_f32: 39 ; CHECK-NEXT: .param f32{{$}} 40 ; CHECK-NEXT: .result i32{{$}} 41 ; CHECK-NEXT: i32.trunc_s/f32 $push[[NUM:[0-9]+]]=, $0{{$}} 42 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 43 define i32 @i32_trunc_s_f32(float %x) { 44 %a = fptosi float %x to i32 45 ret i32 %a 46 } 47 48 ; CHECK-LABEL: i32_trunc_u_f32: 49 ; CHECK-NEXT: .param f32{{$}} 50 ; CHECK-NEXT: .result i32{{$}} 51 ; CHECK-NEXT: i32.trunc_u/f32 $push[[NUM:[0-9]+]]=, $0{{$}} 52 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 53 define i32 @i32_trunc_u_f32(float %x) { 54 %a = fptoui float %x to i32 55 ret i32 %a 56 } 57 58 ; CHECK-LABEL: i32_trunc_s_f64: 59 ; CHECK-NEXT: .param f64{{$}} 60 ; CHECK-NEXT: .result i32{{$}} 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: i32.trunc_u/f64 $push[[NUM:[0-9]+]]=, $0{{$}} 72 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 73 define i32 @i32_trunc_u_f64(double %x) { 74 %a = fptoui double %x to i32 75 ret i32 %a 76 } 77 78 ; CHECK-LABEL: i64_trunc_s_f32: 79 ; CHECK-NEXT: .param f32{{$}} 80 ; CHECK-NEXT: .result i64{{$}} 81 ; CHECK-NEXT: i64.trunc_s/f32 $push[[NUM:[0-9]+]]=, $0{{$}} 82 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 83 define i64 @i64_trunc_s_f32(float %x) { 84 %a = fptosi float %x to i64 85 ret i64 %a 86 } 87 88 ; CHECK-LABEL: i64_trunc_u_f32: 89 ; CHECK-NEXT: .param f32{{$}} 90 ; CHECK-NEXT: .result i64{{$}} 91 ; CHECK-NEXT: i64.trunc_u/f32 $push[[NUM:[0-9]+]]=, $0{{$}} 92 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 93 define i64 @i64_trunc_u_f32(float %x) { 94 %a = fptoui float %x to i64 95 ret i64 %a 96 } 97 98 ; CHECK-LABEL: i64_trunc_s_f64: 99 ; CHECK-NEXT: .param f64{{$}} 100 ; CHECK-NEXT: .result i64{{$}} 101 ; CHECK-NEXT: i64.trunc_s/f64 $push[[NUM:[0-9]+]]=, $0{{$}} 102 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 103 define i64 @i64_trunc_s_f64(double %x) { 104 %a = fptosi double %x to i64 105 ret i64 %a 106 } 107 108 ; CHECK-LABEL: i64_trunc_u_f64: 109 ; CHECK-NEXT: .param f64{{$}} 110 ; CHECK-NEXT: .result i64{{$}} 111 ; CHECK-NEXT: i64.trunc_u/f64 $push[[NUM:[0-9]+]]=, $0{{$}} 112 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 113 define i64 @i64_trunc_u_f64(double %x) { 114 %a = fptoui double %x to i64 115 ret i64 %a 116 } 117 118 ; CHECK-LABEL: f32_convert_s_i32: 119 ; CHECK-NEXT: .param i32{{$}} 120 ; CHECK-NEXT: .result f32{{$}} 121 ; CHECK-NEXT: f32.convert_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}} 122 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 123 define float @f32_convert_s_i32(i32 %x) { 124 %a = sitofp i32 %x to float 125 ret float %a 126 } 127 128 ; CHECK-LABEL: f32_convert_u_i32: 129 ; CHECK-NEXT: .param i32{{$}} 130 ; CHECK-NEXT: .result f32{{$}} 131 ; CHECK-NEXT: f32.convert_u/i32 $push[[NUM:[0-9]+]]=, $0{{$}} 132 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 133 define float @f32_convert_u_i32(i32 %x) { 134 %a = uitofp i32 %x to float 135 ret float %a 136 } 137 138 ; CHECK-LABEL: f64_convert_s_i32: 139 ; CHECK-NEXT: .param i32{{$}} 140 ; CHECK-NEXT: .result f64{{$}} 141 ; CHECK-NEXT: f64.convert_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}} 142 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 143 define double @f64_convert_s_i32(i32 %x) { 144 %a = sitofp i32 %x to double 145 ret double %a 146 } 147 148 ; CHECK-LABEL: f64_convert_u_i32: 149 ; CHECK-NEXT: .param i32{{$}} 150 ; CHECK-NEXT: .result f64{{$}} 151 ; CHECK-NEXT: f64.convert_u/i32 $push[[NUM:[0-9]+]]=, $0{{$}} 152 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 153 define double @f64_convert_u_i32(i32 %x) { 154 %a = uitofp i32 %x to double 155 ret double %a 156 } 157 158 ; CHECK-LABEL: f32_convert_s_i64: 159 ; CHECK-NEXT: .param i64{{$}} 160 ; CHECK-NEXT: .result f32{{$}} 161 ; CHECK-NEXT: f32.convert_s/i64 $push[[NUM:[0-9]+]]=, $0{{$}} 162 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 163 define float @f32_convert_s_i64(i64 %x) { 164 %a = sitofp i64 %x to float 165 ret float %a 166 } 167 168 ; CHECK-LABEL: f32_convert_u_i64: 169 ; CHECK-NEXT: .param i64{{$}} 170 ; CHECK-NEXT: .result f32{{$}} 171 ; CHECK-NEXT: f32.convert_u/i64 $push[[NUM:[0-9]+]]=, $0{{$}} 172 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 173 define float @f32_convert_u_i64(i64 %x) { 174 %a = uitofp i64 %x to float 175 ret float %a 176 } 177 178 ; CHECK-LABEL: f64_convert_s_i64: 179 ; CHECK-NEXT: .param i64{{$}} 180 ; CHECK-NEXT: .result f64{{$}} 181 ; CHECK-NEXT: f64.convert_s/i64 $push[[NUM:[0-9]+]]=, $0{{$}} 182 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 183 define double @f64_convert_s_i64(i64 %x) { 184 %a = sitofp i64 %x to double 185 ret double %a 186 } 187 188 ; CHECK-LABEL: f64_convert_u_i64: 189 ; CHECK-NEXT: .param i64{{$}} 190 ; CHECK-NEXT: .result f64{{$}} 191 ; CHECK-NEXT: f64.convert_u/i64 $push[[NUM:[0-9]+]]=, $0{{$}} 192 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 193 define double @f64_convert_u_i64(i64 %x) { 194 %a = uitofp i64 %x to double 195 ret double %a 196 } 197 198 ; CHECK-LABEL: f64_promote_f32: 199 ; CHECK-NEXT: .param f32{{$}} 200 ; CHECK-NEXT: .result f64{{$}} 201 ; CHECK-NEXT: f64.promote/f32 $push[[NUM:[0-9]+]]=, $0{{$}} 202 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 203 define double @f64_promote_f32(float %x) { 204 %a = fpext float %x to double 205 ret double %a 206 } 207 208 ; CHECK-LABEL: f32_demote_f64: 209 ; CHECK-NEXT: .param f64{{$}} 210 ; CHECK-NEXT: .result f32{{$}} 211 ; CHECK-NEXT: f32.demote/f64 $push[[NUM:[0-9]+]]=, $0{{$}} 212 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 213 define float @f32_demote_f64(double %x) { 214 %a = fptrunc double %x to float 215 ret float %a 216 } 217 218 ; If the high its are unused, LLVM will optimize sext/zext into anyext, which 219 ; we need to patterm-match back to a specific instruction. 220 221 ; CHECK-LABEL: anyext: 222 ; CHECK: i64.extend_u/i32 $push0=, $0{{$}} 223 define i64 @anyext(i32 %x) { 224 %y = sext i32 %x to i64 225 %w = shl i64 %y, 32 226 ret i64 %w 227 } 228 229 ; CHECK-LABEL: bitcast_i32_to_float: 230 ; CHECK: f32.reinterpret/i32 $push0=, $0{{$}} 231 define float @bitcast_i32_to_float(i32 %a) { 232 %t = bitcast i32 %a to float 233 ret float %t 234 } 235 236 ; CHECK-LABEL: bitcast_float_to_i32: 237 ; CHECK: i32.reinterpret/f32 $push0=, $0{{$}} 238 define i32 @bitcast_float_to_i32(float %a) { 239 %t = bitcast float %a to i32 240 ret i32 %t 241 } 242 243 ; CHECK-LABEL: bitcast_i64_to_double: 244 ; CHECK: f64.reinterpret/i64 $push0=, $0{{$}} 245 define double @bitcast_i64_to_double(i64 %a) { 246 %t = bitcast i64 %a to double 247 ret double %t 248 } 249 250 ; CHECK-LABEL: bitcast_double_to_i64: 251 ; CHECK: i64.reinterpret/f64 $push0=, $0{{$}} 252 define i64 @bitcast_double_to_i64(double %a) { 253 %t = bitcast double %a to i64 254 ret i64 %t 255 } 256