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