Home | History | Annotate | Download | only in WebAssembly
      1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
      2 
      3 ; Test loads and stores with custom alignment values.
      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: ldi32_a1:
      9 ; CHECK-NEXT: .param i32{{$}}
     10 ; CHECK-NEXT: .result i32{{$}}
     11 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
     12 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
     13 define i32 @ldi32_a1(i32 *%p) {
     14   %v = load i32, i32* %p, align 1
     15   ret i32 %v
     16 }
     17 
     18 ; CHECK-LABEL: ldi32_a2:
     19 ; CHECK-NEXT: .param i32{{$}}
     20 ; CHECK-NEXT: .result i32{{$}}
     21 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
     22 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
     23 define i32 @ldi32_a2(i32 *%p) {
     24   %v = load i32, i32* %p, align 2
     25   ret i32 %v
     26 }
     27 
     28 ; 4 is the default alignment for i32 so no attribute is needed.
     29 
     30 ; CHECK-LABEL: ldi32_a4:
     31 ; CHECK-NEXT: .param i32{{$}}
     32 ; CHECK-NEXT: .result i32{{$}}
     33 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
     34 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
     35 define i32 @ldi32_a4(i32 *%p) {
     36   %v = load i32, i32* %p, align 4
     37   ret i32 %v
     38 }
     39 
     40 ; The default alignment in LLVM is the same as the defualt alignment in wasm.
     41 
     42 ; CHECK-LABEL: ldi32:
     43 ; CHECK-NEXT: .param i32{{$}}
     44 ; CHECK-NEXT: .result i32{{$}}
     45 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
     46 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
     47 define i32 @ldi32(i32 *%p) {
     48   %v = load i32, i32* %p
     49   ret i32 %v
     50 }
     51 
     52 ; 8 is greater than the default alignment so it is ignored.
     53 
     54 ; CHECK-LABEL: ldi32_a8:
     55 ; CHECK-NEXT: .param i32{{$}}
     56 ; CHECK-NEXT: .result i32{{$}}
     57 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
     58 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
     59 define i32 @ldi32_a8(i32 *%p) {
     60   %v = load i32, i32* %p, align 8
     61   ret i32 %v
     62 }
     63 
     64 ; Extending loads.
     65 
     66 ; CHECK-LABEL: ldi8_a1:
     67 ; CHECK-NEXT: .param i32{{$}}
     68 ; CHECK-NEXT: .result i32{{$}}
     69 ; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
     70 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
     71 define i8 @ldi8_a1(i8 *%p) {
     72   %v = load i8, i8* %p, align 1
     73   ret i8 %v
     74 }
     75 
     76 ; CHECK-LABEL: ldi8_a2:
     77 ; CHECK-NEXT: .param i32{{$}}
     78 ; CHECK-NEXT: .result i32{{$}}
     79 ; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
     80 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
     81 define i8 @ldi8_a2(i8 *%p) {
     82   %v = load i8, i8* %p, align 2
     83   ret i8 %v
     84 }
     85 
     86 ; CHECK-LABEL: ldi16_a1:
     87 ; CHECK-NEXT: .param i32{{$}}
     88 ; CHECK-NEXT: .result i32{{$}}
     89 ; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
     90 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
     91 define i16 @ldi16_a1(i16 *%p) {
     92   %v = load i16, i16* %p, align 1
     93   ret i16 %v
     94 }
     95 
     96 ; CHECK-LABEL: ldi16_a2:
     97 ; CHECK-NEXT: .param i32{{$}}
     98 ; CHECK-NEXT: .result i32{{$}}
     99 ; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
    100 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
    101 define i16 @ldi16_a2(i16 *%p) {
    102   %v = load i16, i16* %p, align 2
    103   ret i16 %v
    104 }
    105 
    106 ; CHECK-LABEL: ldi16_a4:
    107 ; CHECK-NEXT: .param i32{{$}}
    108 ; CHECK-NEXT: .result i32{{$}}
    109 ; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
    110 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
    111 define i16 @ldi16_a4(i16 *%p) {
    112   %v = load i16, i16* %p, align 4
    113   ret i16 %v
    114 }
    115 
    116 ; Stores.
    117 
    118 ; CHECK-LABEL: sti32_a1:
    119 ; CHECK-NEXT: .param i32, i32{{$}}
    120 ; CHECK-NEXT: i32.store $drop=, 0($0):p2align=0, $1{{$}}
    121 ; CHECK-NEXT: return{{$}}
    122 define void @sti32_a1(i32 *%p, i32 %v) {
    123   store i32 %v, i32* %p, align 1
    124   ret void
    125 }
    126 
    127 ; CHECK-LABEL: sti32_a2:
    128 ; CHECK-NEXT: .param i32, i32{{$}}
    129 ; CHECK-NEXT: i32.store $drop=, 0($0):p2align=1, $1{{$}}
    130 ; CHECK-NEXT: return{{$}}
    131 define void @sti32_a2(i32 *%p, i32 %v) {
    132   store i32 %v, i32* %p, align 2
    133   ret void
    134 }
    135 
    136 ; 4 is the default alignment for i32 so no attribute is needed.
    137 
    138 ; CHECK-LABEL: sti32_a4:
    139 ; CHECK-NEXT: .param i32, i32{{$}}
    140 ; CHECK-NEXT: i32.store $drop=, 0($0), $1{{$}}
    141 ; CHECK-NEXT: return{{$}}
    142 define void @sti32_a4(i32 *%p, i32 %v) {
    143   store i32 %v, i32* %p, align 4
    144   ret void
    145 }
    146 
    147 ; The default alignment in LLVM is the same as the defualt alignment in wasm.
    148 
    149 ; CHECK-LABEL: sti32:
    150 ; CHECK-NEXT: .param i32, i32{{$}}
    151 ; CHECK-NEXT: i32.store $drop=, 0($0), $1{{$}}
    152 ; CHECK-NEXT: return{{$}}
    153 define void @sti32(i32 *%p, i32 %v) {
    154   store i32 %v, i32* %p
    155   ret void
    156 }
    157 
    158 ; CHECK-LABEL: sti32_a8:
    159 ; CHECK-NEXT: .param i32, i32{{$}}
    160 ; CHECK-NEXT: i32.store $drop=, 0($0), $1{{$}}
    161 ; CHECK-NEXT: return{{$}}
    162 define void @sti32_a8(i32 *%p, i32 %v) {
    163   store i32 %v, i32* %p, align 8
    164   ret void
    165 }
    166 
    167 ; Truncating stores.
    168 
    169 ; CHECK-LABEL: sti8_a1:
    170 ; CHECK-NEXT: .param i32, i32{{$}}
    171 ; CHECK-NEXT: i32.store8 $drop=, 0($0), $1{{$}}
    172 ; CHECK-NEXT: return{{$}}
    173 define void @sti8_a1(i8 *%p, i8 %v) {
    174   store i8 %v, i8* %p, align 1
    175   ret void
    176 }
    177 
    178 ; CHECK-LABEL: sti8_a2:
    179 ; CHECK-NEXT: .param i32, i32{{$}}
    180 ; CHECK-NEXT: i32.store8 $drop=, 0($0), $1{{$}}
    181 ; CHECK-NEXT: return{{$}}
    182 define void @sti8_a2(i8 *%p, i8 %v) {
    183   store i8 %v, i8* %p, align 2
    184   ret void
    185 }
    186 
    187 ; CHECK-LABEL: sti16_a1:
    188 ; CHECK-NEXT: .param i32, i32{{$}}
    189 ; CHECK-NEXT: i32.store16 $drop=, 0($0):p2align=0, $1{{$}}
    190 ; CHECK-NEXT: return{{$}}
    191 define void @sti16_a1(i16 *%p, i16 %v) {
    192   store i16 %v, i16* %p, align 1
    193   ret void
    194 }
    195 
    196 ; CHECK-LABEL: sti16_a2:
    197 ; CHECK-NEXT: .param i32, i32{{$}}
    198 ; CHECK-NEXT: i32.store16 $drop=, 0($0), $1{{$}}
    199 ; CHECK-NEXT: return{{$}}
    200 define void @sti16_a2(i16 *%p, i16 %v) {
    201   store i16 %v, i16* %p, align 2
    202   ret void
    203 }
    204 
    205 ; CHECK-LABEL: sti16_a4:
    206 ; CHECK-NEXT: .param i32, i32{{$}}
    207 ; CHECK-NEXT: i32.store16 $drop=, 0($0), $1{{$}}
    208 ; CHECK-NEXT: return{{$}}
    209 define void @sti16_a4(i16 *%p, i16 %v) {
    210   store i16 %v, i16* %p, align 4
    211   ret void
    212 }
    213