412 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 22; Test i128 atomicrmw operations.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z15 | FileCheck %s5;6; Test expansion of AtomicRMW instructions, which assume a natural alignment.7; Note that the multiple regmoves inside the CDSG loops hopefully will go away8; when the new i128 support is added.9 10; Check register exchange.11define i128 @atomicrmw_xchg(ptr %src, i128 %b) {12; CHECK-LABEL: atomicrmw_xchg:13; CHECK: # %bb.0:14; CHECK-NEXT: vl %v1, 0(%r4), 315; CHECK-NEXT: vl %v0, 0(%r3), 416; CHECK-NEXT: vlgvg %r1, %v1, 117; CHECK-NEXT: vlgvg %r0, %v1, 018; CHECK-NEXT: .LBB0_1: # %atomicrmw.start19; CHECK-NEXT: # =>This Inner Loop Header: Depth=120; CHECK-NEXT: vlgvg %r5, %v0, 121; CHECK-NEXT: vlgvg %r4, %v0, 022; CHECK-NEXT: cdsg %r4, %r0, 0(%r3)23; CHECK-NEXT: vlvgp %v0, %r4, %r524; CHECK-NEXT: jl .LBB0_125; CHECK-NEXT: # %bb.2: # %atomicrmw.end26; CHECK-NEXT: vst %v0, 0(%r2), 327; CHECK-NEXT: br %r1428 %res = atomicrmw xchg ptr %src, i128 %b seq_cst29 ret i128 %res30}31 32; Check addition of a variable.33define i128 @atomicrmw_add(ptr %src, i128 %b) {34; CHECK-LABEL: atomicrmw_add:35; CHECK: # %bb.0:36; CHECK-NEXT: vl %v0, 0(%r4), 337; CHECK-NEXT: vl %v1, 0(%r3), 438; CHECK-NEXT: .LBB1_1: # %atomicrmw.start39; CHECK-NEXT: # =>This Inner Loop Header: Depth=140; CHECK-NEXT: vaq %v2, %v1, %v041; CHECK-NEXT: vlgvg %r1, %v2, 142; CHECK-NEXT: vlgvg %r0, %v2, 043; CHECK-NEXT: vlgvg %r5, %v1, 144; CHECK-NEXT: vlgvg %r4, %v1, 045; CHECK-NEXT: cdsg %r4, %r0, 0(%r3)46; CHECK-NEXT: vlvgp %v1, %r4, %r547; CHECK-NEXT: jl .LBB1_148; CHECK-NEXT: # %bb.2: # %atomicrmw.end49; CHECK-NEXT: vst %v1, 0(%r2), 350; CHECK-NEXT: br %r1451 %res = atomicrmw add ptr %src, i128 %b seq_cst52 ret i128 %res53}54 55; Check subtraction of a variable.56define i128 @atomicrmw_sub(ptr %src, i128 %b) {57; CHECK-LABEL: atomicrmw_sub:58; CHECK: # %bb.0:59; CHECK-NEXT: vl %v0, 0(%r4), 360; CHECK-NEXT: vl %v1, 0(%r3), 461; CHECK-NEXT: .LBB2_1: # %atomicrmw.start62; CHECK-NEXT: # =>This Inner Loop Header: Depth=163; CHECK-NEXT: vsq %v2, %v1, %v064; CHECK-NEXT: vlgvg %r1, %v2, 165; CHECK-NEXT: vlgvg %r0, %v2, 066; CHECK-NEXT: vlgvg %r5, %v1, 167; CHECK-NEXT: vlgvg %r4, %v1, 068; CHECK-NEXT: cdsg %r4, %r0, 0(%r3)69; CHECK-NEXT: vlvgp %v1, %r4, %r570; CHECK-NEXT: jl .LBB2_171; CHECK-NEXT: # %bb.2: # %atomicrmw.end72; CHECK-NEXT: vst %v1, 0(%r2), 373; CHECK-NEXT: br %r1474 %res = atomicrmw sub ptr %src, i128 %b seq_cst75 ret i128 %res76}77 78; Check AND of a variable.79define i128 @atomicrmw_and(ptr %src, i128 %b) {80; CHECK-LABEL: atomicrmw_and:81; CHECK: # %bb.0:82; CHECK-NEXT: vl %v0, 0(%r4), 383; CHECK-NEXT: vl %v1, 0(%r3), 484; CHECK-NEXT: .LBB3_1: # %atomicrmw.start85; CHECK-NEXT: # =>This Inner Loop Header: Depth=186; CHECK-NEXT: vn %v2, %v1, %v087; CHECK-NEXT: vlgvg %r1, %v2, 188; CHECK-NEXT: vlgvg %r0, %v2, 089; CHECK-NEXT: vlgvg %r5, %v1, 190; CHECK-NEXT: vlgvg %r4, %v1, 091; CHECK-NEXT: cdsg %r4, %r0, 0(%r3)92; CHECK-NEXT: vlvgp %v1, %r4, %r593; CHECK-NEXT: jl .LBB3_194; CHECK-NEXT: # %bb.2: # %atomicrmw.end95; CHECK-NEXT: vst %v1, 0(%r2), 396; CHECK-NEXT: br %r1497 %res = atomicrmw and ptr %src, i128 %b seq_cst98 ret i128 %res99}100 101; Check NAND of a variable.102define i128 @atomicrmw_nand(ptr %src, i128 %b) {103; CHECK-LABEL: atomicrmw_nand:104; CHECK: # %bb.0:105; CHECK-NEXT: vl %v0, 0(%r4), 3106; CHECK-NEXT: vl %v1, 0(%r3), 4107; CHECK-NEXT: .LBB4_1: # %atomicrmw.start108; CHECK-NEXT: # =>This Inner Loop Header: Depth=1109; CHECK-NEXT: vlgvg %r1, %v1, 1110; CHECK-NEXT: vlgvg %r0, %v1, 0111; CHECK-NEXT: vnn %v1, %v1, %v0112; CHECK-NEXT: vlgvg %r5, %v1, 1113; CHECK-NEXT: vlgvg %r4, %v1, 0114; CHECK-NEXT: cdsg %r0, %r4, 0(%r3)115; CHECK-NEXT: vlvgp %v1, %r0, %r1116; CHECK-NEXT: jl .LBB4_1117; CHECK-NEXT: # %bb.2: # %atomicrmw.end118; CHECK-NEXT: vst %v1, 0(%r2), 3119; CHECK-NEXT: br %r14120 %res = atomicrmw nand ptr %src, i128 %b seq_cst121 ret i128 %res122}123 124; Check OR of a variable.125define i128 @atomicrmw_or(ptr %src, i128 %b) {126; CHECK-LABEL: atomicrmw_or:127; CHECK: # %bb.0:128; CHECK-NEXT: vl %v0, 0(%r4), 3129; CHECK-NEXT: vl %v1, 0(%r3), 4130; CHECK-NEXT: .LBB5_1: # %atomicrmw.start131; CHECK-NEXT: # =>This Inner Loop Header: Depth=1132; CHECK-NEXT: vo %v2, %v1, %v0133; CHECK-NEXT: vlgvg %r1, %v2, 1134; CHECK-NEXT: vlgvg %r0, %v2, 0135; CHECK-NEXT: vlgvg %r5, %v1, 1136; CHECK-NEXT: vlgvg %r4, %v1, 0137; CHECK-NEXT: cdsg %r4, %r0, 0(%r3)138; CHECK-NEXT: vlvgp %v1, %r4, %r5139; CHECK-NEXT: jl .LBB5_1140; CHECK-NEXT: # %bb.2: # %atomicrmw.end141; CHECK-NEXT: vst %v1, 0(%r2), 3142; CHECK-NEXT: br %r14143 %res = atomicrmw or ptr %src, i128 %b seq_cst144 ret i128 %res145}146 147; Check XOR of a variable.148define i128 @atomicrmw_xor(ptr %src, i128 %b) {149; CHECK-LABEL: atomicrmw_xor:150; CHECK: # %bb.0:151; CHECK-NEXT: vl %v0, 0(%r4), 3152; CHECK-NEXT: vl %v1, 0(%r3), 4153; CHECK-NEXT: .LBB6_1: # %atomicrmw.start154; CHECK-NEXT: # =>This Inner Loop Header: Depth=1155; CHECK-NEXT: vx %v2, %v1, %v0156; CHECK-NEXT: vlgvg %r1, %v2, 1157; CHECK-NEXT: vlgvg %r0, %v2, 0158; CHECK-NEXT: vlgvg %r5, %v1, 1159; CHECK-NEXT: vlgvg %r4, %v1, 0160; CHECK-NEXT: cdsg %r4, %r0, 0(%r3)161; CHECK-NEXT: vlvgp %v1, %r4, %r5162; CHECK-NEXT: jl .LBB6_1163; CHECK-NEXT: # %bb.2: # %atomicrmw.end164; CHECK-NEXT: vst %v1, 0(%r2), 3165; CHECK-NEXT: br %r14166 %res = atomicrmw xor ptr %src, i128 %b seq_cst167 ret i128 %res168}169 170; Check signed minimum.171define i128 @atomicrmw_min(ptr %src, i128 %b) {172; CHECK-LABEL: atomicrmw_min:173; CHECK: # %bb.0:174; CHECK-NEXT: vl %v0, 0(%r4), 3175; CHECK-NEXT: vl %v1, 0(%r3), 4176; CHECK-NEXT: j .LBB7_2177; CHECK-NEXT: .LBB7_1: # %atomicrmw.start178; CHECK-NEXT: # in Loop: Header=BB7_2 Depth=1179; CHECK-NEXT: vlgvg %r1, %v1, 1180; CHECK-NEXT: vlgvg %r0, %v1, 0181; CHECK-NEXT: vlgvg %r5, %v2, 1182; CHECK-NEXT: vlgvg %r4, %v2, 0183; CHECK-NEXT: cdsg %r0, %r4, 0(%r3)184; CHECK-NEXT: vlvgp %v1, %r0, %r1185; CHECK-NEXT: je .LBB7_6186; CHECK-NEXT: .LBB7_2: # %atomicrmw.start187; CHECK-NEXT: # =>This Inner Loop Header: Depth=1188; CHECK-NEXT: vecg %v0, %v1189; CHECK-NEXT: jlh .LBB7_4190; CHECK-NEXT: # %bb.3: # %atomicrmw.start191; CHECK-NEXT: # in Loop: Header=BB7_2 Depth=1192; CHECK-NEXT: vchlgs %v2, %v1, %v0193; CHECK-NEXT: .LBB7_4: # %atomicrmw.start194; CHECK-NEXT: # in Loop: Header=BB7_2 Depth=1195; CHECK-NEXT: vlr %v2, %v1196; CHECK-NEXT: jnl .LBB7_1197; CHECK-NEXT: # %bb.5: # %atomicrmw.start198; CHECK-NEXT: # in Loop: Header=BB7_2 Depth=1199; CHECK-NEXT: vlr %v2, %v0200; CHECK-NEXT: j .LBB7_1201; CHECK-NEXT: .LBB7_6: # %atomicrmw.end202; CHECK-NEXT: vst %v1, 0(%r2), 3203; CHECK-NEXT: br %r14204 %res = atomicrmw min ptr %src, i128 %b seq_cst205 ret i128 %res206}207 208; Check signed maximum.209define i128 @atomicrmw_max(ptr %src, i128 %b) {210; CHECK-LABEL: atomicrmw_max:211; CHECK: # %bb.0:212; CHECK-NEXT: vl %v0, 0(%r4), 3213; CHECK-NEXT: vl %v1, 0(%r3), 4214; CHECK-NEXT: j .LBB8_2215; CHECK-NEXT: .LBB8_1: # %atomicrmw.start216; CHECK-NEXT: # in Loop: Header=BB8_2 Depth=1217; CHECK-NEXT: vlgvg %r1, %v1, 1218; CHECK-NEXT: vlgvg %r0, %v1, 0219; CHECK-NEXT: vlgvg %r5, %v2, 1220; CHECK-NEXT: vlgvg %r4, %v2, 0221; CHECK-NEXT: cdsg %r0, %r4, 0(%r3)222; CHECK-NEXT: vlvgp %v1, %r0, %r1223; CHECK-NEXT: je .LBB8_6224; CHECK-NEXT: .LBB8_2: # %atomicrmw.start225; CHECK-NEXT: # =>This Inner Loop Header: Depth=1226; CHECK-NEXT: vecg %v0, %v1227; CHECK-NEXT: jlh .LBB8_4228; CHECK-NEXT: # %bb.3: # %atomicrmw.start229; CHECK-NEXT: # in Loop: Header=BB8_2 Depth=1230; CHECK-NEXT: vchlgs %v2, %v1, %v0231; CHECK-NEXT: .LBB8_4: # %atomicrmw.start232; CHECK-NEXT: # in Loop: Header=BB8_2 Depth=1233; CHECK-NEXT: vlr %v2, %v1234; CHECK-NEXT: jl .LBB8_1235; CHECK-NEXT: # %bb.5: # %atomicrmw.start236; CHECK-NEXT: # in Loop: Header=BB8_2 Depth=1237; CHECK-NEXT: vlr %v2, %v0238; CHECK-NEXT: j .LBB8_1239; CHECK-NEXT: .LBB8_6: # %atomicrmw.end240; CHECK-NEXT: vst %v1, 0(%r2), 3241; CHECK-NEXT: br %r14242 %res = atomicrmw max ptr %src, i128 %b seq_cst243 ret i128 %res244}245 246; Check unsigned minimum.247define i128 @atomicrmw_umin(ptr %src, i128 %b) {248; CHECK-LABEL: atomicrmw_umin:249; CHECK: # %bb.0:250; CHECK-NEXT: vl %v0, 0(%r4), 3251; CHECK-NEXT: vl %v1, 0(%r3), 4252; CHECK-NEXT: j .LBB9_2253; CHECK-NEXT: .LBB9_1: # %atomicrmw.start254; CHECK-NEXT: # in Loop: Header=BB9_2 Depth=1255; CHECK-NEXT: vlgvg %r1, %v1, 1256; CHECK-NEXT: vlgvg %r0, %v1, 0257; CHECK-NEXT: vlgvg %r5, %v2, 1258; CHECK-NEXT: vlgvg %r4, %v2, 0259; CHECK-NEXT: cdsg %r0, %r4, 0(%r3)260; CHECK-NEXT: vlvgp %v1, %r0, %r1261; CHECK-NEXT: je .LBB9_6262; CHECK-NEXT: .LBB9_2: # %atomicrmw.start263; CHECK-NEXT: # =>This Inner Loop Header: Depth=1264; CHECK-NEXT: veclg %v0, %v1265; CHECK-NEXT: jlh .LBB9_4266; CHECK-NEXT: # %bb.3: # %atomicrmw.start267; CHECK-NEXT: # in Loop: Header=BB9_2 Depth=1268; CHECK-NEXT: vchlgs %v2, %v1, %v0269; CHECK-NEXT: .LBB9_4: # %atomicrmw.start270; CHECK-NEXT: # in Loop: Header=BB9_2 Depth=1271; CHECK-NEXT: vlr %v2, %v1272; CHECK-NEXT: jnl .LBB9_1273; CHECK-NEXT: # %bb.5: # %atomicrmw.start274; CHECK-NEXT: # in Loop: Header=BB9_2 Depth=1275; CHECK-NEXT: vlr %v2, %v0276; CHECK-NEXT: j .LBB9_1277; CHECK-NEXT: .LBB9_6: # %atomicrmw.end278; CHECK-NEXT: vst %v1, 0(%r2), 3279; CHECK-NEXT: br %r14280 %res = atomicrmw umin ptr %src, i128 %b seq_cst281 ret i128 %res282}283 284; Check unsigned maximum.285define i128 @atomicrmw_umax(ptr %src, i128 %b) {286; CHECK-LABEL: atomicrmw_umax:287; CHECK: # %bb.0:288; CHECK-NEXT: vl %v0, 0(%r4), 3289; CHECK-NEXT: vl %v1, 0(%r3), 4290; CHECK-NEXT: j .LBB10_2291; CHECK-NEXT: .LBB10_1: # %atomicrmw.start292; CHECK-NEXT: # in Loop: Header=BB10_2 Depth=1293; CHECK-NEXT: vlgvg %r1, %v1, 1294; CHECK-NEXT: vlgvg %r0, %v1, 0295; CHECK-NEXT: vlgvg %r5, %v2, 1296; CHECK-NEXT: vlgvg %r4, %v2, 0297; CHECK-NEXT: cdsg %r0, %r4, 0(%r3)298; CHECK-NEXT: vlvgp %v1, %r0, %r1299; CHECK-NEXT: je .LBB10_6300; CHECK-NEXT: .LBB10_2: # %atomicrmw.start301; CHECK-NEXT: # =>This Inner Loop Header: Depth=1302; CHECK-NEXT: veclg %v0, %v1303; CHECK-NEXT: jlh .LBB10_4304; CHECK-NEXT: # %bb.3: # %atomicrmw.start305; CHECK-NEXT: # in Loop: Header=BB10_2 Depth=1306; CHECK-NEXT: vchlgs %v2, %v1, %v0307; CHECK-NEXT: .LBB10_4: # %atomicrmw.start308; CHECK-NEXT: # in Loop: Header=BB10_2 Depth=1309; CHECK-NEXT: vlr %v2, %v1310; CHECK-NEXT: jl .LBB10_1311; CHECK-NEXT: # %bb.5: # %atomicrmw.start312; CHECK-NEXT: # in Loop: Header=BB10_2 Depth=1313; CHECK-NEXT: vlr %v2, %v0314; CHECK-NEXT: j .LBB10_1315; CHECK-NEXT: .LBB10_6: # %atomicrmw.end316; CHECK-NEXT: vst %v1, 0(%r2), 3317; CHECK-NEXT: br %r14318 %res = atomicrmw umax ptr %src, i128 %b seq_cst319 ret i128 %res320}321 322; Check increment with wraparound.323define i128 @atomicrmw_uinc_wrap(ptr %src, i128 %b) {324; CHECK-LABEL: atomicrmw_uinc_wrap:325; CHECK: # %bb.0:326; CHECK-NEXT: larl %r1, .LCPI11_0327; CHECK-NEXT: vl %v0, 0(%r4), 3328; CHECK-NEXT: vl %v2, 0(%r3), 4329; CHECK-NEXT: vl %v1, 0(%r1), 3330; CHECK-NEXT: j .LBB11_2331; CHECK-NEXT: .LBB11_1: # %atomicrmw.start332; CHECK-NEXT: # in Loop: Header=BB11_2 Depth=1333; CHECK-NEXT: vlgvg %r1, %v2, 1334; CHECK-NEXT: vlgvg %r0, %v2, 0335; CHECK-NEXT: vlgvg %r5, %v3, 1336; CHECK-NEXT: vlgvg %r4, %v3, 0337; CHECK-NEXT: cdsg %r0, %r4, 0(%r3)338; CHECK-NEXT: vlvgp %v2, %r0, %r1339; CHECK-NEXT: je .LBB11_6340; CHECK-NEXT: .LBB11_2: # %atomicrmw.start341; CHECK-NEXT: # =>This Inner Loop Header: Depth=1342; CHECK-NEXT: veclg %v2, %v0343; CHECK-NEXT: jlh .LBB11_4344; CHECK-NEXT: # %bb.3: # %atomicrmw.start345; CHECK-NEXT: # in Loop: Header=BB11_2 Depth=1346; CHECK-NEXT: vchlgs %v3, %v0, %v2347; CHECK-NEXT: .LBB11_4: # %atomicrmw.start348; CHECK-NEXT: # in Loop: Header=BB11_2 Depth=1349; CHECK-NEXT: vgbm %v3, 0350; CHECK-NEXT: jnl .LBB11_1351; CHECK-NEXT: # %bb.5: # %atomicrmw.start352; CHECK-NEXT: # in Loop: Header=BB11_2 Depth=1353; CHECK-NEXT: vaq %v3, %v2, %v1354; CHECK-NEXT: j .LBB11_1355; CHECK-NEXT: .LBB11_6: # %atomicrmw.end356; CHECK-NEXT: vst %v2, 0(%r2), 3357; CHECK-NEXT: br %r14358 %res = atomicrmw uinc_wrap ptr %src, i128 %b seq_cst359 ret i128 %res360}361 362; Check decrement with wraparound.363define i128 @atomicrmw_udec_wrap(ptr %src, i128 %b) {364; CHECK-LABEL: atomicrmw_udec_wrap:365; CHECK: # %bb.0:366; CHECK-NEXT: larl %r1, .LCPI12_0367; CHECK-NEXT: vl %v0, 0(%r4), 3368; CHECK-NEXT: vl %v3, 0(%r3), 4369; CHECK-NEXT: vl %v1, 0(%r1), 3370; CHECK-NEXT: vgbm %v2, 65535371; CHECK-NEXT: j .LBB12_2372; CHECK-NEXT: .LBB12_1: # %atomicrmw.start373; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1374; CHECK-NEXT: vlgvg %r1, %v3, 1375; CHECK-NEXT: vlgvg %r0, %v3, 0376; CHECK-NEXT: vlgvg %r5, %v5, 1377; CHECK-NEXT: vlgvg %r4, %v5, 0378; CHECK-NEXT: cdsg %r0, %r4, 0(%r3)379; CHECK-NEXT: vlvgp %v3, %r0, %r1380; CHECK-NEXT: je .LBB12_8381; CHECK-NEXT: .LBB12_2: # %atomicrmw.start382; CHECK-NEXT: # =>This Inner Loop Header: Depth=1383; CHECK-NEXT: vscbiq %v4, %v3, %v1384; CHECK-NEXT: vlgvf %r0, %v4, 3385; CHECK-NEXT: xilf %r0, 1386; CHECK-NEXT: veclg %v0, %v3387; CHECK-NEXT: jlh .LBB12_4388; CHECK-NEXT: # %bb.3: # %atomicrmw.start389; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1390; CHECK-NEXT: vchlgs %v4, %v3, %v0391; CHECK-NEXT: .LBB12_4: # %atomicrmw.start392; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1393; CHECK-NEXT: vlr %v4, %v0394; CHECK-NEXT: jl .LBB12_6395; CHECK-NEXT: # %bb.5: # %atomicrmw.start396; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1397; CHECK-NEXT: vaq %v4, %v3, %v2398; CHECK-NEXT: .LBB12_6: # %atomicrmw.start399; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1400; CHECK-NEXT: vlr %v5, %v0401; CHECK-NEXT: cijlh %r0, 0, .LBB12_1402; CHECK-NEXT: # %bb.7: # %atomicrmw.start403; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1404; CHECK-NEXT: vlr %v5, %v4405; CHECK-NEXT: j .LBB12_1406; CHECK-NEXT: .LBB12_8: # %atomicrmw.end407; CHECK-NEXT: vst %v3, 0(%r2), 3408; CHECK-NEXT: br %r14409 %res = atomicrmw udec_wrap ptr %src, i128 %b seq_cst410 ret i128 %res411}412