786 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck --check-prefix=GCN %s3 4define i32 @s_out32(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {5; GCN-LABEL: s_out32:6; GCN: ; %bb.0:7; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)8; GCN-NEXT: s_xor_b32 s0, s0, s19; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)10; GCN-NEXT: s_and_b32 s0, s0, s211; GCN-NEXT: s_xor_b32 s0, s0, s112; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)13; GCN-NEXT: v_mov_b32_e32 v0, s014; GCN-NEXT: s_setpc_b64 s[30:31]15 %mx = and i32 %x, %mask16 %notmask = xor i32 %mask, -117 %my = and i32 %y, %notmask18 %r = or i32 %mx, %my19 ret i32 %r20}21 22define i64 @s_out64(i64 inreg %x, i64 inreg %y, i64 inreg %mask) {23; GCN-LABEL: s_out64:24; GCN: ; %bb.0:25; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)26; GCN-NEXT: s_xor_b64 s[0:1], s[0:1], s[2:3]27; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)28; GCN-NEXT: s_and_b64 s[0:1], s[0:1], s[16:17]29; GCN-NEXT: s_xor_b64 s[0:1], s[0:1], s[2:3]30; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)31; GCN-NEXT: v_dual_mov_b32 v0, s0 :: v_dual_mov_b32 v1, s132; GCN-NEXT: s_setpc_b64 s[30:31]33 %mx = and i64 %x, %mask34 %notmask = xor i64 %mask, -135 %my = and i64 %y, %notmask36 %r = or i64 %mx, %my37 ret i64 %r38}39 40define i32 @s_in32(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {41; GCN-LABEL: s_in32:42; GCN: ; %bb.0:43; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)44; GCN-NEXT: s_xor_b32 s0, s0, s145; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)46; GCN-NEXT: s_and_b32 s0, s0, s247; GCN-NEXT: s_xor_b32 s0, s0, s148; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)49; GCN-NEXT: v_mov_b32_e32 v0, s050; GCN-NEXT: s_setpc_b64 s[30:31]51 %n0 = xor i32 %x, %y52 %n1 = and i32 %n0, %mask53 %r = xor i32 %n1, %y54 ret i32 %r55}56 57define i64 @s_in64(i64 inreg %x, i64 inreg %y, i64 inreg %mask) {58; GCN-LABEL: s_in64:59; GCN: ; %bb.0:60; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)61; GCN-NEXT: s_xor_b64 s[0:1], s[0:1], s[2:3]62; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)63; GCN-NEXT: s_and_b64 s[0:1], s[0:1], s[16:17]64; GCN-NEXT: s_xor_b64 s[0:1], s[0:1], s[2:3]65; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)66; GCN-NEXT: v_dual_mov_b32 v0, s0 :: v_dual_mov_b32 v1, s167; GCN-NEXT: s_setpc_b64 s[30:31]68 %n0 = xor i64 %x, %y69 %n1 = and i64 %n0, %mask70 %r = xor i64 %n1, %y71 ret i64 %r72}73; ============================================================================ ;74; Commutativity tests.75; ============================================================================ ;76define i32 @s_in_commutativity_0_0_1(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {77; GCN-LABEL: s_in_commutativity_0_0_1:78; GCN: ; %bb.0:79; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)80; GCN-NEXT: s_xor_b32 s0, s0, s181; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)82; GCN-NEXT: s_and_b32 s0, s2, s083; GCN-NEXT: s_xor_b32 s0, s0, s184; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)85; GCN-NEXT: v_mov_b32_e32 v0, s086; GCN-NEXT: s_setpc_b64 s[30:31]87 %n0 = xor i32 %x, %y88 %n1 = and i32 %mask, %n089 %r = xor i32 %n1, %y90 ret i32 %r91}92 93define i32 @s_in_commutativity_0_1_0(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {94; GCN-LABEL: s_in_commutativity_0_1_0:95; GCN: ; %bb.0:96; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)97; GCN-NEXT: s_xor_b32 s0, s0, s198; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)99; GCN-NEXT: s_and_b32 s0, s0, s2100; GCN-NEXT: s_xor_b32 s0, s1, s0101; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)102; GCN-NEXT: v_mov_b32_e32 v0, s0103; GCN-NEXT: s_setpc_b64 s[30:31]104 %n0 = xor i32 %x, %y105 %n1 = and i32 %n0, %mask106 %r = xor i32 %y, %n1107 ret i32 %r108}109 110define i32 @in_commutativity_0_1_1(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {111; GCN-LABEL: in_commutativity_0_1_1:112; GCN: ; %bb.0:113; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)114; GCN-NEXT: s_xor_b32 s0, s0, s1115; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)116; GCN-NEXT: s_and_b32 s0, s2, s0117; GCN-NEXT: s_xor_b32 s0, s1, s0118; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)119; GCN-NEXT: v_mov_b32_e32 v0, s0120; GCN-NEXT: s_setpc_b64 s[30:31]121 %n0 = xor i32 %x, %y122 %n1 = and i32 %mask, %n0123 %r = xor i32 %y, %n1124 ret i32 %r125}126 127define i32 @s_in_commutativity_1_0_0(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {128; GCN-LABEL: s_in_commutativity_1_0_0:129; GCN: ; %bb.0:130; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)131; GCN-NEXT: s_xor_b32 s1, s0, s1132; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)133; GCN-NEXT: s_and_b32 s1, s1, s2134; GCN-NEXT: s_xor_b32 s0, s1, s0135; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)136; GCN-NEXT: v_mov_b32_e32 v0, s0137; GCN-NEXT: s_setpc_b64 s[30:31]138 %n0 = xor i32 %x, %y139 %n1 = and i32 %n0, %mask140 %r = xor i32 %n1, %x141 ret i32 %r142}143 144define i32 @s_in_commutativity_1_0_1(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {145; GCN-LABEL: s_in_commutativity_1_0_1:146; GCN: ; %bb.0:147; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)148; GCN-NEXT: s_xor_b32 s1, s0, s1149; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)150; GCN-NEXT: s_and_b32 s1, s2, s1151; GCN-NEXT: s_xor_b32 s0, s1, s0152; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)153; GCN-NEXT: v_mov_b32_e32 v0, s0154; GCN-NEXT: s_setpc_b64 s[30:31]155 %n0 = xor i32 %x, %y156 %n1 = and i32 %mask, %n0157 %r = xor i32 %n1, %x158 ret i32 %r159}160 161define i32 @s_in_commutativity_1_1_0(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {162; GCN-LABEL: s_in_commutativity_1_1_0:163; GCN: ; %bb.0:164; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)165; GCN-NEXT: s_xor_b32 s1, s0, s1166; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)167; GCN-NEXT: s_and_b32 s1, s1, s2168; GCN-NEXT: s_xor_b32 s0, s0, s1169; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)170; GCN-NEXT: v_mov_b32_e32 v0, s0171; GCN-NEXT: s_setpc_b64 s[30:31]172 %n0 = xor i32 %x, %y173 %n1 = and i32 %n0, %mask174 %r = xor i32 %x, %n1175 ret i32 %r176}177 178define i32 @s_in_commutativity_1_1_1(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {179; GCN-LABEL: s_in_commutativity_1_1_1:180; GCN: ; %bb.0:181; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)182; GCN-NEXT: s_xor_b32 s1, s0, s1183; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)184; GCN-NEXT: s_and_b32 s1, s2, s1185; GCN-NEXT: s_xor_b32 s0, s0, s1186; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)187; GCN-NEXT: v_mov_b32_e32 v0, s0188; GCN-NEXT: s_setpc_b64 s[30:31]189 %n0 = xor i32 %x, %y190 %n1 = and i32 %mask, %n0191 %r = xor i32 %x, %n1192 ret i32 %r193}194; ============================================================================ ;195; Y is an 'and' too.196; ============================================================================ ;197define i32 @s_in_complex_y0(i32 inreg %x, i32 inreg %y_hi, i32 inreg %y_low, i32 inreg %mask) {198; GCN-LABEL: s_in_complex_y0:199; GCN: ; %bb.0:200; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)201; GCN-NEXT: s_and_b32 s1, s1, s2202; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)203; GCN-NEXT: s_xor_b32 s0, s0, s1204; GCN-NEXT: s_and_b32 s0, s0, s3205; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)206; GCN-NEXT: s_xor_b32 s0, s0, s1207; GCN-NEXT: v_mov_b32_e32 v0, s0208; GCN-NEXT: s_setpc_b64 s[30:31]209 %y = and i32 %y_hi, %y_low210 %n0 = xor i32 %x, %y211 %n1 = and i32 %n0, %mask212 %r = xor i32 %n1, %y213 ret i32 %r214}215 216define i32 @s_in_complex_y1(i32 inreg %x, i32 inreg %y_hi, i32 inreg %y_low, i32 inreg %mask) {217; GCN-LABEL: s_in_complex_y1:218; GCN: ; %bb.0:219; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)220; GCN-NEXT: s_and_b32 s1, s1, s2221; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)222; GCN-NEXT: s_xor_b32 s0, s0, s1223; GCN-NEXT: s_and_b32 s0, s0, s3224; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)225; GCN-NEXT: s_xor_b32 s0, s1, s0226; GCN-NEXT: v_mov_b32_e32 v0, s0227; GCN-NEXT: s_setpc_b64 s[30:31]228 %y = and i32 %y_hi, %y_low229 %n0 = xor i32 %x, %y230 %n1 = and i32 %n0, %mask231 %r = xor i32 %y, %n1232 ret i32 %r233}234; ============================================================================ ;235; M is an 'xor' too.236; ============================================================================ ;237define i32 @s_in_complex_m0(i32 inreg %x, i32 inreg %y, i32 inreg %m_a, i32 inreg %m_b) {238; GCN-LABEL: s_in_complex_m0:239; GCN: ; %bb.0:240; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)241; GCN-NEXT: s_xor_b32 s2, s2, s3242; GCN-NEXT: s_xor_b32 s0, s0, s1243; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)244; GCN-NEXT: s_and_b32 s0, s0, s2245; GCN-NEXT: s_xor_b32 s0, s0, s1246; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)247; GCN-NEXT: v_mov_b32_e32 v0, s0248; GCN-NEXT: s_setpc_b64 s[30:31]249 %mask = xor i32 %m_a, %m_b250 %n0 = xor i32 %x, %y251 %n1 = and i32 %n0, %mask252 %r = xor i32 %n1, %y253 ret i32 %r254}255 256define i32 @s_in_complex_m1(i32 inreg %x, i32 inreg %y, i32 inreg %m_a, i32 inreg %m_b) {257; GCN-LABEL: s_in_complex_m1:258; GCN: ; %bb.0:259; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)260; GCN-NEXT: s_xor_b32 s2, s2, s3261; GCN-NEXT: s_xor_b32 s0, s0, s1262; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)263; GCN-NEXT: s_and_b32 s0, s2, s0264; GCN-NEXT: s_xor_b32 s0, s0, s1265; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)266; GCN-NEXT: v_mov_b32_e32 v0, s0267; GCN-NEXT: s_setpc_b64 s[30:31]268 %mask = xor i32 %m_a, %m_b269 %n0 = xor i32 %x, %y270 %n1 = and i32 %mask, %n0271 %r = xor i32 %n1, %y272 ret i32 %r273}274; ============================================================================ ;275; Both Y and M are complex.276; ============================================================================ ;277define i32 @s_in_complex_y0_m0(i32 inreg %x, i32 inreg %y_hi, i32 inreg %y_low, i32 inreg %m_a, i32 inreg %m_b) {278; GCN-LABEL: s_in_complex_y0_m0:279; GCN: ; %bb.0:280; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)281; GCN-NEXT: s_and_b32 s1, s1, s2282; GCN-NEXT: s_xor_b32 s2, s3, s16283; GCN-NEXT: s_xor_b32 s0, s0, s1284; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)285; GCN-NEXT: s_and_b32 s0, s0, s2286; GCN-NEXT: s_xor_b32 s0, s0, s1287; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)288; GCN-NEXT: v_mov_b32_e32 v0, s0289; GCN-NEXT: s_setpc_b64 s[30:31]290 %y = and i32 %y_hi, %y_low291 %mask = xor i32 %m_a, %m_b292 %n0 = xor i32 %x, %y293 %n1 = and i32 %n0, %mask294 %r = xor i32 %n1, %y295 ret i32 %r296}297 298define i32 @s_in_complex_y1_m0(i32 inreg %x, i32 inreg %y_hi, i32 inreg %y_low, i32 inreg %m_a, i32 inreg %m_b) {299; GCN-LABEL: s_in_complex_y1_m0:300; GCN: ; %bb.0:301; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)302; GCN-NEXT: s_and_b32 s1, s1, s2303; GCN-NEXT: s_xor_b32 s2, s3, s16304; GCN-NEXT: s_xor_b32 s0, s0, s1305; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)306; GCN-NEXT: s_and_b32 s0, s0, s2307; GCN-NEXT: s_xor_b32 s0, s1, s0308; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)309; GCN-NEXT: v_mov_b32_e32 v0, s0310; GCN-NEXT: s_setpc_b64 s[30:31]311 %y = and i32 %y_hi, %y_low312 %mask = xor i32 %m_a, %m_b313 %n0 = xor i32 %x, %y314 %n1 = and i32 %n0, %mask315 %r = xor i32 %y, %n1316 ret i32 %r317}318 319define i32 @s_in_complex_y0_m1(i32 inreg %x, i32 inreg %y_hi, i32 inreg %y_low, i32 inreg %m_a, i32 inreg %m_b) {320; GCN-LABEL: s_in_complex_y0_m1:321; GCN: ; %bb.0:322; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)323; GCN-NEXT: s_and_b32 s1, s1, s2324; GCN-NEXT: s_xor_b32 s2, s3, s16325; GCN-NEXT: s_xor_b32 s0, s0, s1326; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)327; GCN-NEXT: s_and_b32 s0, s2, s0328; GCN-NEXT: s_xor_b32 s0, s0, s1329; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)330; GCN-NEXT: v_mov_b32_e32 v0, s0331; GCN-NEXT: s_setpc_b64 s[30:31]332 %y = and i32 %y_hi, %y_low333 %mask = xor i32 %m_a, %m_b334 %n0 = xor i32 %x, %y335 %n1 = and i32 %mask, %n0336 %r = xor i32 %n1, %y337 ret i32 %r338}339 340define i32 @s_in_complex_y1_m1(i32 inreg %x, i32 inreg %y_hi, i32 inreg %y_low, i32 inreg %m_a, i32 inreg %m_b) {341; GCN-LABEL: s_in_complex_y1_m1:342; GCN: ; %bb.0:343; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)344; GCN-NEXT: s_and_b32 s1, s1, s2345; GCN-NEXT: s_xor_b32 s2, s3, s16346; GCN-NEXT: s_xor_b32 s0, s0, s1347; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)348; GCN-NEXT: s_and_b32 s0, s2, s0349; GCN-NEXT: s_xor_b32 s0, s1, s0350; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)351; GCN-NEXT: v_mov_b32_e32 v0, s0352; GCN-NEXT: s_setpc_b64 s[30:31]353 %y = and i32 %y_hi, %y_low354 %mask = xor i32 %m_a, %m_b355 %n0 = xor i32 %x, %y356 %n1 = and i32 %mask, %n0357 %r = xor i32 %y, %n1358 ret i32 %r359}360; ============================================================================ ;361; Various cases with %x and/or %y being a constant362; ============================================================================ ;363define i32 @s_out_constant_varx_mone(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {364; GCN-LABEL: s_out_constant_varx_mone:365; GCN: ; %bb.0:366; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)367; GCN-NEXT: s_and_b32 s0, s2, s0368; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)369; GCN-NEXT: s_or_not1_b32 s0, s0, s2370; GCN-NEXT: v_mov_b32_e32 v0, s0371; GCN-NEXT: s_setpc_b64 s[30:31]372 %notmask = xor i32 %mask, -1373 %mx = and i32 %mask, %x374 %my = and i32 %notmask, -1375 %r = or i32 %mx, %my376 ret i32 %r377}378 379define i32 @s_in_constant_varx_mone(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {380; GCN-LABEL: s_in_constant_varx_mone:381; GCN: ; %bb.0:382; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)383; GCN-NEXT: s_not_b32 s0, s0384; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)385; GCN-NEXT: s_nand_b32 s0, s0, s2386; GCN-NEXT: v_mov_b32_e32 v0, s0387; GCN-NEXT: s_setpc_b64 s[30:31]388 %n0 = xor i32 %x, -1389 %n1 = and i32 %n0, %mask390 %r = xor i32 %n1, -1391 ret i32 %r392}393 394; This is not a canonical form. Testing for completeness only.395define i32 @s_out_constant_varx_mone_invmask(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {396; GCN-LABEL: s_out_constant_varx_mone_invmask:397; GCN: ; %bb.0:398; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)399; GCN-NEXT: s_or_b32 s0, s0, s2400; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)401; GCN-NEXT: v_mov_b32_e32 v0, s0402; GCN-NEXT: s_setpc_b64 s[30:31]403 %notmask = xor i32 %mask, -1404 %mx = and i32 %notmask, %x405 %my = and i32 %mask, -1406 %r = or i32 %mx, %my407 ret i32 %r408}409 410; This is not a canonical form. Testing for completeness only.411define i32 @s_in_constant_varx_mone_invmask(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {412; GCN-LABEL: s_in_constant_varx_mone_invmask:413; GCN: ; %bb.0:414; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)415; GCN-NEXT: s_not_b32 s1, s2416; GCN-NEXT: s_not_b32 s0, s0417; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)418; GCN-NEXT: s_nand_b32 s0, s0, s1419; GCN-NEXT: v_mov_b32_e32 v0, s0420; GCN-NEXT: s_setpc_b64 s[30:31]421 %notmask = xor i32 %mask, -1422 %n0 = xor i32 %x, -1423 %n1 = and i32 %n0, %notmask424 %r = xor i32 %n1, -1425 ret i32 %r426}427 428define i32 @s_out_constant_varx_42(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {429; GCN-LABEL: s_out_constant_varx_42:430; GCN: ; %bb.0:431; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)432; GCN-NEXT: s_xor_b32 s0, s0, 42433; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)434; GCN-NEXT: s_and_b32 s0, s0, s2435; GCN-NEXT: s_xor_b32 s0, s0, 42436; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)437; GCN-NEXT: v_mov_b32_e32 v0, s0438; GCN-NEXT: s_setpc_b64 s[30:31]439 %notmask = xor i32 %mask, -1440 %mx = and i32 %mask, %x441 %my = and i32 %notmask, 42442 %r = or i32 %mx, %my443 ret i32 %r444}445 446define i32 @in_constant_varx_42(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {447; GCN-LABEL: in_constant_varx_42:448; GCN: ; %bb.0:449; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)450; GCN-NEXT: s_xor_b32 s0, s0, 42451; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)452; GCN-NEXT: s_and_b32 s0, s0, s2453; GCN-NEXT: s_xor_b32 s0, s0, 42454; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)455; GCN-NEXT: v_mov_b32_e32 v0, s0456; GCN-NEXT: s_setpc_b64 s[30:31]457 %n0 = xor i32 %x, 42458 %n1 = and i32 %n0, %mask459 %r = xor i32 %n1, 42460 ret i32 %r461}462 463; This is not a canonical form. Testing for completeness only.464define i32 @s_out_constant_varx_42_invmask(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {465; GCN-LABEL: s_out_constant_varx_42_invmask:466; GCN: ; %bb.0:467; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)468; GCN-NEXT: s_xor_b32 s1, s0, 42469; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)470; GCN-NEXT: s_and_b32 s1, s1, s2471; GCN-NEXT: s_xor_b32 s0, s1, s0472; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)473; GCN-NEXT: v_mov_b32_e32 v0, s0474; GCN-NEXT: s_setpc_b64 s[30:31]475 %notmask = xor i32 %mask, -1476 %mx = and i32 %notmask, %x477 %my = and i32 %mask, 42478 %r = or i32 %mx, %my479 ret i32 %r480}481 482; This is not a canonical form. Testing for completeness only.483define i32 @s_in_constant_varx_42_invmask(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {484; GCN-LABEL: s_in_constant_varx_42_invmask:485; GCN: ; %bb.0:486; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)487; GCN-NEXT: s_xor_b32 s0, s0, 42488; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)489; GCN-NEXT: s_and_not1_b32 s0, s0, s2490; GCN-NEXT: s_xor_b32 s0, s0, 42491; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)492; GCN-NEXT: v_mov_b32_e32 v0, s0493; GCN-NEXT: s_setpc_b64 s[30:31]494 %notmask = xor i32 %mask, -1495 %n0 = xor i32 %x, 42496 %n1 = and i32 %n0, %notmask497 %r = xor i32 %n1, 42498 ret i32 %r499}500 501define i32 @s_out_constant_mone_vary(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {502; GCN-LABEL: s_out_constant_mone_vary:503; GCN: ; %bb.0:504; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)505; GCN-NEXT: s_or_b32 s0, s1, s2506; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)507; GCN-NEXT: v_mov_b32_e32 v0, s0508; GCN-NEXT: s_setpc_b64 s[30:31]509 %notmask = xor i32 %mask, -1510 %mx = and i32 %mask, -1511 %my = and i32 %notmask, %y512 %r = or i32 %mx, %my513 ret i32 %r514}515 516define i32 @s_in_constant_mone_vary(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {517; GCN-LABEL: s_in_constant_mone_vary:518; GCN: ; %bb.0:519; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)520; GCN-NEXT: s_or_b32 s0, s2, s1521; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)522; GCN-NEXT: v_mov_b32_e32 v0, s0523; GCN-NEXT: s_setpc_b64 s[30:31]524 %n0 = xor i32 -1, %y525 %n1 = and i32 %n0, %mask526 %r = xor i32 %n1, %y527 ret i32 %r528}529 530; This is not a canonical form. Testing for completeness only.531define i32 @s_out_constant_mone_vary_invmask(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {532; GCN-LABEL: s_out_constant_mone_vary_invmask:533; GCN: ; %bb.0:534; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)535; GCN-NEXT: s_and_b32 s0, s2, s1536; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)537; GCN-NEXT: s_or_not1_b32 s0, s0, s2538; GCN-NEXT: v_mov_b32_e32 v0, s0539; GCN-NEXT: s_setpc_b64 s[30:31]540 %notmask = xor i32 %mask, -1541 %mx = and i32 %notmask, -1542 %my = and i32 %mask, %y543 %r = or i32 %mx, %my544 ret i32 %r545}546 547; This is not a canonical form. Testing for completeness only.548define i32 @s_in_constant_mone_vary_invmask(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {549; GCN-LABEL: s_in_constant_mone_vary_invmask:550; GCN: ; %bb.0:551; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)552; GCN-NEXT: s_or_not1_b32 s0, s1, s2553; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)554; GCN-NEXT: v_mov_b32_e32 v0, s0555; GCN-NEXT: s_setpc_b64 s[30:31]556 %notmask = xor i32 %mask, -1557 %n0 = xor i32 -1, %y558 %n1 = and i32 %n0, %notmask559 %r = xor i32 %n1, %y560 ret i32 %r561}562 563define i32 @s_out_constant_42_vary(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {564; GCN-LABEL: s_out_constant_42_vary:565; GCN: ; %bb.0:566; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)567; GCN-NEXT: s_xor_b32 s0, s1, 42568; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)569; GCN-NEXT: s_and_b32 s0, s0, s2570; GCN-NEXT: s_xor_b32 s0, s0, s1571; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)572; GCN-NEXT: v_mov_b32_e32 v0, s0573; GCN-NEXT: s_setpc_b64 s[30:31]574 %notmask = xor i32 %mask, -1575 %mx = and i32 %mask, 42576 %my = and i32 %notmask, %y577 %r = or i32 %mx, %my578 ret i32 %r579}580 581define i32 @s_in_constant_42_vary(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {582; GCN-LABEL: s_in_constant_42_vary:583; GCN: ; %bb.0:584; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)585; GCN-NEXT: s_xor_b32 s0, s1, 42586; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)587; GCN-NEXT: s_and_b32 s0, s0, s2588; GCN-NEXT: s_xor_b32 s0, s0, s1589; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)590; GCN-NEXT: v_mov_b32_e32 v0, s0591; GCN-NEXT: s_setpc_b64 s[30:31]592 %n0 = xor i32 42, %y593 %n1 = and i32 %n0, %mask594 %r = xor i32 %n1, %y595 ret i32 %r596}597 598; This is not a canonical form. Testing for completeness only.599define i32 @s_out_constant_42_vary_invmask(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {600; GCN-LABEL: s_out_constant_42_vary_invmask:601; GCN: ; %bb.0:602; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)603; GCN-NEXT: s_xor_b32 s0, s1, 42604; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)605; GCN-NEXT: s_and_b32 s0, s0, s2606; GCN-NEXT: s_xor_b32 s0, s0, 42607; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)608; GCN-NEXT: v_mov_b32_e32 v0, s0609; GCN-NEXT: s_setpc_b64 s[30:31]610 %notmask = xor i32 %mask, -1611 %mx = and i32 %notmask, 42612 %my = and i32 %mask, %y613 %r = or i32 %mx, %my614 ret i32 %r615}616 617; This is not a canonical form. Testing for completeness only.618define i32 @s_in_constant_42_vary_invmask(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {619; GCN-LABEL: s_in_constant_42_vary_invmask:620; GCN: ; %bb.0:621; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)622; GCN-NEXT: s_xor_b32 s0, s1, 42623; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)624; GCN-NEXT: s_and_not1_b32 s0, s0, s2625; GCN-NEXT: s_xor_b32 s0, s0, s1626; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)627; GCN-NEXT: v_mov_b32_e32 v0, s0628; GCN-NEXT: s_setpc_b64 s[30:31]629 %notmask = xor i32 %mask, -1630 %n0 = xor i32 42, %y631 %n1 = and i32 %n0, %notmask632 %r = xor i32 %n1, %y633 ret i32 %r634}635; ============================================================================ ;636; Negative tests. Should not be folded.637; ============================================================================ ;638; Multi-use tests.639declare void @use32(i32) nounwind640define i32 @s_in_multiuse_A(i32 inreg %x, i32 inreg %y, i32 inreg %z, i32 inreg %mask) nounwind {641; GCN-LABEL: s_in_multiuse_A:642; GCN: ; %bb.0:643; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)644; GCN-NEXT: s_mov_b32 s2, s33645; GCN-NEXT: s_mov_b32 s33, s32646; GCN-NEXT: s_or_saveexec_b32 s16, -1647; GCN-NEXT: scratch_store_b32 off, v40, s33 ; 4-byte Folded Spill648; GCN-NEXT: s_mov_b32 exec_lo, s16649; GCN-NEXT: v_writelane_b32 v40, s2, 4650; GCN-NEXT: s_add_i32 s32, s32, 16651; GCN-NEXT: s_getpc_b64 s[16:17]652; GCN-NEXT: s_add_u32 s16, s16, use32@gotpcrel32@lo+4653; GCN-NEXT: s_addc_u32 s17, s17, use32@gotpcrel32@hi+12654; GCN-NEXT: s_xor_b32 s0, s0, s1655; GCN-NEXT: s_load_b64 s[16:17], s[16:17], 0x0656; GCN-NEXT: v_writelane_b32 v40, s30, 0657; GCN-NEXT: v_writelane_b32 v40, s31, 1658; GCN-NEXT: v_writelane_b32 v40, s34, 2659; GCN-NEXT: s_mov_b32 s34, s1660; GCN-NEXT: v_writelane_b32 v40, s35, 3661; GCN-NEXT: s_and_b32 s35, s0, s3662; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)663; GCN-NEXT: v_mov_b32_e32 v0, s35664; GCN-NEXT: s_waitcnt lgkmcnt(0)665; GCN-NEXT: s_swappc_b64 s[30:31], s[16:17]666; GCN-NEXT: s_xor_b32 s0, s35, s34667; GCN-NEXT: v_readlane_b32 s35, v40, 3668; GCN-NEXT: v_mov_b32_e32 v0, s0669; GCN-NEXT: v_readlane_b32 s34, v40, 2670; GCN-NEXT: v_readlane_b32 s31, v40, 1671; GCN-NEXT: v_readlane_b32 s30, v40, 0672; GCN-NEXT: s_mov_b32 s32, s33673; GCN-NEXT: v_readlane_b32 s0, v40, 4674; GCN-NEXT: s_or_saveexec_b32 s1, -1675; GCN-NEXT: scratch_load_b32 v40, off, s33 ; 4-byte Folded Reload676; GCN-NEXT: s_mov_b32 exec_lo, s1677; GCN-NEXT: s_mov_b32 s33, s0678; GCN-NEXT: s_waitcnt vmcnt(0)679; GCN-NEXT: s_setpc_b64 s[30:31]680 %n0 = xor i32 %x, %y681 %n1 = and i32 %n0, %mask682 call void @use32(i32 %n1)683 %r = xor i32 %n1, %y684 ret i32 %r685}686 687define i32 @s_in_multiuse_B(i32 inreg %x, i32 inreg %y, i32 inreg %z, i32 inreg %mask) nounwind {688; GCN-LABEL: s_in_multiuse_B:689; GCN: ; %bb.0:690; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)691; GCN-NEXT: s_mov_b32 s2, s33692; GCN-NEXT: s_mov_b32 s33, s32693; GCN-NEXT: s_or_saveexec_b32 s16, -1694; GCN-NEXT: scratch_store_b32 off, v40, s33 ; 4-byte Folded Spill695; GCN-NEXT: s_mov_b32 exec_lo, s16696; GCN-NEXT: s_add_i32 s32, s32, 16697; GCN-NEXT: s_getpc_b64 s[16:17]698; GCN-NEXT: s_add_u32 s16, s16, use32@gotpcrel32@lo+4699; GCN-NEXT: s_addc_u32 s17, s17, use32@gotpcrel32@hi+12700; GCN-NEXT: v_writelane_b32 v40, s2, 4701; GCN-NEXT: s_load_b64 s[16:17], s[16:17], 0x0702; GCN-NEXT: s_xor_b32 s0, s0, s1703; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)704; GCN-NEXT: v_mov_b32_e32 v0, s0705; GCN-NEXT: v_writelane_b32 v40, s30, 0706; GCN-NEXT: v_writelane_b32 v40, s31, 1707; GCN-NEXT: v_writelane_b32 v40, s34, 2708; GCN-NEXT: s_mov_b32 s34, s1709; GCN-NEXT: v_writelane_b32 v40, s35, 3710; GCN-NEXT: s_and_b32 s35, s0, s3711; GCN-NEXT: s_waitcnt lgkmcnt(0)712; GCN-NEXT: s_swappc_b64 s[30:31], s[16:17]713; GCN-NEXT: s_xor_b32 s0, s35, s34714; GCN-NEXT: v_readlane_b32 s35, v40, 3715; GCN-NEXT: v_mov_b32_e32 v0, s0716; GCN-NEXT: v_readlane_b32 s34, v40, 2717; GCN-NEXT: v_readlane_b32 s31, v40, 1718; GCN-NEXT: v_readlane_b32 s30, v40, 0719; GCN-NEXT: s_mov_b32 s32, s33720; GCN-NEXT: v_readlane_b32 s0, v40, 4721; GCN-NEXT: s_or_saveexec_b32 s1, -1722; GCN-NEXT: scratch_load_b32 v40, off, s33 ; 4-byte Folded Reload723; GCN-NEXT: s_mov_b32 exec_lo, s1724; GCN-NEXT: s_mov_b32 s33, s0725; GCN-NEXT: s_waitcnt vmcnt(0)726; GCN-NEXT: s_setpc_b64 s[30:31]727 %n0 = xor i32 %x, %y728 %n1 = and i32 %n0, %mask729 call void @use32(i32 %n0)730 %r = xor i32 %n1, %y731 ret i32 %r732}733 734; Various bad variants735define i32 @s_n0_badmask(i32 inreg %x, i32 inreg %y, i32 inreg %mask, i32 inreg %mask2) {736; GCN-LABEL: s_n0_badmask:737; GCN: ; %bb.0:738; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)739; GCN-NEXT: s_and_b32 s0, s0, s2740; GCN-NEXT: s_and_not1_b32 s1, s1, s3741; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)742; GCN-NEXT: s_or_b32 s0, s0, s1743; GCN-NEXT: v_mov_b32_e32 v0, s0744; GCN-NEXT: s_setpc_b64 s[30:31]745 %mx = and i32 %x, %mask746 %notmask = xor i32 %mask2, -1747 %my = and i32 %y, %notmask748 %r = or i32 %mx, %my749 ret i32 %r750}751 752define i32 @s_n0_badxor(i32 inreg %x, i32 inreg %y, i32 inreg %mask) {753; GCN-LABEL: s_n0_badxor:754; GCN: ; %bb.0:755; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)756; GCN-NEXT: s_xor_b32 s3, s2, 1757; GCN-NEXT: s_and_b32 s0, s0, s2758; GCN-NEXT: s_and_b32 s1, s1, s3759; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)760; GCN-NEXT: s_or_b32 s0, s0, s1761; GCN-NEXT: v_mov_b32_e32 v0, s0762; GCN-NEXT: s_setpc_b64 s[30:31]763 %mx = and i32 %x, %mask764 %notmask = xor i32 %mask, 1765 %my = and i32 %y, %notmask766 %r = or i32 %mx, %my767 ret i32 %r768}769 770define i32 @s_n1_thirdvar(i32 inreg %x, i32 inreg %y, i32 inreg %z, i32 inreg %mask) {771; GCN-LABEL: s_n1_thirdvar:772; GCN: ; %bb.0:773; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)774; GCN-NEXT: s_xor_b32 s0, s0, s1775; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)776; GCN-NEXT: s_and_b32 s0, s0, s3777; GCN-NEXT: s_xor_b32 s0, s0, s2778; GCN-NEXT: s_delay_alu instid0(SALU_CYCLE_1)779; GCN-NEXT: v_mov_b32_e32 v0, s0780; GCN-NEXT: s_setpc_b64 s[30:31]781 %n0 = xor i32 %x, %y782 %n1 = and i32 %n0, %mask783 %r = xor i32 %n1, %z784 ret i32 %r785}786