365 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52;; Test that carryout from 64-bit add/sub (synthesized from two 32-bit adds/subs) is utilized3;; (i.e. no additional compare is generated).4 5; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx900 < %s | FileCheck %s6 7%struct.uint96 = type { i64, i32 }8%struct.uint64pair = type { i64, i64 }9 10declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64)11declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64)12 13declare {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64>, <2 x i64>)14declare {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64>, <2 x i64>)15 16define %struct.uint96 @v_add64_32(i64 %val64A, i64 %val64B, i32 %val32) {17; CHECK-LABEL: v_add64_32:18; CHECK: ; %bb.0:19; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)20; CHECK-NEXT: v_add_co_u32_e32 v0, vcc, v0, v221; CHECK-NEXT: v_addc_co_u32_e32 v1, vcc, v1, v3, vcc22; CHECK-NEXT: v_addc_co_u32_e32 v2, vcc, 0, v4, vcc23; CHECK-NEXT: s_setpc_b64 s[30:31]24 %sum64 = add i64 %val64A, %val64B25 %obit = icmp ult i64 %sum64, %val64A26 %obit32 = zext i1 %obit to i3227 %sum32 = add i32 %val32, %obit3228 %.fca.0.insert = insertvalue %struct.uint96 poison, i64 %sum64, 029 %.fca.1.insert = insertvalue %struct.uint96 %.fca.0.insert, i32 %sum32, 130 ret %struct.uint96 %.fca.1.insert31}32 33define <2 x i64> @v_uadd_v2i64(<2 x i64> %val0, <2 x i64> %val1, ptr %ptrval) {34; CHECK-LABEL: v_uadd_v2i64:35; CHECK: ; %bb.0:36; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)37; CHECK-NEXT: v_add_co_u32_e32 v6, vcc, v2, v638; CHECK-NEXT: v_add_co_u32_e64 v4, s[4:5], v0, v439; CHECK-NEXT: v_addc_co_u32_e32 v7, vcc, v3, v7, vcc40; CHECK-NEXT: v_addc_co_u32_e64 v5, s[4:5], v1, v5, s[4:5]41; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, s[4:5]42; CHECK-NEXT: v_cndmask_b32_e64 v2, 0, -1, vcc43; CHECK-NEXT: v_mov_b32_e32 v1, v044; CHECK-NEXT: v_mov_b32_e32 v3, v245; CHECK-NEXT: flat_store_dwordx4 v[8:9], v[4:7]46; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)47; CHECK-NEXT: s_setpc_b64 s[30:31]48 %pair = call {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64> %val0, <2 x i64> %val1)49 %val = extractvalue {<2 x i64>, <2 x i1>} %pair, 050 %obit = extractvalue {<2 x i64>, <2 x i1>} %pair, 151 %res = sext <2 x i1> %obit to <2 x i64>52 store <2 x i64> %val, ptr %ptrval53 ret <2 x i64> %res54}55 56define <2 x i64> @v_usub_v2i64(<2 x i64> %val0, <2 x i64> %val1, ptr %ptrval) {57; CHECK-LABEL: v_usub_v2i64:58; CHECK: ; %bb.0:59; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)60; CHECK-NEXT: v_sub_co_u32_e32 v6, vcc, v2, v661; CHECK-NEXT: v_sub_co_u32_e64 v4, s[4:5], v0, v462; CHECK-NEXT: v_subb_co_u32_e32 v7, vcc, v3, v7, vcc63; CHECK-NEXT: v_subb_co_u32_e64 v5, s[4:5], v1, v5, s[4:5]64; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, s[4:5]65; CHECK-NEXT: v_cndmask_b32_e64 v2, 0, -1, vcc66; CHECK-NEXT: v_mov_b32_e32 v1, v067; CHECK-NEXT: v_mov_b32_e32 v3, v268; CHECK-NEXT: flat_store_dwordx4 v[8:9], v[4:7]69; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)70; CHECK-NEXT: s_setpc_b64 s[30:31]71 %pair = call {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64> %val0, <2 x i64> %val1)72 %val = extractvalue {<2 x i64>, <2 x i1>} %pair, 073 %obit = extractvalue {<2 x i64>, <2 x i1>} %pair, 174 %res = sext <2 x i1> %obit to <2 x i64>75 store <2 x i64> %val, ptr %ptrval76 ret <2 x i64> %res77}78 79define i64 @v_uadd_i64(i64 %val0, i64 %val1, ptr %ptrval) {80; CHECK-LABEL: v_uadd_i64:81; CHECK: ; %bb.0:82; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)83; CHECK-NEXT: v_add_co_u32_e32 v0, vcc, v0, v284; CHECK-NEXT: v_addc_co_u32_e32 v1, vcc, v1, v3, vcc85; CHECK-NEXT: flat_store_dwordx2 v[4:5], v[0:1]86; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, vcc87; CHECK-NEXT: v_mov_b32_e32 v1, v088; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)89; CHECK-NEXT: s_setpc_b64 s[30:31]90 %pair = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %val0, i64 %val1)91 %val = extractvalue {i64, i1} %pair, 092 %obit = extractvalue {i64, i1} %pair, 193 %res = sext i1 %obit to i6494 store i64 %val, ptr %ptrval95 ret i64 %res96}97 98define i64 @v_uadd_p1(i64 %val0, i64 %val1, ptr %ptrval) {99; CHECK-LABEL: v_uadd_p1:100; CHECK: ; %bb.0:101; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)102; CHECK-NEXT: v_add_co_u32_e32 v0, vcc, 1, v0103; CHECK-NEXT: v_addc_co_u32_e32 v1, vcc, 0, v1, vcc104; CHECK-NEXT: flat_store_dwordx2 v[4:5], v[0:1]105; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, vcc106; CHECK-NEXT: v_mov_b32_e32 v1, v0107; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)108; CHECK-NEXT: s_setpc_b64 s[30:31]109 %pair = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %val0, i64 1)110 %val = extractvalue {i64, i1} %pair, 0111 %obit = extractvalue {i64, i1} %pair, 1112 %res = sext i1 %obit to i64113 store i64 %val, ptr %ptrval114 ret i64 %res115}116 117define i64 @v_uadd_n1(i64 %val0, i64 %val1, ptr %ptrval) {118; CHECK-LABEL: v_uadd_n1:119; CHECK: ; %bb.0:120; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)121; CHECK-NEXT: v_add_co_u32_e32 v2, vcc, -1, v0122; CHECK-NEXT: v_addc_co_u32_e32 v3, vcc, -1, v1, vcc123; CHECK-NEXT: v_cmp_ne_u64_e32 vcc, 0, v[0:1]124; CHECK-NEXT: flat_store_dwordx2 v[4:5], v[2:3]125; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, vcc126; CHECK-NEXT: v_mov_b32_e32 v1, v0127; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)128; CHECK-NEXT: s_setpc_b64 s[30:31]129 %pair = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %val0, i64 -1)130 %val = extractvalue {i64, i1} %pair, 0131 %obit = extractvalue {i64, i1} %pair, 1132 %res = sext i1 %obit to i64133 store i64 %val, ptr %ptrval134 ret i64 %res135}136 137define i64 @v_usub_p1(i64 %val0, i64 %val1, ptr %ptrval) {138; CHECK-LABEL: v_usub_p1:139; CHECK: ; %bb.0:140; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)141; CHECK-NEXT: v_subrev_co_u32_e32 v0, vcc, 1, v0142; CHECK-NEXT: v_subbrev_co_u32_e32 v1, vcc, 0, v1, vcc143; CHECK-NEXT: flat_store_dwordx2 v[4:5], v[0:1]144; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, vcc145; CHECK-NEXT: v_mov_b32_e32 v1, v0146; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)147; CHECK-NEXT: s_setpc_b64 s[30:31]148 %pair = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %val0, i64 1)149 %val = extractvalue {i64, i1} %pair, 0150 %obit = extractvalue {i64, i1} %pair, 1151 %res = sext i1 %obit to i64152 store i64 %val, ptr %ptrval153 ret i64 %res154}155 156define i64 @v_usub_n1(i64 %val0, i64 %val1, ptr %ptrval) {157; CHECK-LABEL: v_usub_n1:158; CHECK: ; %bb.0:159; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)160; CHECK-NEXT: v_subrev_co_u32_e32 v0, vcc, -1, v0161; CHECK-NEXT: v_subbrev_co_u32_e32 v1, vcc, -1, v1, vcc162; CHECK-NEXT: flat_store_dwordx2 v[4:5], v[0:1]163; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, vcc164; CHECK-NEXT: v_mov_b32_e32 v1, v0165; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)166; CHECK-NEXT: s_setpc_b64 s[30:31]167 %pair = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %val0, i64 -1)168 %val = extractvalue {i64, i1} %pair, 0169 %obit = extractvalue {i64, i1} %pair, 1170 %res = sext i1 %obit to i64171 store i64 %val, ptr %ptrval172 ret i64 %res173}174 175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;176; test SGPR177;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;178 179define amdgpu_ps %struct.uint96 @s_add64_32(i64 inreg %val64A, i64 inreg %val64B, i32 inreg %val32) {180; CHECK-LABEL: s_add64_32:181; CHECK: ; %bb.0:182; CHECK-NEXT: s_add_u32 s0, s0, s2183; CHECK-NEXT: s_addc_u32 s1, s1, s3184; CHECK-NEXT: s_addc_u32 s2, s4, 0185; CHECK-NEXT: ; return to shader part epilog186 %sum64 = add i64 %val64A, %val64B187 %obit = icmp ult i64 %sum64, %val64A188 %obit32 = zext i1 %obit to i32189 %sum32 = add i32 %val32, %obit32190 %.fca.0.insert = insertvalue %struct.uint96 poison, i64 %sum64, 0191 %.fca.1.insert = insertvalue %struct.uint96 %.fca.0.insert, i32 %sum32, 1192 ret %struct.uint96 %.fca.1.insert193}194 195define amdgpu_ps <2 x i64> @s_uadd_v2i64(<2 x i64> inreg %val0, <2 x i64> inreg %val1, ptr %ptrval) {196; CHECK-LABEL: s_uadd_v2i64:197; CHECK: ; %bb.0:198; CHECK-NEXT: s_add_u32 s6, s2, s6199; CHECK-NEXT: s_addc_u32 s7, s3, s7200; CHECK-NEXT: s_cselect_b64 s[2:3], -1, 0201; CHECK-NEXT: s_add_u32 s0, s0, s4202; CHECK-NEXT: s_addc_u32 s1, s1, s5203; CHECK-NEXT: v_mov_b32_e32 v2, s0204; CHECK-NEXT: v_mov_b32_e32 v3, s1205; CHECK-NEXT: s_cselect_b64 s[0:1], -1, 0206; CHECK-NEXT: v_cndmask_b32_e64 v6, 0, -1, s[2:3]207; CHECK-NEXT: v_cndmask_b32_e64 v7, 0, -1, s[0:1]208; CHECK-NEXT: v_readfirstlane_b32 s0, v7209; CHECK-NEXT: v_readfirstlane_b32 s2, v6210; CHECK-NEXT: v_mov_b32_e32 v4, s6211; CHECK-NEXT: v_mov_b32_e32 v5, s7212; CHECK-NEXT: s_mov_b32 s1, s0213; CHECK-NEXT: s_mov_b32 s3, s2214; CHECK-NEXT: flat_store_dwordx4 v[0:1], v[2:5]215; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)216; CHECK-NEXT: ; return to shader part epilog217 %pair = call {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64> %val0, <2 x i64> %val1)218 %val = extractvalue {<2 x i64>, <2 x i1>} %pair, 0219 %obit = extractvalue {<2 x i64>, <2 x i1>} %pair, 1220 %res = sext <2 x i1> %obit to <2 x i64>221 store <2 x i64> %val, ptr %ptrval222 ret <2 x i64> %res223}224 225define amdgpu_ps <2 x i64> @s_usub_v2i64(<2 x i64> inreg %val0, <2 x i64> inreg %val1, ptr %ptrval) {226; CHECK-LABEL: s_usub_v2i64:227; CHECK: ; %bb.0:228; CHECK-NEXT: s_sub_u32 s6, s2, s6229; CHECK-NEXT: s_subb_u32 s7, s3, s7230; CHECK-NEXT: s_cselect_b64 s[2:3], -1, 0231; CHECK-NEXT: s_sub_u32 s0, s0, s4232; CHECK-NEXT: s_subb_u32 s1, s1, s5233; CHECK-NEXT: v_mov_b32_e32 v2, s0234; CHECK-NEXT: v_mov_b32_e32 v3, s1235; CHECK-NEXT: s_cselect_b64 s[0:1], -1, 0236; CHECK-NEXT: v_cndmask_b32_e64 v6, 0, -1, s[2:3]237; CHECK-NEXT: v_cndmask_b32_e64 v7, 0, -1, s[0:1]238; CHECK-NEXT: v_readfirstlane_b32 s0, v7239; CHECK-NEXT: v_readfirstlane_b32 s2, v6240; CHECK-NEXT: v_mov_b32_e32 v4, s6241; CHECK-NEXT: v_mov_b32_e32 v5, s7242; CHECK-NEXT: s_mov_b32 s1, s0243; CHECK-NEXT: s_mov_b32 s3, s2244; CHECK-NEXT: flat_store_dwordx4 v[0:1], v[2:5]245; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)246; CHECK-NEXT: ; return to shader part epilog247 %pair = call {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64> %val0, <2 x i64> %val1)248 %val = extractvalue {<2 x i64>, <2 x i1>} %pair, 0249 %obit = extractvalue {<2 x i64>, <2 x i1>} %pair, 1250 %res = sext <2 x i1> %obit to <2 x i64>251 store <2 x i64> %val, ptr %ptrval252 ret <2 x i64> %res253}254 255define amdgpu_ps i64 @s_uadd_i64(i64 inreg %val0, i64 inreg %val1, ptr %ptrval) {256; CHECK-LABEL: s_uadd_i64:257; CHECK: ; %bb.0:258; CHECK-NEXT: s_add_u32 s0, s0, s2259; CHECK-NEXT: s_addc_u32 s1, s1, s3260; CHECK-NEXT: v_mov_b32_e32 v2, s0261; CHECK-NEXT: v_mov_b32_e32 v3, s1262; CHECK-NEXT: s_cselect_b64 s[0:1], -1, 0263; CHECK-NEXT: flat_store_dwordx2 v[0:1], v[2:3]264; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, s[0:1]265; CHECK-NEXT: v_readfirstlane_b32 s0, v0266; CHECK-NEXT: s_mov_b32 s1, s0267; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)268; CHECK-NEXT: ; return to shader part epilog269 %pair = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %val0, i64 %val1)270 %val = extractvalue {i64, i1} %pair, 0271 %obit = extractvalue {i64, i1} %pair, 1272 %res = sext i1 %obit to i64273 store i64 %val, ptr %ptrval274 ret i64 %res275}276 277define amdgpu_ps i64 @s_uadd_p1(i64 inreg %val0, i64 inreg %val1, ptr %ptrval) {278; CHECK-LABEL: s_uadd_p1:279; CHECK: ; %bb.0:280; CHECK-NEXT: s_add_u32 s0, s0, 1281; CHECK-NEXT: s_addc_u32 s1, s1, 0282; CHECK-NEXT: v_mov_b32_e32 v2, s0283; CHECK-NEXT: v_mov_b32_e32 v3, s1284; CHECK-NEXT: s_cselect_b64 s[0:1], -1, 0285; CHECK-NEXT: flat_store_dwordx2 v[0:1], v[2:3]286; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, s[0:1]287; CHECK-NEXT: v_readfirstlane_b32 s0, v0288; CHECK-NEXT: s_mov_b32 s1, s0289; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)290; CHECK-NEXT: ; return to shader part epilog291 %pair = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %val0, i64 1)292 %val = extractvalue {i64, i1} %pair, 0293 %obit = extractvalue {i64, i1} %pair, 1294 %res = sext i1 %obit to i64295 store i64 %val, ptr %ptrval296 ret i64 %res297}298 299define amdgpu_ps i64 @s_uadd_n1(i64 inreg %val0, i64 inreg %val1, ptr %ptrval) {300; CHECK-LABEL: s_uadd_n1:301; CHECK: ; %bb.0:302; CHECK-NEXT: s_add_u32 s2, s0, -1303; CHECK-NEXT: s_addc_u32 s3, s1, -1304; CHECK-NEXT: s_cmp_lg_u64 s[0:1], 0305; CHECK-NEXT: v_mov_b32_e32 v2, s2306; CHECK-NEXT: v_mov_b32_e32 v3, s3307; CHECK-NEXT: s_cselect_b64 s[0:1], -1, 0308; CHECK-NEXT: flat_store_dwordx2 v[0:1], v[2:3]309; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, s[0:1]310; CHECK-NEXT: v_readfirstlane_b32 s0, v0311; CHECK-NEXT: s_mov_b32 s1, s0312; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)313; CHECK-NEXT: ; return to shader part epilog314 %pair = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %val0, i64 -1)315 %val = extractvalue {i64, i1} %pair, 0316 %obit = extractvalue {i64, i1} %pair, 1317 %res = sext i1 %obit to i64318 store i64 %val, ptr %ptrval319 ret i64 %res320}321 322define amdgpu_ps i64 @s_usub_p1(i64 inreg %val0, i64 inreg %val1, ptr %ptrval) {323; CHECK-LABEL: s_usub_p1:324; CHECK: ; %bb.0:325; CHECK-NEXT: s_sub_u32 s0, s0, 1326; CHECK-NEXT: s_subb_u32 s1, s1, 0327; CHECK-NEXT: v_mov_b32_e32 v2, s0328; CHECK-NEXT: v_mov_b32_e32 v3, s1329; CHECK-NEXT: s_cselect_b64 s[0:1], -1, 0330; CHECK-NEXT: flat_store_dwordx2 v[0:1], v[2:3]331; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, s[0:1]332; CHECK-NEXT: v_readfirstlane_b32 s0, v0333; CHECK-NEXT: s_mov_b32 s1, s0334; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)335; CHECK-NEXT: ; return to shader part epilog336 %pair = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %val0, i64 1)337 %val = extractvalue {i64, i1} %pair, 0338 %obit = extractvalue {i64, i1} %pair, 1339 %res = sext i1 %obit to i64340 store i64 %val, ptr %ptrval341 ret i64 %res342}343 344define amdgpu_ps i64 @s_usub_n1(i64 inreg %val0, i64 inreg %val1, ptr %ptrval) {345; CHECK-LABEL: s_usub_n1:346; CHECK: ; %bb.0:347; CHECK-NEXT: s_sub_u32 s0, s0, -1348; CHECK-NEXT: s_subb_u32 s1, s1, -1349; CHECK-NEXT: v_mov_b32_e32 v2, s0350; CHECK-NEXT: v_mov_b32_e32 v3, s1351; CHECK-NEXT: s_cselect_b64 s[0:1], -1, 0352; CHECK-NEXT: flat_store_dwordx2 v[0:1], v[2:3]353; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, -1, s[0:1]354; CHECK-NEXT: v_readfirstlane_b32 s0, v0355; CHECK-NEXT: s_mov_b32 s1, s0356; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)357; CHECK-NEXT: ; return to shader part epilog358 %pair = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %val0, i64 -1)359 %val = extractvalue {i64, i1} %pair, 0360 %obit = extractvalue {i64, i1} %pair, 1361 %res = sext i1 %obit to i64362 store i64 %val, ptr %ptrval363 ret i64 %res364}365