349 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; If we have a masked merge, in the form of: (M is constant)5; ((x ^ y) & M) ^ y6; Unfold it to7; (x & M) | (y & ~M)8 9define <2 x i4> @splat (<2 x i4> %x, <2 x i4> %y) {10; CHECK-LABEL: @splat(11; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], splat (i4 -2)12; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i4> [[Y:%.*]], splat (i4 1)13; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], [[TMP2]]14; CHECK-NEXT: ret <2 x i4> [[R]]15;16 %n0 = xor <2 x i4> %x, %y17 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2>18 %r = xor <2 x i4> %n1, %y19 ret <2 x i4> %r20}21 22define <3 x i4> @splat_undef (<3 x i4> %x, <3 x i4> %y) {23; CHECK-LABEL: @splat_undef(24; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 -2, i4 -1, i4 -2>25; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i4> [[Y:%.*]], <i4 1, i4 0, i4 1>26; CHECK-NEXT: [[R:%.*]] = or <3 x i4> [[TMP1]], [[TMP2]]27; CHECK-NEXT: ret <3 x i4> [[R]]28;29 %n0 = xor <3 x i4> %x, %y30 %n1 = and <3 x i4> %n0, <i4 -2, i4 undef, i4 -2>31 %r = xor <3 x i4> %n1, %y32 ret <3 x i4> %r33}34 35define <2 x i4> @nonsplat (<2 x i4> %x, <2 x i4> %y) {36; CHECK-LABEL: @nonsplat(37; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 -2, i4 1>38; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i4> [[Y:%.*]], <i4 1, i4 -2>39; CHECK-NEXT: [[R:%.*]] = or <2 x i4> [[TMP1]], [[TMP2]]40; CHECK-NEXT: ret <2 x i4> [[R]]41;42 %n0 = xor <2 x i4> %x, %y43 %n1 = and <2 x i4> %n0, <i4 -2, i4 1>44 %r = xor <2 x i4> %n1, %y45 ret <2 x i4> %r46}47 48; ============================================================================ ;49; Various cases with %x and/or %y being a constant50; ============================================================================ ;51 52define <2 x i4> @in_constant_varx_mone(<2 x i4> %x, <2 x i4> %mask) {53; CHECK-LABEL: @in_constant_varx_mone(54; CHECK-NEXT: [[R1:%.*]] = or <2 x i4> [[X:%.*]], splat (i4 -2)55; CHECK-NEXT: ret <2 x i4> [[R1]]56;57 %n0 = xor <2 x i4> %x, <i4 -1, i4 -1> ; %x58 %n1 = and <2 x i4> %n0, <i4 1, i4 1>59 %r = xor <2 x i4> %n1, <i4 -1, i4 -1>60 ret <2 x i4> %r61}62 63define <2 x i4> @in_constant_varx_14(<2 x i4> %x, <2 x i4> %mask) {64; CHECK-LABEL: @in_constant_varx_14(65; CHECK-NEXT: [[R1:%.*]] = or <2 x i4> [[X:%.*]], splat (i4 -2)66; CHECK-NEXT: ret <2 x i4> [[R1]]67;68 %n0 = xor <2 x i4> %x, <i4 14, i4 14> ; %x69 %n1 = and <2 x i4> %n0, <i4 1, i4 1>70 %r = xor <2 x i4> %n1, <i4 14, i4 14>71 ret <2 x i4> %r72}73 74define <2 x i4> @in_constant_varx_14_nonsplat(<2 x i4> %x, <2 x i4> %mask) {75; CHECK-LABEL: @in_constant_varx_14_nonsplat(76; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], splat (i4 1)77; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], <i4 -2, i4 6>78; CHECK-NEXT: ret <2 x i4> [[R]]79;80 %n0 = xor <2 x i4> %x, <i4 14, i4 7> ; %x81 %n1 = and <2 x i4> %n0, <i4 1, i4 1>82 %r = xor <2 x i4> %n1, <i4 14, i4 7>83 ret <2 x i4> %r84}85 86define <3 x i4> @in_constant_varx_14_undef(<3 x i4> %x, <3 x i4> %mask) {87; CHECK-LABEL: @in_constant_varx_14_undef(88; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 1, i4 -1, i4 1>89; CHECK-NEXT: [[R:%.*]] = or <3 x i4> [[TMP1]], <i4 -2, i4 0, i4 6>90; CHECK-NEXT: ret <3 x i4> [[R]]91;92 %n0 = xor <3 x i4> %x, <i4 14, i4 undef, i4 7> ; %x93 %n1 = and <3 x i4> %n0, <i4 1, i4 undef, i4 1>94 %r = xor <3 x i4> %n1, <i4 14, i4 undef, i4 7>95 ret <3 x i4> %r96}97 98define <2 x i4> @in_constant_mone_vary(<2 x i4> %y, <2 x i4> %mask) {99; CHECK-LABEL: @in_constant_mone_vary(100; CHECK-NEXT: [[R1:%.*]] = or <2 x i4> [[Y:%.*]], splat (i4 1)101; CHECK-NEXT: ret <2 x i4> [[R1]]102;103 %n0 = xor <2 x i4> %y, <i4 -1, i4 -1> ; %x104 %n1 = and <2 x i4> %n0, <i4 1, i4 1>105 %r = xor <2 x i4> %n1, %y106 ret <2 x i4> %r107}108 109define <2 x i4> @in_constant_14_vary(<2 x i4> %y, <2 x i4> %mask) {110; CHECK-LABEL: @in_constant_14_vary(111; CHECK-NEXT: [[R:%.*]] = and <2 x i4> [[Y:%.*]], splat (i4 -2)112; CHECK-NEXT: ret <2 x i4> [[R]]113;114 %n0 = xor <2 x i4> %y, <i4 14, i4 14> ; %x115 %n1 = and <2 x i4> %n0, <i4 1, i4 1>116 %r = xor <2 x i4> %n1, %y117 ret <2 x i4> %r118}119 120define <2 x i4> @in_constant_14_vary_nonsplat(<2 x i4> %y, <2 x i4> %mask) {121; CHECK-LABEL: @in_constant_14_vary_nonsplat(122; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[Y:%.*]], splat (i4 -2)123; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], <i4 0, i4 1>124; CHECK-NEXT: ret <2 x i4> [[R]]125;126 %n0 = xor <2 x i4> %y, <i4 14, i4 7> ; %x127 %n1 = and <2 x i4> %n0, <i4 1, i4 1>128 %r = xor <2 x i4> %n1, %y129 ret <2 x i4> %r130}131 132define <3 x i4> @in_constant_14_vary_undef(<3 x i4> %y, <3 x i4> %mask) {133; CHECK-LABEL: @in_constant_14_vary_undef(134; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[Y:%.*]], <i4 -2, i4 0, i4 -2>135; CHECK-NEXT: [[R:%.*]] = or <3 x i4> [[TMP1]], <i4 0, i4 undef, i4 1>136; CHECK-NEXT: ret <3 x i4> [[R]]137;138 %n0 = xor <3 x i4> %y, <i4 14, i4 undef, i4 7> ; %x139 %n1 = and <3 x i4> %n0, <i4 1, i4 undef, i4 1>140 %r = xor <3 x i4> %n1, %y141 ret <3 x i4> %r142}143 144; ============================================================================ ;145; Commutativity146; ============================================================================ ;147 148; Used to make sure that the IR complexity sorting does not interfere.149declare <2 x i4> @gen4()150 151define <2 x i4> @c_1_0_0 (<2 x i4> %x, <2 x i4> %y) {152; CHECK-LABEL: @c_1_0_0(153; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], splat (i4 -2)154; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i4> [[Y:%.*]], splat (i4 1)155; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], [[TMP2]]156; CHECK-NEXT: ret <2 x i4> [[R]]157;158 %n0 = xor <2 x i4> %y, %x ; swapped order159 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2>160 %r = xor <2 x i4> %n1, %y161 ret <2 x i4> %r162}163 164define <2 x i4> @c_0_1_0 (<2 x i4> %x, <2 x i4> %y) {165; CHECK-LABEL: @c_0_1_0(166; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[Y:%.*]], splat (i4 -2)167; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i4> [[X:%.*]], splat (i4 1)168; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], [[TMP2]]169; CHECK-NEXT: ret <2 x i4> [[R]]170;171 %n0 = xor <2 x i4> %x, %y172 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2>173 %r = xor <2 x i4> %n1, %x ; %x instead of %y174 ret <2 x i4> %r175}176 177define <2 x i4> @c_0_0_1 () {178; CHECK-LABEL: @c_0_0_1(179; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4()180; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4()181; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X]], splat (i4 -2)182; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i4> [[Y]], splat (i4 1)183; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], [[TMP2]]184; CHECK-NEXT: ret <2 x i4> [[R]]185;186 %x = call <2 x i4> @gen4()187 %y = call <2 x i4> @gen4()188 %n0 = xor <2 x i4> %x, %y189 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2>190 %r = xor <2 x i4> %y, %n1 ; swapped order191 ret <2 x i4> %r192}193 194define <2 x i4> @c_1_1_0 (<2 x i4> %x, <2 x i4> %y) {195; CHECK-LABEL: @c_1_1_0(196; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[Y:%.*]], splat (i4 -2)197; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i4> [[X:%.*]], splat (i4 1)198; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], [[TMP2]]199; CHECK-NEXT: ret <2 x i4> [[R]]200;201 %n0 = xor <2 x i4> %y, %x ; swapped order202 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2>203 %r = xor <2 x i4> %n1, %x ; %x instead of %y204 ret <2 x i4> %r205}206 207define <2 x i4> @c_1_0_1 (<2 x i4> %x) {208; CHECK-LABEL: @c_1_0_1(209; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4()210; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], splat (i4 -2)211; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i4> [[Y]], splat (i4 1)212; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], [[TMP2]]213; CHECK-NEXT: ret <2 x i4> [[R]]214;215 %y = call <2 x i4> @gen4()216 %n0 = xor <2 x i4> %y, %x ; swapped order217 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2>218 %r = xor <2 x i4> %y, %n1 ; swapped order219 ret <2 x i4> %r220}221 222define <2 x i4> @c_0_1_1 (<2 x i4> %y) {223; CHECK-LABEL: @c_0_1_1(224; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4()225; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[Y:%.*]], splat (i4 -2)226; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i4> [[X]], splat (i4 1)227; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], [[TMP2]]228; CHECK-NEXT: ret <2 x i4> [[R]]229;230 %x = call <2 x i4> @gen4()231 %n0 = xor <2 x i4> %x, %y232 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2>233 %r = xor <2 x i4> %x, %n1 ; swapped order, %x instead of %y234 ret <2 x i4> %r235}236 237define <2 x i4> @c_1_1_1 () {238; CHECK-LABEL: @c_1_1_1(239; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4()240; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4()241; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[Y]], splat (i4 -2)242; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i4> [[X]], splat (i4 1)243; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i4> [[TMP1]], [[TMP2]]244; CHECK-NEXT: ret <2 x i4> [[R]]245;246 %x = call <2 x i4> @gen4()247 %y = call <2 x i4> @gen4()248 %n0 = xor <2 x i4> %y, %x ; swapped order249 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2>250 %r = xor <2 x i4> %x, %n1 ; swapped order, %x instead of %y251 ret <2 x i4> %r252}253 254define <2 x i4> @commutativity_constant_14_vary(<2 x i4> %y, <2 x i4> %mask) {255; CHECK-LABEL: @commutativity_constant_14_vary(256; CHECK-NEXT: [[R:%.*]] = and <2 x i4> [[Y:%.*]], splat (i4 -2)257; CHECK-NEXT: ret <2 x i4> [[R]]258;259 %n0 = xor <2 x i4> %y, <i4 14, i4 14> ; %x260 %n1 = and <2 x i4> %n0, <i4 1, i4 1>261 %r = xor <2 x i4> %y, %n1 ; swapped262 ret <2 x i4> %r263}264 265; ============================================================================ ;266; Negative tests. Should not be folded.267; ============================================================================ ;268 269; One use only.270 271declare void @use4(<2 x i4>)272 273define <2 x i4> @n_oneuse_D (<2 x i4> %x, <2 x i4> %y) {274; CHECK-LABEL: @n_oneuse_D(275; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]276; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], splat (i4 -2)277; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]278; CHECK-NEXT: call void @use4(<2 x i4> [[N0]])279; CHECK-NEXT: ret <2 x i4> [[R]]280;281 %n0 = xor <2 x i4> %x, %y ; two uses of %n0, which is going to be replaced282 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2>283 %r = xor <2 x i4> %n1, %y284 call void @use4(<2 x i4> %n0)285 ret <2 x i4> %r286}287 288define <2 x i4> @n_oneuse_A (<2 x i4> %x, <2 x i4> %y) {289; CHECK-LABEL: @n_oneuse_A(290; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]291; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], splat (i4 -2)292; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]293; CHECK-NEXT: call void @use4(<2 x i4> [[N1]])294; CHECK-NEXT: ret <2 x i4> [[R]]295;296 %n0 = xor <2 x i4> %x, %y297 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2> ; two uses of %n1, which is going to be replaced298 %r = xor <2 x i4> %n1, %y299 call void @use4(<2 x i4> %n1)300 ret <2 x i4> %r301}302 303define <2 x i4> @n_oneuse_AD (<2 x i4> %x, <2 x i4> %y) {304; CHECK-LABEL: @n_oneuse_AD(305; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]306; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], splat (i4 -2)307; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]308; CHECK-NEXT: call void @use4(<2 x i4> [[N0]])309; CHECK-NEXT: call void @use4(<2 x i4> [[N1]])310; CHECK-NEXT: ret <2 x i4> [[R]]311;312 %n0 = xor <2 x i4> %x, %y313 %n1 = and <2 x i4> %n0, <i4 -2, i4 -2> ; two uses of %n1, which is going to be replaced314 %r = xor <2 x i4> %n1, %y315 call void @use4(<2 x i4> %n0)316 call void @use4(<2 x i4> %n1)317 ret <2 x i4> %r318}319 320; Mask is not constant321 322define <2 x i4> @n_var_mask (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {323; CHECK-LABEL: @n_var_mask(324; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]325; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]326; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]327; CHECK-NEXT: ret <2 x i4> [[R]]328;329 %n0 = xor <2 x i4> %x, %y330 %n1 = and <2 x i4> %n0, %m331 %r = xor <2 x i4> %n1, %y332 ret <2 x i4> %r333}334 335; Some third variable is used336 337define <2 x i4> @n_differenty(<2 x i4> %x, <2 x i4> %mask) {338; CHECK-LABEL: @n_differenty(339; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], <i4 -2, i4 7>340; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], splat (i4 1)341; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], <i4 7, i4 -2>342; CHECK-NEXT: ret <2 x i4> [[R]]343;344 %n0 = xor <2 x i4> %x, <i4 14, i4 7> ; %x345 %n1 = and <2 x i4> %n0, <i4 1, i4 1>346 %r = xor <2 x i4> %n1, <i4 7, i4 14>347 ret <2 x i4> %r348}349