brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.6 KiB · 5f484d4 Raw
371 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: ldi64_a1:12; CHECK-NEXT: .functype ldi64_a1 (i32) -> (i64){{$}}13; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}14; CHECK-NEXT: return $pop[[NUM]]{{$}}15define i64 @ldi64_a1(ptr %p) {16  %v = load i64, ptr %p, align 117  ret i64 %v18}19 20; CHECK-LABEL: ldi64_a2:21; CHECK-NEXT: .functype ldi64_a2 (i32) -> (i64){{$}}22; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}23; CHECK-NEXT: return $pop[[NUM]]{{$}}24define i64 @ldi64_a2(ptr %p) {25  %v = load i64, ptr %p, align 226  ret i64 %v27}28 29; CHECK-LABEL: ldi64_a4:30; CHECK-NEXT: .functype ldi64_a4 (i32) -> (i64){{$}}31; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=2{{$}}32; CHECK-NEXT: return $pop[[NUM]]{{$}}33define i64 @ldi64_a4(ptr %p) {34  %v = load i64, ptr %p, align 435  ret i64 %v36}37 38; 8 is the default alignment for i64 so no attribute is needed.39 40; CHECK-LABEL: ldi64_a8:41; CHECK-NEXT: .functype ldi64_a8 (i32) -> (i64){{$}}42; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}43; CHECK-NEXT: return $pop[[NUM]]{{$}}44define i64 @ldi64_a8(ptr %p) {45  %v = load i64, ptr %p, align 846  ret i64 %v47}48 49; The default alignment in LLVM is the same as the default alignment in wasm.50 51; CHECK-LABEL: ldi64:52; CHECK-NEXT: .functype ldi64 (i32) -> (i64){{$}}53; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}54; CHECK-NEXT: return $pop[[NUM]]{{$}}55define i64 @ldi64(ptr %p) {56  %v = load i64, ptr %p57  ret i64 %v58}59 60; 16 is greater than the default alignment so it is ignored.61 62; CHECK-LABEL: ldi64_a16:63; CHECK-NEXT: .functype ldi64_a16 (i32) -> (i64){{$}}64; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}65; CHECK-NEXT: return $pop[[NUM]]{{$}}66define i64 @ldi64_a16(ptr %p) {67  %v = load i64, ptr %p, align 1668  ret i64 %v69}70 71;===----------------------------------------------------------------------------72; Extending loads73;===----------------------------------------------------------------------------74 75; CHECK-LABEL: ldi8_a1:76; CHECK-NEXT: .functype ldi8_a1 (i32) -> (i64){{$}}77; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}78; CHECK-NEXT: return $pop[[NUM]]{{$}}79define i64 @ldi8_a1(ptr %p) {80  %v = load i8, ptr %p, align 181  %w = zext i8 %v to i6482  ret i64 %w83}84 85; CHECK-LABEL: ldi8_a2:86; CHECK-NEXT: .functype ldi8_a2 (i32) -> (i64){{$}}87; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}88; CHECK-NEXT: return $pop[[NUM]]{{$}}89define i64 @ldi8_a2(ptr %p) {90  %v = load i8, ptr %p, align 291  %w = zext i8 %v to i6492  ret i64 %w93}94 95; CHECK-LABEL: ldi16_a1:96; CHECK-NEXT: .functype ldi16_a1 (i32) -> (i64){{$}}97; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}98; CHECK-NEXT: return $pop[[NUM]]{{$}}99define i64 @ldi16_a1(ptr %p) {100  %v = load i16, ptr %p, align 1101  %w = zext i16 %v to i64102  ret i64 %w103}104 105; CHECK-LABEL: ldi16_a2:106; CHECK-NEXT: .functype ldi16_a2 (i32) -> (i64){{$}}107; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}108; CHECK-NEXT: return $pop[[NUM]]{{$}}109define i64 @ldi16_a2(ptr %p) {110  %v = load i16, ptr %p, align 2111  %w = zext i16 %v to i64112  ret i64 %w113}114 115; CHECK-LABEL: ldi16_a4:116; CHECK-NEXT: .functype ldi16_a4 (i32) -> (i64){{$}}117; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}118; CHECK-NEXT: return $pop[[NUM]]{{$}}119define i64 @ldi16_a4(ptr %p) {120  %v = load i16, ptr %p, align 4121  %w = zext i16 %v to i64122  ret i64 %w123}124 125; CHECK-LABEL: ldi32_a1:126; CHECK-NEXT: .functype ldi32_a1 (i32) -> (i64){{$}}127; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}128; CHECK-NEXT: return $pop[[NUM]]{{$}}129define i64 @ldi32_a1(ptr %p) {130  %v = load i32, ptr %p, align 1131  %w = zext i32 %v to i64132  ret i64 %w133}134 135; CHECK-LABEL: ldi32_a2:136; CHECK-NEXT: .functype ldi32_a2 (i32) -> (i64){{$}}137; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}138; CHECK-NEXT: return $pop[[NUM]]{{$}}139define i64 @ldi32_a2(ptr %p) {140  %v = load i32, ptr %p, align 2141  %w = zext i32 %v to i64142  ret i64 %w143}144 145; CHECK-LABEL: ldi32_a4:146; CHECK-NEXT: .functype ldi32_a4 (i32) -> (i64){{$}}147; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0){{$}}148; CHECK-NEXT: return $pop[[NUM]]{{$}}149define i64 @ldi32_a4(ptr %p) {150  %v = load i32, ptr %p, align 4151  %w = zext i32 %v to i64152  ret i64 %w153}154 155; CHECK-LABEL: ldi32_a8:156; CHECK-NEXT: .functype ldi32_a8 (i32) -> (i64){{$}}157; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0){{$}}158; CHECK-NEXT: return $pop[[NUM]]{{$}}159define i64 @ldi32_a8(ptr %p) {160  %v = load i32, ptr %p, align 8161  %w = zext i32 %v to i64162  ret i64 %w163}164 165;===----------------------------------------------------------------------------166; Stores167;===----------------------------------------------------------------------------168 169; CHECK-LABEL: sti64_a1:170; CHECK-NEXT: .functype sti64_a1 (i32, i64) -> (){{$}}171; CHECK-NEXT: i64.store 0($0):p2align=0, $1{{$}}172; CHECK-NEXT: return{{$}}173define void @sti64_a1(ptr %p, i64 %v) {174  store i64 %v, ptr %p, align 1175  ret void176}177 178; CHECK-LABEL: sti64_a2:179; CHECK-NEXT: .functype sti64_a2 (i32, i64) -> (){{$}}180; CHECK-NEXT: i64.store 0($0):p2align=1, $1{{$}}181; CHECK-NEXT: return{{$}}182define void @sti64_a2(ptr %p, i64 %v) {183  store i64 %v, ptr %p, align 2184  ret void185}186 187; CHECK-LABEL: sti64_a4:188; CHECK-NEXT: .functype sti64_a4 (i32, i64) -> (){{$}}189; CHECK-NEXT: i64.store 0($0):p2align=2, $1{{$}}190; CHECK-NEXT: return{{$}}191define void @sti64_a4(ptr %p, i64 %v) {192  store i64 %v, ptr %p, align 4193  ret void194}195 196; 8 is the default alignment for i32 so no attribute is needed.197 198; CHECK-LABEL: sti64_a8:199; CHECK-NEXT: .functype sti64_a8 (i32, i64) -> (){{$}}200; CHECK-NEXT: i64.store 0($0), $1{{$}}201; CHECK-NEXT: return{{$}}202define void @sti64_a8(ptr %p, i64 %v) {203  store i64 %v, ptr %p, align 8204  ret void205}206 207; The default alignment in LLVM is the same as the default alignment in wasm.208 209; CHECK-LABEL: sti64:210; CHECK-NEXT: .functype sti64 (i32, i64) -> (){{$}}211; CHECK-NEXT: i64.store 0($0), $1{{$}}212; CHECK-NEXT: return{{$}}213define void @sti64(ptr %p, i64 %v) {214  store i64 %v, ptr %p215  ret void216}217 218; CHECK-LABEL: sti64_a16:219; CHECK-NEXT: .functype sti64_a16 (i32, i64) -> (){{$}}220; CHECK-NEXT: i64.store 0($0), $1{{$}}221; CHECK-NEXT: return{{$}}222define void @sti64_a16(ptr %p, i64 %v) {223  store i64 %v, ptr %p, align 16224  ret void225}226 227;===----------------------------------------------------------------------------228; Truncating stores229;===----------------------------------------------------------------------------230 231; CHECK-LABEL: sti8_a1:232; CHECK-NEXT: .functype sti8_a1 (i32, i64) -> (){{$}}233; CHECK-NEXT: i64.store8 0($0), $1{{$}}234; CHECK-NEXT: return{{$}}235define void @sti8_a1(ptr %p, i64 %w) {236  %v = trunc i64 %w to i8237  store i8 %v, ptr %p, align 1238  ret void239}240 241; CHECK-LABEL: sti8_a2:242; CHECK-NEXT: .functype sti8_a2 (i32, i64) -> (){{$}}243; CHECK-NEXT: i64.store8 0($0), $1{{$}}244; CHECK-NEXT: return{{$}}245define void @sti8_a2(ptr %p, i64 %w) {246  %v = trunc i64 %w to i8247  store i8 %v, ptr %p, align 2248  ret void249}250 251; CHECK-LABEL: sti16_a1:252; CHECK-NEXT: .functype sti16_a1 (i32, i64) -> (){{$}}253; CHECK-NEXT: i64.store16 0($0):p2align=0, $1{{$}}254; CHECK-NEXT: return{{$}}255define void @sti16_a1(ptr %p, i64 %w) {256  %v = trunc i64 %w to i16257  store i16 %v, ptr %p, align 1258  ret void259}260 261; CHECK-LABEL: sti16_a2:262; CHECK-NEXT: .functype sti16_a2 (i32, i64) -> (){{$}}263; CHECK-NEXT: i64.store16 0($0), $1{{$}}264; CHECK-NEXT: return{{$}}265define void @sti16_a2(ptr %p, i64 %w) {266  %v = trunc i64 %w to i16267  store i16 %v, ptr %p, align 2268  ret void269}270 271; CHECK-LABEL: sti16_a4:272; CHECK-NEXT: .functype sti16_a4 (i32, i64) -> (){{$}}273; CHECK-NEXT: i64.store16 0($0), $1{{$}}274; CHECK-NEXT: return{{$}}275define void @sti16_a4(ptr %p, i64 %w) {276  %v = trunc i64 %w to i16277  store i16 %v, ptr %p, align 4278  ret void279}280 281; CHECK-LABEL: sti32_a1:282; CHECK-NEXT: .functype sti32_a1 (i32, i64) -> (){{$}}283; CHECK-NEXT: i64.store32 0($0):p2align=0, $1{{$}}284; CHECK-NEXT: return{{$}}285define void @sti32_a1(ptr %p, i64 %w) {286  %v = trunc i64 %w to i32287  store i32 %v, ptr %p, align 1288  ret void289}290 291; CHECK-LABEL: sti32_a2:292; CHECK-NEXT: .functype sti32_a2 (i32, i64) -> (){{$}}293; CHECK-NEXT: i64.store32 0($0):p2align=1, $1{{$}}294; CHECK-NEXT: return{{$}}295define void @sti32_a2(ptr %p, i64 %w) {296  %v = trunc i64 %w to i32297  store i32 %v, ptr %p, align 2298  ret void299}300 301; CHECK-LABEL: sti32_a4:302; CHECK-NEXT: .functype sti32_a4 (i32, i64) -> (){{$}}303; CHECK-NEXT: i64.store32 0($0), $1{{$}}304; CHECK-NEXT: return{{$}}305define void @sti32_a4(ptr %p, i64 %w) {306  %v = trunc i64 %w to i32307  store i32 %v, ptr %p, align 4308  ret void309}310 311; CHECK-LABEL: sti32_a8:312; CHECK-NEXT: .functype sti32_a8 (i32, i64) -> (){{$}}313; CHECK-NEXT: i64.store32 0($0), $1{{$}}314; CHECK-NEXT: return{{$}}315define void @sti32_a8(ptr %p, i64 %w) {316  %v = trunc i64 %w to i32317  store i32 %v, ptr %p, align 8318  ret void319}320 321;===----------------------------------------------------------------------------322; Atomic loads323;===----------------------------------------------------------------------------324 325; Wasm atomics have the alignment field, but it must always have the type's326; natural alignment.327 328; CHECK-LABEL: ldi64_atomic_a8:329; CHECK-NEXT: .functype ldi64_atomic_a8 (i32) -> (i64){{$}}330; CHECK-NEXT: i64.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}331; CHECK-NEXT: return $pop[[NUM]]{{$}}332define i64 @ldi64_atomic_a8(ptr %p) {333  %v = load atomic i64, ptr %p seq_cst, align 8334  ret i64 %v335}336 337; 16 is greater than the default alignment so it is ignored.338 339; CHECK-LABEL: ldi64_atomic_a16:340; CHECK-NEXT: .functype ldi64_atomic_a16 (i32) -> (i64){{$}}341; CHECK-NEXT: i64.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}342; CHECK-NEXT: return $pop[[NUM]]{{$}}343define i64 @ldi64_atomic_a16(ptr %p) {344  %v = load atomic i64, ptr %p seq_cst, align 16345  ret i64 %v346}347 348;===----------------------------------------------------------------------------349; Atomic stores350;===----------------------------------------------------------------------------351 352; CHECK-LABEL: sti64_atomic_a4:353; CHECK-NEXT: .functype sti64_atomic_a4 (i32, i64) -> (){{$}}354; CHECK-NEXT: i64.atomic.store 0($0), $1{{$}}355; CHECK-NEXT: return{{$}}356define void @sti64_atomic_a4(ptr %p, i64 %v) {357 store atomic i64 %v, ptr %p seq_cst, align 8358 ret void359}360 361; 16 is greater than the default alignment so it is ignored.362 363; CHECK-LABEL: sti64_atomic_a8:364; CHECK-NEXT: .functype sti64_atomic_a8 (i32, i64) -> (){{$}}365; CHECK-NEXT: i64.atomic.store 0($0), $1{{$}}366; CHECK-NEXT: return{{$}}367define void @sti64_atomic_a8(ptr %p, i64 %v) {368 store atomic i64 %v, ptr %p seq_cst, align 16369 ret void370}371