Home | History | Annotate | Download | only in WebAssembly
      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