1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; If we have a masked merge, in the form of: (M is not constant) 5; ((x ^ y) & ~M) ^ y 6; We can de-invert the M: 7; ((x ^ y) & M) ^ x 8 9define <2 x i4> @vector (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { 10; CHECK-LABEL: @vector( 11; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] 12; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] 13; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] 14; CHECK-NEXT: ret <2 x i4> [[R]] 15; 16 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 17 %n0 = xor <2 x i4> %x, %y 18 %n1 = and <2 x i4> %n0, %im 19 %r = xor <2 x i4> %n1, %y 20 ret <2 x i4> %r 21} 22 23define <3 x i4> @vector_poison (<3 x i4> %x, <3 x i4> %y, <3 x i4> %m) { 24; CHECK-LABEL: @vector_poison( 25; CHECK-NEXT: [[N0:%.*]] = xor <3 x i4> [[X:%.*]], [[Y:%.*]] 26; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[N0]], [[M:%.*]] 27; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[TMP1]], [[X]] 28; CHECK-NEXT: ret <3 x i4> [[R]] 29; 30 %im = xor <3 x i4> %m, <i4 -1, i4 poison, i4 -1> 31 %n0 = xor <3 x i4> %x, %y 32 %n1 = and <3 x i4> %n0, %im 33 %r = xor <3 x i4> %n1, %y 34 ret <3 x i4> %r 35} 36 37; ============================================================================ ; 38; Various cases with %x and/or %y being a constant 39; ============================================================================ ; 40 41define <2 x i4> @in_constant_varx_mone_invmask(<2 x i4> %x, <2 x i4> %mask) { 42; CHECK-LABEL: @in_constant_varx_mone_invmask( 43; CHECK-NEXT: [[N1_DEMORGAN:%.*]] = or <2 x i4> [[X:%.*]], [[MASK:%.*]] 44; CHECK-NEXT: ret <2 x i4> [[N1_DEMORGAN]] 45; 46 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1> 47 %n0 = xor <2 x i4> %x, <i4 -1, i4 -1> ; %x 48 %n1 = and <2 x i4> %n0, %notmask 49 %r = xor <2 x i4> %n1, <i4 -1, i4 -1> 50 ret <2 x i4> %r 51} 52 53define <2 x i4> @in_constant_varx_6_invmask(<2 x i4> %x, <2 x i4> %mask) { 54; CHECK-LABEL: @in_constant_varx_6_invmask( 55; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], splat (i4 6) 56; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] 57; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] 58; CHECK-NEXT: ret <2 x i4> [[R]] 59; 60 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1> 61 %n0 = xor <2 x i4> %x, <i4 6, i4 6> ; %x 62 %n1 = and <2 x i4> %n0, %notmask 63 %r = xor <2 x i4> %n1, <i4 6, i4 6> 64 ret <2 x i4> %r 65} 66 67define <2 x i4> @in_constant_varx_6_invmask_nonsplat(<2 x i4> %x, <2 x i4> %mask) { 68; CHECK-LABEL: @in_constant_varx_6_invmask_nonsplat( 69; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], <i4 6, i4 7> 70; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] 71; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] 72; CHECK-NEXT: ret <2 x i4> [[R]] 73; 74 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1> 75 %n0 = xor <2 x i4> %x, <i4 6, i4 7> ; %x 76 %n1 = and <2 x i4> %n0, %notmask 77 %r = xor <2 x i4> %n1, <i4 6, i4 7> 78 ret <2 x i4> %r 79} 80 81define <3 x i4> @in_constant_varx_6_invmask_poison(<3 x i4> %x, <3 x i4> %mask) { 82; CHECK-LABEL: @in_constant_varx_6_invmask_poison( 83; CHECK-NEXT: [[N0:%.*]] = xor <3 x i4> [[X:%.*]], <i4 6, i4 poison, i4 7> 84; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[N0]], [[MASK:%.*]] 85; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[TMP1]], [[X]] 86; CHECK-NEXT: ret <3 x i4> [[R]] 87; 88 %notmask = xor <3 x i4> %mask, <i4 -1, i4 poison, i4 -1> 89 %n0 = xor <3 x i4> %x, <i4 6, i4 poison, i4 7> ; %x 90 %n1 = and <3 x i4> %n0, %notmask 91 %r = xor <3 x i4> %n1, <i4 6, i4 poison, i4 7> 92 ret <3 x i4> %r 93} 94 95define <2 x i4> @in_constant_mone_vary_invmask(<2 x i4> %y, <2 x i4> %mask) { 96; CHECK-LABEL: @in_constant_mone_vary_invmask( 97; CHECK-NEXT: [[MASK_NOT:%.*]] = xor <2 x i4> [[MASK:%.*]], splat (i4 -1) 98; CHECK-NEXT: [[R:%.*]] = or <2 x i4> [[Y:%.*]], [[MASK_NOT]] 99; CHECK-NEXT: ret <2 x i4> [[R]] 100; 101 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1> 102 %n0 = xor <2 x i4> <i4 -1, i4 -1>, %y ; %x 103 %n1 = and <2 x i4> %n0, %notmask 104 %r = xor <2 x i4> %n1, %y 105 ret <2 x i4> %r 106} 107 108define <2 x i4> @in_constant_6_vary_invmask(<2 x i4> %y, <2 x i4> %mask) { 109; CHECK-LABEL: @in_constant_6_vary_invmask( 110; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], splat (i4 6) 111; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] 112; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 6) 113; CHECK-NEXT: ret <2 x i4> [[R]] 114; 115 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1> 116 %n0 = xor <2 x i4> %y, <i4 6, i4 6> ; %x 117 %n1 = and <2 x i4> %n0, %notmask 118 %r = xor <2 x i4> %n1, %y 119 ret <2 x i4> %r 120} 121 122define <2 x i4> @in_constant_6_vary_invmask_nonsplat(<2 x i4> %y, <2 x i4> %mask) { 123; CHECK-LABEL: @in_constant_6_vary_invmask_nonsplat( 124; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], <i4 6, i4 7> 125; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] 126; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 7> 127; CHECK-NEXT: ret <2 x i4> [[R]] 128; 129 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1> 130 %n0 = xor <2 x i4> %y, <i4 6, i4 7> ; %x 131 %n1 = and <2 x i4> %n0, %notmask 132 %r = xor <2 x i4> %n1, %y 133 ret <2 x i4> %r 134} 135 136define <3 x i4> @in_constant_6_vary_invmask_poison(<3 x i4> %y, <3 x i4> %mask) { 137; CHECK-LABEL: @in_constant_6_vary_invmask_poison( 138; CHECK-NEXT: [[N0:%.*]] = xor <3 x i4> [[Y:%.*]], <i4 6, i4 poison, i4 6> 139; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[N0]], [[MASK:%.*]] 140; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[TMP1]], <i4 6, i4 poison, i4 6> 141; CHECK-NEXT: ret <3 x i4> [[R]] 142; 143 %notmask = xor <3 x i4> %mask, <i4 -1, i4 poison, i4 -1> 144 %n0 = xor <3 x i4> %y, <i4 6, i4 poison, i4 6> ; %x 145 %n1 = and <3 x i4> %n0, %notmask 146 %r = xor <3 x i4> %n1, %y 147 ret <3 x i4> %r 148} 149 150; ============================================================================ ; 151; Commutativity 152; ============================================================================ ; 153 154; Used to make sure that the IR complexity sorting does not interfere. 155declare <2 x i4> @gen4() 156 157; FIXME: should %n1 = and <2 x i4> %im, %n0 swapped order pattern be tested? 158 159define <2 x i4> @c_1_0_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { 160; CHECK-LABEL: @c_1_0_0( 161; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]] 162; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] 163; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] 164; CHECK-NEXT: ret <2 x i4> [[R]] 165; 166 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 167 %n0 = xor <2 x i4> %y, %x ; swapped order 168 %n1 = and <2 x i4> %n0, %im 169 %r = xor <2 x i4> %n1, %y 170 ret <2 x i4> %r 171} 172 173define <2 x i4> @c_0_1_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { 174; CHECK-LABEL: @c_0_1_0( 175; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] 176; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] 177; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]] 178; CHECK-NEXT: ret <2 x i4> [[R]] 179; 180 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 181 %n0 = xor <2 x i4> %x, %y 182 %n1 = and <2 x i4> %n0, %im 183 %r = xor <2 x i4> %n1, %x ; %x instead of %y 184 ret <2 x i4> %r 185} 186 187define <2 x i4> @c_0_0_1 (<2 x i4> %m) { 188; CHECK-LABEL: @c_0_0_1( 189; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4() 190; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4() 191; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X]], [[Y]] 192; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] 193; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] 194; CHECK-NEXT: ret <2 x i4> [[R]] 195; 196 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 197 %x = call <2 x i4> @gen4() 198 %y = call <2 x i4> @gen4() 199 %n0 = xor <2 x i4> %x, %y 200 %n1 = and <2 x i4> %n0, %im 201 %r = xor <2 x i4> %y, %n1 ; swapped order 202 ret <2 x i4> %r 203} 204 205define <2 x i4> @c_1_1_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { 206; CHECK-LABEL: @c_1_1_0( 207; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]] 208; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] 209; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]] 210; CHECK-NEXT: ret <2 x i4> [[R]] 211; 212 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 213 %n0 = xor <2 x i4> %y, %x ; swapped order 214 %n1 = and <2 x i4> %n0, %im 215 %r = xor <2 x i4> %n1, %x ; %x instead of %y 216 ret <2 x i4> %r 217} 218 219define <2 x i4> @c_1_0_1 (<2 x i4> %x, <2 x i4> %m) { 220; CHECK-LABEL: @c_1_0_1( 221; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4() 222; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y]], [[X:%.*]] 223; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] 224; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] 225; CHECK-NEXT: ret <2 x i4> [[R]] 226; 227 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 228 %y = call <2 x i4> @gen4() 229 %n0 = xor <2 x i4> %y, %x ; swapped order 230 %n1 = and <2 x i4> %n0, %im 231 %r = xor <2 x i4> %y, %n1 ; swapped order 232 ret <2 x i4> %r 233} 234 235define <2 x i4> @c_0_1_1 (<2 x i4> %y, <2 x i4> %m) { 236; CHECK-LABEL: @c_0_1_1( 237; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4() 238; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X]], [[Y:%.*]] 239; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] 240; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]] 241; CHECK-NEXT: ret <2 x i4> [[R]] 242; 243 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 244 %x = call <2 x i4> @gen4() 245 %n0 = xor <2 x i4> %x, %y 246 %n1 = and <2 x i4> %n0, %im 247 %r = xor <2 x i4> %x, %n1 ; swapped order, %x instead of %y 248 ret <2 x i4> %r 249} 250 251define <2 x i4> @c_1_1_1 (<2 x i4> %m) { 252; CHECK-LABEL: @c_1_1_1( 253; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4() 254; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4() 255; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y]], [[X]] 256; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] 257; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]] 258; CHECK-NEXT: ret <2 x i4> [[R]] 259; 260 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 261 %x = call <2 x i4> @gen4() 262 %y = call <2 x i4> @gen4() 263 %n0 = xor <2 x i4> %y, %x ; swapped order 264 %n1 = and <2 x i4> %n0, %im 265 %r = xor <2 x i4> %x, %n1 ; swapped order, %x instead of %y 266 ret <2 x i4> %r 267} 268 269define <2 x i4> @commutativity_constant_varx_6_invmask(<2 x i4> %x, <2 x i4> %mask) { 270; CHECK-LABEL: @commutativity_constant_varx_6_invmask( 271; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], splat (i4 6) 272; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] 273; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] 274; CHECK-NEXT: ret <2 x i4> [[R]] 275; 276 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1> 277 %n0 = xor <2 x i4> %x, <i4 6, i4 6> ; %x 278 %n1 = and <2 x i4> %notmask, %n0 ; swapped 279 %r = xor <2 x i4> %n1, <i4 6, i4 6> 280 ret <2 x i4> %r 281} 282 283define <2 x i4> @commutativity_constant_6_vary_invmask(<2 x i4> %y, <2 x i4> %mask) { 284; CHECK-LABEL: @commutativity_constant_6_vary_invmask( 285; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], splat (i4 6) 286; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]] 287; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 6) 288; CHECK-NEXT: ret <2 x i4> [[R]] 289; 290 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1> 291 %n0 = xor <2 x i4> %y, <i4 6, i4 6> ; %x 292 %n1 = and <2 x i4> %notmask, %n0 ; swapped 293 %r = xor <2 x i4> %n1, %y 294 ret <2 x i4> %r 295} 296 297; ============================================================================ ; 298; Negative tests. Should not be folded. 299; ============================================================================ ; 300 301; One use only. 302 303declare void @use4(<2 x i4>) 304 305define <2 x i4> @n_oneuse_D_is_ok (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { 306; CHECK-LABEL: @n_oneuse_D_is_ok( 307; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] 308; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]] 309; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]] 310; CHECK-NEXT: call void @use4(<2 x i4> [[N0]]) 311; CHECK-NEXT: ret <2 x i4> [[R]] 312; 313 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 314 %n0 = xor <2 x i4> %x, %y ; two uses of %n0, THIS IS OK! 315 %n1 = and <2 x i4> %n0, %im 316 %r = xor <2 x i4> %n1, %y 317 call void @use4(<2 x i4> %n0) 318 ret <2 x i4> %r 319} 320 321define <2 x i4> @n_oneuse_A (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { 322; CHECK-LABEL: @n_oneuse_A( 323; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], splat (i4 -1) 324; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] 325; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] 326; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] 327; CHECK-NEXT: call void @use4(<2 x i4> [[N1]]) 328; CHECK-NEXT: ret <2 x i4> [[R]] 329; 330 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 331 %n0 = xor <2 x i4> %x, %y 332 %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced 333 %r = xor <2 x i4> %n1, %y 334 call void @use4(<2 x i4> %n1) 335 ret <2 x i4> %r 336} 337 338define <2 x i4> @n_oneuse_AD (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { 339; CHECK-LABEL: @n_oneuse_AD( 340; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], splat (i4 -1) 341; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] 342; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] 343; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] 344; CHECK-NEXT: call void @use4(<2 x i4> [[N0]]) 345; CHECK-NEXT: call void @use4(<2 x i4> [[N1]]) 346; CHECK-NEXT: ret <2 x i4> [[R]] 347; 348 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 349 %n0 = xor <2 x i4> %x, %y ; two uses of %n0 IS OK 350 %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced 351 %r = xor <2 x i4> %n1, %y 352 call void @use4(<2 x i4> %n0) 353 call void @use4(<2 x i4> %n1) 354 ret <2 x i4> %r 355} 356 357; Some third variable is used 358 359define <2 x i4> @n_third_var (<2 x i4> %x, <2 x i4> %y, <2 x i4> %z, <2 x i4> %m) { 360; CHECK-LABEL: @n_third_var( 361; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], splat (i4 -1) 362; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] 363; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] 364; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Z:%.*]] 365; CHECK-NEXT: ret <2 x i4> [[R]] 366; 367 %im = xor <2 x i4> %m, <i4 -1, i4 -1> 368 %n0 = xor <2 x i4> %x, %y 369 %n1 = and <2 x i4> %n0, %im 370 %r = xor <2 x i4> %n1, %z ; not %x or %y 371 ret <2 x i4> %r 372} 373 374 375define <2 x i4> @n_third_var_const(<2 x i4> %x, <2 x i4> %y, <2 x i4> %mask) { 376; CHECK-LABEL: @n_third_var_const( 377; CHECK-NEXT: [[NOTMASK:%.*]] = xor <2 x i4> [[MASK:%.*]], splat (i4 -1) 378; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], <i4 6, i4 7> 379; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[NOTMASK]] 380; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], <i4 7, i4 6> 381; CHECK-NEXT: ret <2 x i4> [[R]] 382; 383 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1> 384 %n0 = xor <2 x i4> %x, <i4 6, i4 7> ; %x 385 %n1 = and <2 x i4> %n0, %notmask 386 %r = xor <2 x i4> %n1, <i4 7, i4 6> 387 ret <2 x i4> %r 388} 389 390; Bad xor 391 392define <2 x i4> @n_badxor_splat (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { 393; CHECK-LABEL: @n_badxor_splat( 394; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], splat (i4 1) 395; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] 396; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] 397; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] 398; CHECK-NEXT: ret <2 x i4> [[R]] 399; 400 %im = xor <2 x i4> %m, <i4 1, i4 1> ; not -1 401 %n0 = xor <2 x i4> %x, %y 402 %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced 403 %r = xor <2 x i4> %n1, %y 404 ret <2 x i4> %r 405} 406 407define <2 x i4> @n_badxor (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) { 408; CHECK-LABEL: @n_badxor( 409; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 -1, i4 1> 410; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]] 411; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]] 412; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]] 413; CHECK-NEXT: ret <2 x i4> [[R]] 414; 415 %im = xor <2 x i4> %m, <i4 -1, i4 1> ; not -1 416 %n0 = xor <2 x i4> %x, %y 417 %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced 418 %r = xor <2 x i4> %n1, %y 419 ret <2 x i4> %r 420} 421