263 lines · plain
1; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s2 3; Test loads and stores with custom alignment values.4 5target triple = "wasm32-unknown-unknown"6 7;===----------------------------------------------------------------------------8; Loads9;===----------------------------------------------------------------------------10 11; CHECK-LABEL: ldi32_a1:12; CHECK-NEXT: .functype ldi32_a1 (i32) -> (i32){{$}}13; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}14; CHECK-NEXT: return $pop[[NUM]]{{$}}15define i32 @ldi32_a1(ptr %p) {16 %v = load i32, ptr %p, align 117 ret i32 %v18}19 20; CHECK-LABEL: ldi32_a2:21; CHECK-NEXT: .functype ldi32_a2 (i32) -> (i32){{$}}22; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}23; CHECK-NEXT: return $pop[[NUM]]{{$}}24define i32 @ldi32_a2(ptr %p) {25 %v = load i32, ptr %p, align 226 ret i32 %v27}28 29; 4 is the default alignment for i32 so no attribute is needed.30 31; CHECK-LABEL: ldi32_a4:32; CHECK-NEXT: .functype ldi32_a4 (i32) -> (i32){{$}}33; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}34; CHECK-NEXT: return $pop[[NUM]]{{$}}35define i32 @ldi32_a4(ptr %p) {36 %v = load i32, ptr %p, align 437 ret i32 %v38}39 40; The default alignment in LLVM is the same as the default alignment in wasm.41 42; CHECK-LABEL: ldi32:43; CHECK-NEXT: .functype ldi32 (i32) -> (i32){{$}}44; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}45; CHECK-NEXT: return $pop[[NUM]]{{$}}46define i32 @ldi32(ptr %p) {47 %v = load i32, ptr %p48 ret i32 %v49}50 51; 8 is greater than the default alignment so it is ignored.52 53; CHECK-LABEL: ldi32_a8:54; CHECK-NEXT: .functype ldi32_a8 (i32) -> (i32){{$}}55; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}56; CHECK-NEXT: return $pop[[NUM]]{{$}}57define i32 @ldi32_a8(ptr %p) {58 %v = load i32, ptr %p, align 859 ret i32 %v60}61 62;===----------------------------------------------------------------------------63; Extending loads64;===----------------------------------------------------------------------------65 66; CHECK-LABEL: ldi8_a1:67; CHECK-NEXT: .functype ldi8_a1 (i32) -> (i32){{$}}68; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}69; CHECK-NEXT: return $pop[[NUM]]{{$}}70define i8 @ldi8_a1(ptr %p) {71 %v = load i8, ptr %p, align 172 ret i8 %v73}74 75; CHECK-LABEL: ldi8_a2:76; CHECK-NEXT: .functype ldi8_a2 (i32) -> (i32){{$}}77; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}78; CHECK-NEXT: return $pop[[NUM]]{{$}}79define i8 @ldi8_a2(ptr %p) {80 %v = load i8, ptr %p, align 281 ret i8 %v82}83 84; CHECK-LABEL: ldi16_a1:85; CHECK-NEXT: .functype ldi16_a1 (i32) -> (i32){{$}}86; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}87; CHECK-NEXT: return $pop[[NUM]]{{$}}88define i16 @ldi16_a1(ptr %p) {89 %v = load i16, ptr %p, align 190 ret i16 %v91}92 93; CHECK-LABEL: ldi16_a2:94; CHECK-NEXT: .functype ldi16_a2 (i32) -> (i32){{$}}95; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}96; CHECK-NEXT: return $pop[[NUM]]{{$}}97define i16 @ldi16_a2(ptr %p) {98 %v = load i16, ptr %p, align 299 ret i16 %v100}101 102; CHECK-LABEL: ldi16_a4:103; CHECK-NEXT: .functype ldi16_a4 (i32) -> (i32){{$}}104; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}105; CHECK-NEXT: return $pop[[NUM]]{{$}}106define i16 @ldi16_a4(ptr %p) {107 %v = load i16, ptr %p, align 4108 ret i16 %v109}110 111;===----------------------------------------------------------------------------112; Stores113;===----------------------------------------------------------------------------114 115; CHECK-LABEL: sti32_a1:116; CHECK-NEXT: .functype sti32_a1 (i32, i32) -> (){{$}}117; CHECK-NEXT: i32.store 0($0):p2align=0, $1{{$}}118; CHECK-NEXT: return{{$}}119define void @sti32_a1(ptr %p, i32 %v) {120 store i32 %v, ptr %p, align 1121 ret void122}123 124; CHECK-LABEL: sti32_a2:125; CHECK-NEXT: .functype sti32_a2 (i32, i32) -> (){{$}}126; CHECK-NEXT: i32.store 0($0):p2align=1, $1{{$}}127; CHECK-NEXT: return{{$}}128define void @sti32_a2(ptr %p, i32 %v) {129 store i32 %v, ptr %p, align 2130 ret void131}132 133; 4 is the default alignment for i32 so no attribute is needed.134 135; CHECK-LABEL: sti32_a4:136; CHECK-NEXT: .functype sti32_a4 (i32, i32) -> (){{$}}137; CHECK-NEXT: i32.store 0($0), $1{{$}}138; CHECK-NEXT: return{{$}}139define void @sti32_a4(ptr %p, i32 %v) {140 store i32 %v, ptr %p, align 4141 ret void142}143 144; The default alignment in LLVM is the same as the default alignment in wasm.145 146; CHECK-LABEL: sti32:147; CHECK-NEXT: .functype sti32 (i32, i32) -> (){{$}}148; CHECK-NEXT: i32.store 0($0), $1{{$}}149; CHECK-NEXT: return{{$}}150define void @sti32(ptr %p, i32 %v) {151 store i32 %v, ptr %p152 ret void153}154 155; CHECK-LABEL: sti32_a8:156; CHECK-NEXT: .functype sti32_a8 (i32, i32) -> (){{$}}157; CHECK-NEXT: i32.store 0($0), $1{{$}}158; CHECK-NEXT: return{{$}}159define void @sti32_a8(ptr %p, i32 %v) {160 store i32 %v, ptr %p, align 8161 ret void162}163 164;===----------------------------------------------------------------------------165; Truncating stores166;===----------------------------------------------------------------------------167 168; CHECK-LABEL: sti8_a1:169; CHECK-NEXT: .functype sti8_a1 (i32, i32) -> (){{$}}170; CHECK-NEXT: i32.store8 0($0), $1{{$}}171; CHECK-NEXT: return{{$}}172define void @sti8_a1(ptr %p, i8 %v) {173 store i8 %v, ptr %p, align 1174 ret void175}176 177; CHECK-LABEL: sti8_a2:178; CHECK-NEXT: .functype sti8_a2 (i32, i32) -> (){{$}}179; CHECK-NEXT: i32.store8 0($0), $1{{$}}180; CHECK-NEXT: return{{$}}181define void @sti8_a2(ptr %p, i8 %v) {182 store i8 %v, ptr %p, align 2183 ret void184}185 186; CHECK-LABEL: sti16_a1:187; CHECK-NEXT: .functype sti16_a1 (i32, i32) -> (){{$}}188; CHECK-NEXT: i32.store16 0($0):p2align=0, $1{{$}}189; CHECK-NEXT: return{{$}}190define void @sti16_a1(ptr %p, i16 %v) {191 store i16 %v, ptr %p, align 1192 ret void193}194 195; CHECK-LABEL: sti16_a2:196; CHECK-NEXT: .functype sti16_a2 (i32, i32) -> (){{$}}197; CHECK-NEXT: i32.store16 0($0), $1{{$}}198; CHECK-NEXT: return{{$}}199define void @sti16_a2(ptr %p, i16 %v) {200 store i16 %v, ptr %p, align 2201 ret void202}203 204; CHECK-LABEL: sti16_a4:205; CHECK-NEXT: .functype sti16_a4 (i32, i32) -> (){{$}}206; CHECK-NEXT: i32.store16 0($0), $1{{$}}207; CHECK-NEXT: return{{$}}208define void @sti16_a4(ptr %p, i16 %v) {209 store i16 %v, ptr %p, align 4210 ret void211}212 213;===----------------------------------------------------------------------------214; Atomic loads215;===----------------------------------------------------------------------------216 217; Wasm atomics have the alignment field, but it must always have the type's218; natural alignment.219 220; CHECK-LABEL: ldi32_atomic_a4:221; CHECK-NEXT: .functype ldi32_atomic_a4 (i32) -> (i32){{$}}222; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}223; CHECK-NEXT: return $pop[[NUM]]{{$}}224define i32 @ldi32_atomic_a4(ptr %p) {225 %v = load atomic i32, ptr %p seq_cst, align 4226 ret i32 %v227}228 229; 8 is greater than the default alignment so it is ignored.230 231; CHECK-LABEL: ldi32_atomic_a8:232; CHECK-NEXT: .functype ldi32_atomic_a8 (i32) -> (i32){{$}}233; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}234; CHECK-NEXT: return $pop[[NUM]]{{$}}235define i32 @ldi32_atomic_a8(ptr %p) {236 %v = load atomic i32, ptr %p seq_cst, align 8237 ret i32 %v238}239 240;===----------------------------------------------------------------------------241; Atomic stores242;===----------------------------------------------------------------------------243 244; CHECK-LABEL: sti32_atomic_a4:245; CHECK-NEXT: .functype sti32_atomic_a4 (i32, i32) -> (){{$}}246; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}247; CHECK-NEXT: return{{$}}248define void @sti32_atomic_a4(ptr %p, i32 %v) {249 store atomic i32 %v, ptr %p seq_cst, align 4250 ret void251}252 253; 8 is greater than the default alignment so it is ignored.254 255; CHECK-LABEL: sti32_atomic_a8:256; CHECK-NEXT: .functype sti32_atomic_a8 (i32, i32) -> (){{$}}257; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}258; CHECK-NEXT: return{{$}}259define void @sti32_atomic_a8(ptr %p, i32 %v) {260 store atomic i32 %v, ptr %p seq_cst, align 8261 ret void262}263